src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/edit/histwalk.go (about) 1 package edit 2 3 import ( 4 "errors" 5 6 "src.elv.sh/pkg/cli" 7 "src.elv.sh/pkg/cli/histutil" 8 "src.elv.sh/pkg/cli/modes" 9 "src.elv.sh/pkg/cli/tk" 10 "src.elv.sh/pkg/eval" 11 ) 12 13 func initHistWalk(ed *Editor, ev *eval.Evaler, hs *histStore, nb eval.NsBuilder) { 14 bindingVar := newBindingVar(emptyBindingsMap) 15 bindings := newMapBindings(ed, ev, bindingVar) 16 app := ed.app 17 nb.AddNs("history", 18 eval.BuildNsNamed("edit:history"). 19 AddVar("binding", bindingVar). 20 AddGoFns(map[string]any{ 21 "start": func() { notifyError(app, histwalkStart(app, hs, bindings)) }, 22 "up": func() { notifyError(app, histwalkDo(app, modes.Histwalk.Prev)) }, 23 "down": func() { notifyError(app, histwalkDo(app, modes.Histwalk.Next)) }, 24 "down-or-quit": func() { 25 err := histwalkDo(app, modes.Histwalk.Next) 26 if err == histutil.ErrEndOfHistory { 27 app.PopAddon() 28 } else { 29 notifyError(app, err) 30 } 31 }, 32 "accept": func() { notifyError(app, histwalkDo(app, modes.Histwalk.Accept)) }, 33 "fast-forward": hs.FastForward, 34 })) 35 } 36 37 func histwalkStart(app cli.App, hs *histStore, bindings tk.Bindings) error { 38 codeArea, ok := focusedCodeArea(app) 39 if !ok { 40 return nil 41 } 42 buf := codeArea.CopyState().Buffer 43 w, err := modes.NewHistwalk(app, modes.HistwalkSpec{ 44 Bindings: bindings, Store: hs, Prefix: buf.Content[:buf.Dot], 45 }) 46 if w != nil { 47 app.PushAddon(w) 48 } 49 return err 50 } 51 52 var errNotInHistoryMode = errors.New("not in history mode") 53 54 func histwalkDo(app cli.App, f func(modes.Histwalk) error) error { 55 w, ok := app.ActiveWidget().(modes.Histwalk) 56 if !ok { 57 return errNotInHistoryMode 58 } 59 return f(w) 60 } 61 62 func notifyError(app cli.App, err error) { 63 if err != nil { 64 app.Notify(modes.ErrorText(err)) 65 } 66 }