2018-05-25 05:56:30 +08:00
|
|
|
package edcore
|
2017-05-22 09:00:44 +08:00
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/elves/elvish/eval"
|
2018-02-15 17:14:05 +08:00
|
|
|
"github.com/elves/elvish/eval/vals"
|
2018-02-15 17:26:30 +08:00
|
|
|
"github.com/elves/elvish/eval/vars"
|
2018-01-28 01:26:22 +08:00
|
|
|
"github.com/xiaq/persistent/vector"
|
2017-05-22 09:00:44 +08:00
|
|
|
)
|
|
|
|
|
2018-02-06 16:20:33 +08:00
|
|
|
// The $edit:{before,after}-readline lists that contain hooks. We might have more
|
2017-05-22 23:05:03 +08:00
|
|
|
// hooks in future.
|
|
|
|
|
2018-02-07 09:07:54 +08:00
|
|
|
// editorHooks contain hooks for the editor. They are just slices of functions;
|
|
|
|
// each of them is initialized with a function that calls all Elvish functions
|
|
|
|
// contained in the eponymous variable under edit:.
|
2018-02-06 16:20:33 +08:00
|
|
|
type editorHooks struct {
|
2018-02-07 09:07:54 +08:00
|
|
|
beforeReadline []func()
|
|
|
|
afterReadline []func(string)
|
2017-05-22 09:00:44 +08:00
|
|
|
}
|
|
|
|
|
2018-02-06 16:20:33 +08:00
|
|
|
func init() {
|
2018-02-07 17:09:33 +08:00
|
|
|
atEditorInit(func(ed *editor, ns eval.Ns) {
|
2018-02-15 17:14:05 +08:00
|
|
|
beforeReadline := vals.EmptyList
|
2018-03-08 21:20:31 +08:00
|
|
|
ns["before-readline"] = vars.FromPtr(&beforeReadline)
|
2018-02-07 13:48:04 +08:00
|
|
|
ed.AddBeforeReadline(func() { callHooks(ed, beforeReadline) })
|
2018-02-07 09:07:54 +08:00
|
|
|
|
2018-02-15 17:14:05 +08:00
|
|
|
afterReadline := vals.EmptyList
|
2018-03-08 21:20:31 +08:00
|
|
|
ns["after-readline"] = vars.FromPtr(&afterReadline)
|
2018-02-07 13:48:04 +08:00
|
|
|
ed.AddAfterReadline(func(s string) { callHooks(ed, afterReadline, s) })
|
2018-02-06 16:20:33 +08:00
|
|
|
})
|
2017-05-22 09:00:44 +08:00
|
|
|
}
|
|
|
|
|
2018-02-07 13:48:04 +08:00
|
|
|
// AddBeforeReadline adds a function to the before-readline hook.
|
|
|
|
func (h *editorHooks) AddBeforeReadline(f func()) {
|
|
|
|
h.beforeReadline = append(h.beforeReadline, f)
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddAfterReadline adds a function to the after-readline hook.
|
|
|
|
func (h *editorHooks) AddAfterReadline(f func(string)) {
|
|
|
|
h.afterReadline = append(h.afterReadline, f)
|
|
|
|
}
|
|
|
|
|
2018-02-07 17:09:33 +08:00
|
|
|
func callHooks(ed *editor, li vector.Vector, args ...interface{}) {
|
2018-01-28 01:26:22 +08:00
|
|
|
for it := li.Iterator(); it.HasElem(); it.Next() {
|
2018-02-07 09:07:54 +08:00
|
|
|
fn, ok := it.Elem().(eval.Callable)
|
|
|
|
if !ok {
|
|
|
|
// TODO More detailed error message.
|
|
|
|
ed.Notify("hook not a function")
|
|
|
|
}
|
|
|
|
ed.CallFn(fn, args...)
|
2018-01-21 20:49:25 +08:00
|
|
|
}
|
|
|
|
}
|