diff --git a/newedit/core/editor.go b/newedit/core/editor.go index dce97a47..57044194 100644 --- a/newedit/core/editor.go +++ b/newedit/core/editor.go @@ -25,11 +25,11 @@ type Editor struct { // Editor configuration that can be modified concurrently. Config Config - // If not nil, will be called when ReadCode starts. - BeforeReadline func() - // If not nil, will be called when ReadCode ends; the argument is the code - // that has been read. - AfterReadline func(string) + // Functions called when ReadCode starts. + BeforeReadline []func() + // Functions called when ReadCode ends; the argument is the code that has + // just been read. + AfterReadline []func(string) // Code highlighter. Highlighter Highlighter @@ -233,12 +233,14 @@ func (ed *Editor) ReadCode() (string, error) { defer ed.state.Reset() // BeforeReadline and AfterReadline hooks. - if ed.BeforeReadline != nil { - ed.BeforeReadline() + for _, f := range ed.BeforeReadline { + f() } - if ed.AfterReadline != nil { + if len(ed.AfterReadline) > 0 { defer func() { - ed.AfterReadline(ed.state.Code()) + for _, f := range ed.AfterReadline { + f(ed.state.Code()) + } }() } @@ -269,3 +271,13 @@ func (ed *Editor) Notify(note string) { ed.state.AddNote(note) ed.Redraw(false) } + +// AddBeforeReadline adds a new before-readline hook function. +func (ed *Editor) AddBeforeReadline(f func()) { + ed.BeforeReadline = append(ed.BeforeReadline, f) +} + +// AddAfterReadline adds a new after-readline hook function. +func (ed *Editor) AddAfterReadline(f func(string)) { + ed.AfterReadline = append(ed.AfterReadline, f) +} diff --git a/newedit/core/editor_test.go b/newedit/core/editor_test.go index d092e00e..ed179e11 100644 --- a/newedit/core/editor_test.go +++ b/newedit/core/editor_test.go @@ -77,7 +77,7 @@ func TestReadCode_CallsBeforeReadlineOnce(t *testing.T) { ed, terminal, _ := setup() called := 0 - ed.BeforeReadline = func() { called++ } + ed.AddBeforeReadline(func() { called++ }) // Causes BasicMode to quit terminal.EventCh <- tty.KeyEvent{Rune: '\n'} @@ -93,10 +93,10 @@ func TestReadCode_CallsAfterReadlineOnceWithCode(t *testing.T) { called := 0 code := "" - ed.AfterReadline = func(s string) { + ed.AddAfterReadline(func(s string) { called++ code = s - } + }) // Causes BasicMode to write state.Code and then quit terminal.EventCh <- tty.KeyEvent{Rune: 'a'} terminal.EventCh <- tty.KeyEvent{Rune: 'b'} diff --git a/newedit/editor.go b/newedit/editor.go index 9f57594e..8d7c0bfe 100644 --- a/newedit/editor.go +++ b/newedit/editor.go @@ -41,9 +41,19 @@ func NewEditor(in, out *os.File, ev *eval.Evaler, st storedefs.Store) *Editor { }). AddGoFns("", bufferBuiltins(ed.State())) - // Hooks - ns["before-readline"], ed.BeforeReadline = initBeforeReadline(ev) - ns["after-readline"], ed.AfterReadline = initAfterReadline(ev) + // Add the builtin hook of appending history in after-readline. + ed.AddAfterReadline(func(code string) { + st.AddCmd(code) + // TODO: Log errors + }) + + // Elvish hook APIs + var beforeReadline func() + ns["before-readline"], beforeReadline = initBeforeReadline(ev) + ed.AddBeforeReadline(beforeReadline) + var afterReadline func(string) + ns["after-readline"], afterReadline = initAfterReadline(ev) + ed.AddAfterReadline(afterReadline) // Prompts ed.Prompt = makePrompt(ed, ev, ns, defaultPrompt, "prompt") diff --git a/newedit/editor_test.go b/newedit/editor_test.go index 88effbd4..5db8bca5 100644 --- a/newedit/editor_test.go +++ b/newedit/editor_test.go @@ -17,6 +17,10 @@ func TestNs(t *testing.T) { } } +func TestAddCmdAfterReadline(t *testing.T) { + // TODO +} + func TestInsertMode(t *testing.T) { // TODO }