github.com/kolbycrouch/elvish@v0.14.1-0.20210614162631-215b9ac1c423/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/mode" 9 "src.elv.sh/pkg/cli/tk" 10 "src.elv.sh/pkg/eval" 11 ) 12 13 //elvdoc:var history:binding 14 // 15 // Binding table for the history mode. 16 17 //elvdoc:fn history:start 18 // 19 // Starts the history mode. 20 21 //elvdoc:fn history:up 22 // 23 // Walks to the previous entry in history mode. 24 25 //elvdoc:fn history:down 26 // 27 // Walks to the next entry in history mode. 28 29 //elvdoc:fn history:down-or-quit 30 // 31 // Walks to the next entry in history mode, or quit the history mode if already 32 // at the newest entry. 33 34 //elvdoc:fn history:fast-forward 35 // 36 // Import command history entries that happened after the current session 37 // started. 38 39 func initHistWalk(ed *Editor, ev *eval.Evaler, hs *histStore, nb eval.NsBuilder) { 40 bindingVar := newBindingVar(emptyBindingsMap) 41 bindings := newMapBindings(ed, ev, bindingVar) 42 app := ed.app 43 nb.AddNs("history", 44 eval.NsBuilder{ 45 "binding": bindingVar, 46 }.AddGoFns("<edit:history>", map[string]interface{}{ 47 "start": func() { notifyError(app, histwalkStart(app, hs, bindings)) }, 48 "up": func() { notifyError(app, histwalkDo(app, mode.Histwalk.Prev)) }, 49 50 "down": func() { notifyError(app, histwalkDo(app, mode.Histwalk.Next)) }, 51 "down-or-quit": func() { 52 err := histwalkDo(app, mode.Histwalk.Next) 53 if err == histutil.ErrEndOfHistory { 54 app.SetAddon(nil, false) 55 } else { 56 notifyError(app, err) 57 } 58 }, 59 // TODO: Remove these builtins in favor of two universal accept and 60 // close builtins 61 "accept": func() { app.SetAddon(nil, true) }, 62 63 "fast-forward": hs.FastForward, 64 }).Ns()) 65 } 66 67 func histwalkStart(app cli.App, hs *histStore, bindings tk.Bindings) error { 68 buf := app.CodeArea().CopyState().Buffer 69 w, err := mode.NewHistwalk(app, mode.HistwalkSpec{ 70 Bindings: bindings, Store: hs, Prefix: buf.Content[:buf.Dot]}) 71 if w != nil { 72 app.SetAddon(w, false) 73 } 74 return err 75 } 76 77 var errNotInHistoryMode = errors.New("not in history mode") 78 79 func histwalkDo(app cli.App, f func(mode.Histwalk) error) error { 80 w, ok := app.CopyState().Addon.(mode.Histwalk) 81 if !ok { 82 return errNotInHistoryMode 83 } 84 return f(w) 85 } 86 87 func notifyError(app cli.App, err error) { 88 if err != nil { 89 app.Notify(err.Error()) 90 } 91 }