pkg/cli: Simplify the API for dismissing a widget.

- Rename the method from "Close" to "Dimiss" to avoid any conflict with the
  standard interface{ Close() error }

- Remove the "accept" parameter from the Dismiss method and App.PopAddon - it is
  false in most places, and the few places that pass accept=true has knowledge
  of how to accept the state in the particular widget.

- edit:history:accept has been removed as a consequence - it is never
  documented, and is not currently used by any Elvish code published on GitHub
  (https://github.com/search?q=%22edit%3Ahistory%3Aaccept%22+extension%3Aelv&type=Code)
This commit is contained in:
Qi Xiao 2021-09-07 23:12:11 +01:00
parent d2936c06a1
commit f011034c06
15 changed files with 33 additions and 47 deletions

View File

@ -57,7 +57,7 @@ func main() {
},
},
GlobalBindings: tk.MapBindings{
term.K('[', ui.Ctrl): func(tk.Widget) { app.PopAddon(false) },
term.K('[', ui.Ctrl): func(tk.Widget) { app.PopAddon() },
},
})

View File

@ -27,9 +27,9 @@ type App interface {
// PushAddon pushes a widget to the addon stack.
PushAddon(w tk.Widget)
// PopAddon pops the last widget from the addon stack. If the widget
// implements interface{ Close(accept bool) }, the Close method is called
// implements interface{ Dismiss() }, the Dismiss method is called
// first. This method does nothing if the addon stack is empty.
PopAddon(accept bool)
PopAddon()
// ActiveWidget returns the currently active widget. If the addon stack is
// non-empty, it returns the last addon. Otherwise it returns the main code
@ -159,8 +159,8 @@ func (a *app) CopyState() State {
}
}
type closer interface {
Close(bool)
type dismisser interface {
Dismiss()
}
func (a *app) PushAddon(w tk.Widget) {
@ -169,14 +169,14 @@ func (a *app) PushAddon(w tk.Widget) {
a.State.Addons = append(a.State.Addons, w)
}
func (a *app) PopAddon(accept bool) {
func (a *app) PopAddon() {
a.StateMutex.Lock()
defer a.StateMutex.Unlock()
if len(a.State.Addons) == 0 {
return
}
if c, ok := a.State.Addons[len(a.State.Addons)-1].(closer); ok {
c.Close(accept)
if d, ok := a.State.Addons[len(a.State.Addons)-1].(dismisser); ok {
d.Dismiss()
}
a.State.Addons = a.State.Addons[:len(a.State.Addons)-1]
}

View File

@ -388,17 +388,17 @@ func TestPushAddonPopAddon(t *testing.T) {
"addon1> \n",
term.DotHere, "addon2> ")
f.App.PopAddon(false)
f.App.PopAddon()
f.App.Redraw()
f.TestTTY(t, "\n",
term.DotHere, "addon1> ")
f.App.PopAddon(false)
f.App.PopAddon()
f.App.Redraw()
f.TestTTY(t /* nothing */)
// Popping addon when there is no addon does nothing
f.App.PopAddon(false)
f.App.PopAddon()
// Add something to the codearea to ensure that we're not just looking at
// the previous buffer
f.TTY.Inject(term.K(' '))

View File

@ -66,7 +66,8 @@ func NewCompletion(app cli.App, cfg CompletionSpec) (Completion, error) {
})
},
OnAccept: func(it tk.Items, i int) {
app.PopAddon(true)
codeArea.MutateState((*tk.CodeAreaState).ApplyPending)
app.PopAddon()
},
ExtendStyle: true,
},
@ -77,14 +78,8 @@ func NewCompletion(app cli.App, cfg CompletionSpec) (Completion, error) {
return completion{w, codeArea}, nil
}
func (w completion) Close(accept bool) {
w.attached.MutateState(func(s *tk.CodeAreaState) {
if accept {
s.ApplyPending()
} else {
s.Pending = tk.PendingCode{}
}
})
func (w completion) Dismiss() {
w.attached.MutateState(func(s *tk.CodeAreaState) { s.Pending = tk.PendingCode{} })
}
type completionItems []CompletionItem

View File

@ -33,11 +33,11 @@ func TestCompletion_Accept(t *testing.T) {
f.TestTTY(t, "foo", term.DotHere)
}
func TestCompletion_Close(t *testing.T) {
func TestCompletion_Dismiss(t *testing.T) {
f := setupStartedCompletion(t)
defer f.Stop()
f.App.PopAddon(false)
f.App.PopAddon()
f.App.Redraw()
f.TestTTY(t /* nothing */)
}

View File

@ -74,7 +74,7 @@ func NewHistlist(app cli.App, spec HistlistSpec) (Histlist, error) {
buf.InsertAtDot("\n" + text)
}
})
app.PopAddon(false)
app.PopAddon()
},
},
OnFilter: func(w tk.ComboBox, p string) {

View File

@ -106,7 +106,7 @@ func TestHistlist_Dedup(t *testing.T) {
" 2 ls ", Styles,
"++++++++++++++++++++++++++++++++++++++++++++++++++")
f.App.PopAddon(false)
f.App.PopAddon()
// With dedup
startHistlist(f.App,

View File

@ -57,7 +57,8 @@ func (w *histwalk) Handle(event term.Event) bool {
if handled {
return true
}
w.app.PopAddon(true)
w.attachedTo.MutateState((*tk.CodeAreaState).ApplyPending)
w.app.PopAddon()
return w.attachedTo.Handle(event)
}
@ -106,14 +107,8 @@ func (w *histwalk) walk(f func(histutil.Cursor), undo func(histutil.Cursor)) err
return err
}
func (w *histwalk) Close(accept bool) {
w.attachedTo.MutateState(func(s *tk.CodeAreaState) {
if accept {
s.ApplyPending()
} else {
s.Pending = tk.PendingCode{}
}
})
func (w *histwalk) Dismiss() {
w.attachedTo.MutateState(func(s *tk.CodeAreaState) { s.Pending = tk.PendingCode{} })
}
func (w *histwalk) updatePending() {

View File

@ -31,8 +31,7 @@ func TestHistWalk(t *testing.T) {
Bindings: tk.MapBindings{
term.K(ui.Up): func(w tk.Widget) { w.(Histwalk).Prev() },
term.K(ui.Down): func(w tk.Widget) { w.(Histwalk).Next() },
term.K('[', ui.Ctrl): func(tk.Widget) { f.App.PopAddon(false) },
term.K(ui.Enter): func(tk.Widget) { f.App.PopAddon(true) },
term.K('[', ui.Ctrl): func(tk.Widget) { f.App.PopAddon() },
},
}
}
@ -64,8 +63,8 @@ func TestHistWalk(t *testing.T) {
// Start over and accept.
startHistwalk(f.App, getCfg())
f.TTY.TestBuffer(t, buf5)
f.TTY.Inject(term.K(ui.Enter))
f.TestTTY(t, "ls -a", term.DotHere)
f.TTY.Inject(term.K(' '))
f.TestTTY(t, "ls -a ", term.DotHere)
}
func TestHistWalk_FocusedWidgetNotCodeArea(t *testing.T) {

View File

@ -65,7 +65,7 @@ func NewLastcmd(app cli.App, cfg LastcmdSpec) (Lastcmd, error) {
codeArea.MutateState(func(s *tk.CodeAreaState) {
s.Buffer.InsertAtDot(text)
})
app.PopAddon(false)
app.PopAddon()
}
w := tk.NewComboBox(tk.ComboBoxSpec{
CodeArea: tk.CodeAreaSpec{Prompt: modePrompt(" LASTCMD ", true)},

View File

@ -54,7 +54,7 @@ func NewListing(app cli.App, spec ListingSpec) (Listing, error) {
spec.Caption = " LISTING "
}
accept := func(s string) {
app.PopAddon(false)
app.PopAddon()
spec.Accept(s)
}
w := tk.NewComboBox(tk.ComboBoxSpec{

View File

@ -107,7 +107,7 @@ func NewLocation(app cli.App, cfg LocationSpec) (Location, error) {
if err != nil {
app.Notify(err.Error())
}
app.PopAddon(false)
app.PopAddon()
},
},
OnFilter: func(w tk.ComboBox, p string) {

View File

@ -43,7 +43,7 @@ func dumpBuf(tty cli.TTY) string {
// Closes the current active mode.
func closeMode(app cli.App) {
app.PopAddon(false)
app.PopAddon()
}
//elvdoc:fn end-of-history
@ -114,7 +114,7 @@ func insertRaw(app cli.App, tty cli.TTY) {
codeArea.MutateState(func(s *tk.CodeAreaState) {
s.Buffer.InsertAtDot(string(event.Rune))
})
app.PopAddon(false)
app.PopAddon()
return true
default:
return false

View File

@ -51,14 +51,11 @@ func initHistWalk(ed *Editor, ev *eval.Evaler, hs *histStore, nb eval.NsBuilder)
"down-or-quit": func() {
err := histwalkDo(app, modes.Histwalk.Next)
if err == histutil.ErrEndOfHistory {
app.PopAddon(false)
app.PopAddon()
} else {
notifyError(app, err)
}
},
// TODO: Remove these builtins in favor of two universal accept and
// close builtins
"accept": func() { app.PopAddon(true) },
"fast-forward": hs.FastForward,
}).Ns())

View File

@ -36,7 +36,7 @@ func minibufSubmit(ed *Editor, ev *eval.Evaler) {
if !ok {
return
}
ed.app.PopAddon(false)
ed.app.PopAddon()
code := codeArea.CopyState().Buffer.Content
src := parse.Source{Name: "[minibuf]", Code: code}
notifyPort, cleanup := makeNotifyPort(ed)