]> git.lizzy.rs Git - micro.git/commitdiff
Search and replace within a selection
authorZachary Yedidia <zyedidia@gmail.com>
Fri, 14 Feb 2020 00:48:48 +0000 (19:48 -0500)
committerZachary Yedidia <zyedidia@gmail.com>
Fri, 14 Feb 2020 00:48:48 +0000 (19:48 -0500)
Closes #1098

internal/action/command.go
internal/buffer/loc.go
internal/buffer/search.go
internal/display/bufwindow.go

index 2d9b2fbbbb361671f7fe8b4f85d3db9b18334909..64d0aab89260abd4414a4c4f43d91afb69070882 100644 (file)
@@ -732,23 +732,22 @@ func (h *BufPane) ReplaceCmd(args []string) {
 
        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
@@ -764,10 +763,11 @@ func (h *BufPane) ReplaceCmd(args []string) {
 
                        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 {
@@ -778,9 +778,7 @@ func (h *BufPane) ReplaceCmd(args []string) {
                                        h.Buf.RelocateCursors()
                                        return
                                }
-                               if searching {
-                                       doReplacement()
-                               }
+                               doReplacement()
                        })
                }
                doReplacement()
index 5687f97754e795ed90f64746ebd21fb846de220e..16a62f9b5a31016df466612de6a9abdeb0e96120 100644 (file)
@@ -102,7 +102,7 @@ func (l Loc) left(buf *LineArray) Loc {
        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 {
@@ -117,9 +117,12 @@ func (l Loc) MoveLA(n int, buf *LineArray) Loc {
        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)
 }
index 64bcc48c8b429b11befc6233984a8d8355d6d499..d537347a88b0b064ab6da5be5d5e5811c3531148 100644 (file)
@@ -120,24 +120,27 @@ func (b *Buffer) FindNext(s string, start, end, from Loc, down bool, useRegex bo
        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++ {
@@ -160,6 +163,7 @@ func (b *Buffer) ReplaceRegex(start, end Loc, search *regexp.Regexp, replace []b
                                result = search.Expand(result, replace, in, submatches)
                        }
                        found++
+                       netrunes += utf8.RuneCount(in) - utf8.RuneCount(result)
                        return result
                })
 
@@ -170,5 +174,5 @@ func (b *Buffer) ReplaceRegex(start, end Loc, search *regexp.Regexp, replace []b
        }
        b.MultipleReplace(deltas)
 
-       return found
+       return found, netrunes
 }
index fb52728af09b46a5e2b06dbc6ce8278f722816d5..42fd489c31faa6d03745ca3ab7b787e7ec84cac0 100644 (file)
@@ -638,13 +638,12 @@ func (w *BufWindow) displayBuffer() {
                                                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) {