2019-12-18 18:38:21 +08:00
|
|
|
package edit
|
2019-10-27 07:17:43 +08:00
|
|
|
|
|
|
|
import (
|
2021-02-13 06:31:33 +08:00
|
|
|
"errors"
|
|
|
|
|
2021-01-27 09:28:38 +08:00
|
|
|
"src.elv.sh/pkg/cli"
|
|
|
|
"src.elv.sh/pkg/cli/histutil"
|
2021-02-13 06:31:33 +08:00
|
|
|
"src.elv.sh/pkg/cli/mode"
|
2021-02-12 02:49:00 +08:00
|
|
|
"src.elv.sh/pkg/cli/tk"
|
2021-01-27 09:28:38 +08:00
|
|
|
"src.elv.sh/pkg/eval"
|
2019-10-27 07:17:43 +08:00
|
|
|
)
|
|
|
|
|
2021-02-13 06:31:33 +08:00
|
|
|
//elvdoc:var history:binding
|
|
|
|
//
|
|
|
|
// Binding table for the history mode.
|
|
|
|
|
|
|
|
//elvdoc:fn history:start
|
|
|
|
//
|
|
|
|
// Starts the history mode.
|
|
|
|
|
|
|
|
//elvdoc:fn history:up
|
|
|
|
//
|
|
|
|
// Walks to the previous entry in history mode.
|
|
|
|
|
|
|
|
//elvdoc:fn history:down
|
|
|
|
//
|
|
|
|
// Walks to the next entry in history mode.
|
|
|
|
|
|
|
|
//elvdoc:fn history:down-or-quit
|
|
|
|
//
|
|
|
|
// Walks to the next entry in history mode, or quit the history mode if already
|
|
|
|
// at the newest entry.
|
|
|
|
|
2019-12-26 23:23:40 +08:00
|
|
|
//elvdoc:fn history:fast-forward
|
|
|
|
//
|
|
|
|
// Import command history entries that happened after the current session
|
|
|
|
// started.
|
|
|
|
|
2020-12-25 01:39:51 +08:00
|
|
|
func initHistWalk(ed *Editor, ev *eval.Evaler, hs *histStore, nb eval.NsBuilder) {
|
2021-02-13 05:34:47 +08:00
|
|
|
bindingVar := newBindingVar(emptyBindingsMap)
|
|
|
|
bindings := newMapBindings(ed, ev, bindingVar)
|
2020-05-03 02:51:12 +08:00
|
|
|
app := ed.app
|
2020-12-25 01:39:51 +08:00
|
|
|
nb.AddNs("history",
|
|
|
|
eval.NsBuilder{
|
2019-10-27 07:17:43 +08:00
|
|
|
"binding": bindingVar,
|
|
|
|
}.AddGoFns("<edit:history>", map[string]interface{}{
|
2021-02-13 06:31:33 +08:00
|
|
|
"start": func() { notifyError(app, histwalkStart(app, hs, bindings)) },
|
|
|
|
"up": func() { notifyError(app, histwalkDo(app, mode.Histwalk.Prev)) },
|
|
|
|
|
|
|
|
"down": func() { notifyError(app, histwalkDo(app, mode.Histwalk.Next)) },
|
2019-11-20 18:21:25 +08:00
|
|
|
"down-or-quit": func() {
|
2021-02-13 06:31:33 +08:00
|
|
|
err := histwalkDo(app, mode.Histwalk.Next)
|
2019-11-20 18:21:25 +08:00
|
|
|
if err == histutil.ErrEndOfHistory {
|
2021-02-13 06:31:33 +08:00
|
|
|
app.SetAddon(nil, false)
|
2019-11-20 18:21:25 +08:00
|
|
|
} else {
|
2021-02-13 06:31:33 +08:00
|
|
|
notifyError(app, err)
|
2019-11-20 18:21:25 +08:00
|
|
|
}
|
|
|
|
},
|
2021-02-13 06:31:33 +08:00
|
|
|
// TODO: Remove these builtins in favor of two universal accept and
|
|
|
|
// close builtins
|
|
|
|
"accept": func() { app.SetAddon(nil, true) },
|
2019-11-20 18:24:01 +08:00
|
|
|
|
2020-07-14 06:35:19 +08:00
|
|
|
"fast-forward": hs.FastForward,
|
2020-12-25 01:39:51 +08:00
|
|
|
}).Ns())
|
2019-10-27 07:17:43 +08:00
|
|
|
}
|
2019-10-29 06:48:16 +08:00
|
|
|
|
2021-02-13 06:31:33 +08:00
|
|
|
func histwalkStart(app cli.App, hs *histStore, bindings tk.Bindings) error {
|
2019-11-04 07:22:36 +08:00
|
|
|
buf := app.CodeArea().CopyState().Buffer
|
2021-02-13 06:31:33 +08:00
|
|
|
w, err := mode.NewHistwalk(app, mode.HistwalkSpec{
|
2021-02-13 05:34:47 +08:00
|
|
|
Bindings: bindings, Store: hs, Prefix: buf.Content[:buf.Dot]})
|
2021-02-13 06:31:33 +08:00
|
|
|
if w != nil {
|
|
|
|
app.SetAddon(w, false)
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
var errNotInHistoryMode = errors.New("not in history mode")
|
|
|
|
|
|
|
|
func histwalkDo(app cli.App, f func(mode.Histwalk) error) error {
|
|
|
|
w, ok := app.CopyState().Addon.(mode.Histwalk)
|
|
|
|
if !ok {
|
|
|
|
return errNotInHistoryMode
|
|
|
|
}
|
|
|
|
return f(w)
|
2019-10-29 06:48:16 +08:00
|
|
|
}
|
2019-11-20 18:21:25 +08:00
|
|
|
|
2021-02-13 06:31:33 +08:00
|
|
|
func notifyError(app cli.App, err error) {
|
2019-11-20 18:21:25 +08:00
|
|
|
if err != nil {
|
|
|
|
app.Notify(err.Error())
|
|
|
|
}
|
|
|
|
}
|