diff --git a/src/buffer.go b/src/buffer.go index 0ffe5fc8..fa32a631 100644 --- a/src/buffer.go +++ b/src/buffer.go @@ -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() diff --git a/src/command.go b/src/command.go index cfffc22a..1994e207 100644 --- a/src/command.go +++ b/src/command.go @@ -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) } } diff --git a/src/eventhandler.go b/src/eventhandler.go index b563151d..c54319eb 100644 --- a/src/eventhandler.go +++ b/src/eventhandler.go @@ -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 {