nreplaced := 0
start := h.Buf.Start()
- // end := h.Buf.End()
- // if h.Cursor.HasSelection() {
- // start = h.Cursor.CurSelection[0]
- // end = h.Cursor.CurSelection[1]
- // }
+ end := h.Buf.End()
+ if h.Cursor.HasSelection() {
+ start = h.Cursor.CurSelection[0]
+ end = h.Cursor.CurSelection[1]
+ }
if all {
- nreplaced = h.Buf.ReplaceRegex(start, h.Buf.End(), regex, replace)
+ nreplaced, _ = h.Buf.ReplaceRegex(start, end, regex, replace)
} else {
inRange := func(l buffer.Loc) bool {
- return l.GreaterEqual(start) && l.LessEqual(h.Buf.End())
+ return l.GreaterEqual(start) && l.LessEqual(end)
}
searchLoc := start
- searching := true
var doReplacement func()
doReplacement = func() {
- locs, found, err := h.Buf.FindNext(search, start, h.Buf.End(), searchLoc, true, !noRegex)
+ locs, found, err := h.Buf.FindNext(search, start, end, searchLoc, true, !noRegex)
if err != nil {
InfoBar.Error(err)
return
InfoBar.YNPrompt("Perform replacement (y,n,esc)", func(yes, canceled bool) {
if !canceled && yes {
- h.Buf.ReplaceRegex(locs[0], locs[1], regex, replace)
+ _, nrunes := h.Buf.ReplaceRegex(locs[0], locs[1], regex, replace)
searchLoc = locs[0]
- searchLoc.X += utf8.RuneCount(replace)
+ searchLoc.X += nrunes + locs[0].Diff(locs[1], h.Buf)
+ end.Move(nrunes, h.Buf)
h.Cursor.Loc = searchLoc
nreplaced++
} else if !canceled && !yes {
h.Buf.RelocateCursors()
return
}
- if searching {
- doReplacement()
- }
+ doReplacement()
})
}
doReplacement()
return res
}
-// Move moves the cursor n characters to the left or right
+// MoveLA moves the cursor n characters to the left or right
// It moves the cursor left if n is negative
func (l Loc) MoveLA(n int, buf *LineArray) Loc {
if n > 0 {
return l
}
-func (l Loc) Diff(a, b Loc, buf *Buffer) int {
- return DiffLA(a, b, buf.LineArray)
+// Diff returns the difference between two locs
+func (l Loc) Diff(b Loc, buf *Buffer) int {
+ return DiffLA(l, b, buf.LineArray)
}
+
+// Move moves a loc n characters
func (l Loc) Move(n int, buf *Buffer) Loc {
return l.MoveLA(n, buf.LineArray)
}
if down {
l, found = b.findDown(r, from, end)
if !found {
- l, found = b.findDown(r, start, from)
+ l, found = b.findDown(r, start, end)
}
} else {
l, found = b.findUp(r, from, start)
if !found {
- l, found = b.findUp(r, end, from)
+ l, found = b.findUp(r, end, start)
}
}
return l, found, nil
}
// ReplaceRegex replaces all occurrences of 'search' with 'replace' in the given area
-// and returns the number of replacements made
-func (b *Buffer) ReplaceRegex(start, end Loc, search *regexp.Regexp, replace []byte) int {
+// and returns the number of replacements made and the number of runes
+// added or removed
+func (b *Buffer) ReplaceRegex(start, end Loc, search *regexp.Regexp, replace []byte) (int, int) {
if start.GreaterThan(end) {
start, end = end, start
}
+ netrunes := 0
+
found := 0
var deltas []Delta
for i := start.Y; i <= end.Y; i++ {
result = search.Expand(result, replace, in, submatches)
}
found++
+ netrunes += utf8.RuneCount(in) - utf8.RuneCount(result)
return result
})
}
b.MultipleReplace(deltas)
- return found
+ return found, netrunes
}
break
}
vloc.X = 0
- if b.Settings["diffgutter"].(bool) {
- w.drawDiffGutter(lineNumStyle, true, &vloc, &bloc)
- }
-
if hasMessage {
w.drawGutter(&vloc, &bloc)
}
+ if b.Settings["diffgutter"].(bool) {
+ w.drawDiffGutter(lineNumStyle, true, &vloc, &bloc)
+ }
// This will draw an empty line number because the current line is wrapped
if b.Settings["ruler"].(bool) {