pkg/cli: Add a SetAddon method to App.

This commit is contained in:
Qi Xiao 2021-02-12 18:20:04 +00:00
parent 8fbbdf4983
commit c2319fbf59
14 changed files with 44 additions and 28 deletions

View File

@ -24,6 +24,12 @@ type App interface {
CopyState() State
// CodeArea returns the codearea widget of the app.
CodeArea() tk.CodeArea
// SetAddon sets the current addon to the given widget. If there is an
// existing addon, it is closed first. If the existing addon implements
// interface{ Close(bool) }, the Close method is called with the accept
// argument. To close the current addon without setting a new one, call
// SetAddon(nil, accept).
SetAddon(w tk.Widget, accept bool)
// CommitEOF causes the main loop to exit with EOF. If this method is called
// when an event is being handled, the main loop will exit after the handler
@ -76,10 +82,6 @@ type State struct {
Addon tk.Widget
}
type focuser interface {
Focus() bool
}
// NewApp creates a new App from the given specification.
func NewApp(spec AppSpec) App {
lp := newLoop()
@ -148,6 +150,19 @@ func (a *app) CodeArea() tk.CodeArea {
return a.codeArea
}
type closer interface {
Close(bool)
}
func (a *app) SetAddon(w tk.Widget, accept bool) {
a.StateMutex.Lock()
defer a.StateMutex.Unlock()
if c, ok := a.State.Addon.(closer); ok {
c.Close(accept)
}
a.State.Addon = w
}
func (a *app) resetAllStates() {
a.MutateState(func(s *State) { *s = State{} })
a.codeArea.MutateState(
@ -236,6 +251,10 @@ func renderNotes(notes []string, width int) *term.Buffer {
return bb.Buffer()
}
type focuser interface {
Focus() bool
}
// Renders the codearea, and uses the rest of the height for the listing.
func renderApp(codeArea, addon tk.Renderer, width, height int) *term.Buffer {
buf := codeArea.Render(width, height)

View File

@ -54,7 +54,7 @@ func Start(app cli.App, cfg Config) {
app.CodeArea().MutateState(func(s *tk.CodeAreaState) {
s.ApplyPending()
})
app.MutateState(func(s *cli.State) { s.Addon = nil })
app.SetAddon(nil, false)
},
ExtendStyle: true,
},
@ -62,7 +62,7 @@ func Start(app cli.App, cfg Config) {
w.ListBox().Reset(filter(cfg.Items, p), 0)
},
})
app.MutateState(func(s *cli.State) { s.Addon = w })
app.SetAddon(w, false)
app.Redraw()
}
@ -70,7 +70,7 @@ func Start(app cli.App, cfg Config) {
func Close(app cli.App) {
app.CodeArea().MutateState(
func(s *tk.CodeAreaState) { s.Pending = tk.PendingCode{} })
app.MutateState(func(s *cli.State) { s.Addon = nil })
app.SetAddon(nil, false)
app.Redraw()
}

View File

@ -80,7 +80,7 @@ func Start(app cli.App, cfg Config) {
buf.InsertAtDot("\n" + text)
}
})
app.MutateState(func(s *cli.State) { s.Addon = nil })
app.SetAddon(nil, false)
},
},
OnFilter: func(w tk.ComboBox, p string) {
@ -89,7 +89,7 @@ func Start(app cli.App, cfg Config) {
},
})
app.MutateState(func(s *cli.State) { s.Addon = w })
app.SetAddon(w, false)
app.Redraw()
}

View File

@ -5,7 +5,6 @@ import (
"fmt"
"testing"
"src.elv.sh/pkg/cli"
. "src.elv.sh/pkg/cli/clitest"
"src.elv.sh/pkg/cli/histutil"
"src.elv.sh/pkg/cli/mode"
@ -90,7 +89,7 @@ func TestStart_Dedup(t *testing.T) {
" 0 ls",
" 1 echo",
" 2 ls"))
f.App.MutateState(func(s *cli.State) { s.Addon = nil })
f.App.SetAddon(nil, false)
// With dedup
Start(f.App, Config{Store: st, Dedup: func() bool { return true }})
@ -116,7 +115,7 @@ func TestStart_CaseSensitive(t *testing.T) {
makeListingBuf(
" HISTORY (dedup on) ", "l",
" 0 ls"))
f.App.MutateState(func(s *cli.State) { s.Addon = nil })
f.App.SetAddon(nil, false)
// Case insensitive
Start(f.App, Config{Store: st, CaseSensitive: func() bool { return false }})

View File

@ -77,7 +77,7 @@ func Start(app cli.App, cfg Config) {
}
w := widget{app: app, Config: cfg, cursor: cursor}
w.onWalk()
app.MutateState(func(s *cli.State) { s.Addon = &w })
app.SetAddon(&w, false)
app.Redraw()
}

View File

@ -84,6 +84,6 @@ func Start(app cli.App, cfg Config) {
textView: tk.NewTextView(tk.TextViewSpec{Scrollable: true}),
}
w.update(true)
app.MutateState(func(s *cli.State) { s.Addon = &w })
app.SetAddon(&w, false)
app.Redraw()
}

View File

@ -60,7 +60,7 @@ func Start(app cli.App, cfg Config) {
app.CodeArea().MutateState(func(s *tk.CodeAreaState) {
s.Buffer.InsertAtDot(text)
})
app.MutateState(func(s *cli.State) { s.Addon = nil })
app.SetAddon(nil, false)
}
w := tk.NewComboBox(tk.ComboBoxSpec{
CodeArea: tk.CodeAreaSpec{Prompt: mode.Prompt(" LASTCMD ", true)},
@ -79,7 +79,7 @@ func Start(app cli.App, cfg Config) {
}
},
})
app.MutateState(func(s *cli.State) { s.Addon = w })
app.SetAddon(w, false)
app.Redraw()
}

View File

@ -49,7 +49,7 @@ func Start(app cli.App, cfg Config) {
accept := func(s string) {
retain := cfg.Accept(s)
if !retain {
app.MutateState(func(s *cli.State) { s.Addon = nil })
app.SetAddon(nil, false)
}
}
w := tk.NewComboBox(tk.ComboBoxSpec{
@ -71,7 +71,7 @@ func Start(app cli.App, cfg Config) {
}
},
})
app.MutateState(func(s *cli.State) { s.Addon = w })
app.SetAddon(w, false)
app.Redraw()
}

View File

@ -103,14 +103,14 @@ func Start(app cli.App, cfg Config) {
if err != nil {
app.Notify(err.Error())
}
app.MutateState(func(s *cli.State) { s.Addon = nil })
app.SetAddon(nil, false)
},
},
OnFilter: func(w tk.ComboBox, p string) {
w.ListBox().Reset(l.filter(p), 0)
},
})
app.MutateState(func(s *cli.State) { s.Addon = w })
app.SetAddon(w, false)
app.Redraw()
}

View File

@ -156,7 +156,7 @@ func Start(app cli.App, cfg Config) {
}),
}
updateState(w, "")
app.MutateState(func(s *cli.State) { s.Addon = w })
app.SetAddon(w, false)
app.Redraw()
}

View File

@ -44,6 +44,6 @@ func Start(app cli.App, cfg Config) {
cfg.Binding = tk.DummyHandler{}
}
w := widget{cfg}
app.MutateState(func(s *cli.State) { s.Addon = &w })
app.SetAddon(&w, false)
app.Redraw()
}

View File

@ -43,7 +43,7 @@ func dumpBuf(tty cli.TTY) string {
// Closes any active listing.
func closeListing(app cli.App) {
app.MutateState(func(s *cli.State) { s.Addon = nil })
app.SetAddon(nil, false)
}
//elvdoc:fn end-of-history

View File

@ -4,7 +4,6 @@ import (
"io"
"testing"
"src.elv.sh/pkg/cli"
"src.elv.sh/pkg/cli/term"
"src.elv.sh/pkg/cli/tk"
"src.elv.sh/pkg/eval/vals"
@ -28,7 +27,7 @@ func TestCloseListing(t *testing.T) {
f := setup()
defer f.Cleanup()
f.Editor.app.MutateState(func(s *cli.State) { s.Addon = tk.Empty{} })
f.Editor.app.SetAddon(tk.Empty{}, false)
evals(f.Evaler, `edit:close-listing`)
if listing := f.Editor.app.CopyState().Addon; listing != nil {

View File

@ -1,7 +1,6 @@
package edit
import (
"src.elv.sh/pkg/cli"
"src.elv.sh/pkg/cli/mode"
"src.elv.sh/pkg/cli/tk"
"src.elv.sh/pkg/eval"
@ -27,7 +26,7 @@ func minibufStart(ed *Editor, ev *eval.Evaler, binding tk.Handler) {
// TODO: Add Highlighter. Right now the async highlighter is not
// directly usable.
})
ed.app.MutateState(func(s *cli.State) { s.Addon = w })
ed.app.SetAddon(w, false)
ed.app.Redraw()
}
@ -37,7 +36,7 @@ func minibufSubmit(ed *Editor, ev *eval.Evaler) {
if !ok {
return
}
ed.app.MutateState(func(s *cli.State) { s.Addon = nil })
ed.app.SetAddon(nil, false)
code := codeArea.CopyState().Buffer.Content
src := parse.Source{Name: "[minibuf]", Code: code}
notifyPort, cleanup := makeNotifyPort(ed)