github.com/jmigpin/editor@v1.6.0/util/iout/iorw/rwedit/replace.go (about) 1 package rwedit 2 3 import ( 4 "github.com/jmigpin/editor/util/iout/iorw" 5 ) 6 7 func Replace(ctx *Ctx, old, new string) (bool, error) { 8 if old == "" { 9 return false, nil 10 } 11 12 oldb := []byte(old) 13 newb := []byte(new) 14 15 a, b, ok := ctx.C.SelectionIndexes() 16 if !ok { 17 a = ctx.RW.Min() 18 b = ctx.RW.Max() 19 } 20 21 ci, replaced, err := replace2(ctx, oldb, newb, a, b) 22 if err != nil { 23 return replaced, err 24 } 25 ctx.C.SetIndex(ci) 26 return replaced, nil 27 } 28 29 func replace2(ctx *Ctx, oldb, newb []byte, a, b int) (int, bool, error) { 30 ci := ctx.C.Index() 31 replaced := false 32 for a < b { 33 rd := iorw.NewLimitedReaderAt(ctx.RW, a, b) 34 i, _, err := iorw.Index(rd, a, oldb, false) 35 if err != nil { 36 return ci, replaced, err 37 } 38 if i < 0 { 39 return ci, replaced, nil 40 } 41 if err := ctx.RW.OverwriteAt(i, len(oldb), newb); err != nil { 42 return ci, replaced, err 43 } 44 replaced = true 45 d := -len(oldb) + len(newb) 46 b += d 47 a = i + len(newb) 48 49 if i < ci { 50 ci += d 51 if ci < i { 52 ci = i 53 } 54 } 55 } 56 return ci, replaced, nil 57 }