github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/cmds/core/elvish/edit/hooks.go (about) 1 package edit 2 3 import ( 4 "github.com/u-root/u-root/cmds/core/elvish/eval" 5 "github.com/u-root/u-root/cmds/core/elvish/eval/vals" 6 "github.com/u-root/u-root/cmds/core/elvish/eval/vars" 7 "github.com/u-root/u-root/cmds/core/elvish/vector" 8 ) 9 10 // The $edit:{before,after}-readline lists that contain hooks. We might have more 11 // hooks in future. 12 13 // editorHooks contain hooks for the editor. They are just slices of functions; 14 // each of them is initialized with a function that calls all Elvish functions 15 // contained in the eponymous variable under edit:. 16 type editorHooks struct { 17 beforeReadline []func() 18 afterReadline []func(string) 19 } 20 21 func init() { 22 atEditorInit(func(ed *editor, ns eval.Ns) { 23 beforeReadline := vals.EmptyList 24 ns["before-readline"] = vars.FromPtr(&beforeReadline) 25 ed.AddBeforeReadline(func() { callHooks(ed, beforeReadline) }) 26 27 afterReadline := vals.EmptyList 28 ns["after-readline"] = vars.FromPtr(&afterReadline) 29 ed.AddAfterReadline(func(s string) { callHooks(ed, afterReadline, s) }) 30 }) 31 } 32 33 // AddBeforeReadline adds a function to the before-readline hook. 34 func (h *editorHooks) AddBeforeReadline(f func()) { 35 h.beforeReadline = append(h.beforeReadline, f) 36 } 37 38 // AddAfterReadline adds a function to the after-readline hook. 39 func (h *editorHooks) AddAfterReadline(f func(string)) { 40 h.afterReadline = append(h.afterReadline, f) 41 } 42 43 func callHooks(ed *editor, li vector.Vector, args ...interface{}) { 44 for it := li.Iterator(); it.HasElem(); it.Next() { 45 fn, ok := it.Elem().(eval.Callable) 46 if !ok { 47 // TODO More detailed error message. 48 ed.Notify("hook not a function") 49 } 50 ed.CallFn(fn, args...) 51 } 52 }