Add search and replace

This commit is contained in:
Zachary Yedidia
2016-04-03 15:22:31 -04:00
parent f88ef4f9a4
commit 43187c0438
3 changed files with 61 additions and 0 deletions

View File

@@ -3,6 +3,7 @@ package main
import (
"github.com/vinzmay/go-rope"
"io/ioutil"
"regexp"
"strings"
)
@@ -110,6 +111,21 @@ func (b *Buffer) Remove(start, end int) string {
return removed
}
func (b *Buffer) Replace(search, replace string) error {
re, err := regexp.Compile(search)
if err != nil {
return err
}
text := re.ReplaceAllString(b.text, replace)
if text == "" {
b.r = new(rope.Rope)
} else {
b.r = rope.New(text)
}
b.Update()
return nil
}
// Len gives the length of the buffer
func (b *Buffer) Len() int {
return b.r.Len()

View File

@@ -2,6 +2,7 @@ package main
import (
"os"
"regexp"
"strings"
)
@@ -35,5 +36,43 @@ func HandleCommand(input string, view *View) {
}
case "save":
view.Save()
case "replace":
r := regexp.MustCompile(`"[^"\\]*(?:\\.[^"\\]*)*"|[^\s]*`)
replaceCmd := r.FindAllString(strings.Join(args, " "), -1)
if len(replaceCmd) != 2 {
messenger.Error("Invalid replace statement: " + strings.Join(args, " "))
return
}
search := string(replaceCmd[0])
replace := string(replaceCmd[1])
if strings.HasPrefix(search, `"`) && strings.HasSuffix(search, `"`) {
search = search[1 : len(search)-1]
}
if strings.HasPrefix(replace, `"`) && strings.HasSuffix(replace, `"`) {
replace = replace[1 : len(replace)-1]
}
search = strings.Replace(search, `\"`, `"`, -1)
replace = strings.Replace(replace, `\"`, `"`, -1)
messenger.Error(search + " -> " + replace)
regex, err := regexp.Compile(search)
if err != nil {
messenger.Error(err.Error())
return
}
for {
match := regex.FindStringIndex(view.buf.text)
if match == nil {
break
}
view.eh.Replace(match[0], match[1], replace)
}
default:
messenger.Error("Unknown command: " + cmd)
}
}

View File

@@ -83,6 +83,12 @@ func (eh *EventHandler) Remove(start, end int) {
eh.Execute(e)
}
// Replace deletes from start to end and replaces it with the given string
func (eh *EventHandler) Replace(start, end int, replace string) {
eh.Remove(start, end)
eh.Insert(start, replace)
}
// Execute a textevent and add it to the undo stack
func (eh *EventHandler) Execute(t *TextEvent) {
if eh.redo.Len() > 0 {