pkg/edit: Show dedup binding in history listing mode.

Also fix a lot of elvdoc.
This commit is contained in:
Qi Xiao 2022-12-06 22:47:17 +00:00
parent fe4ca3cb05
commit 1acc45cfc2
6 changed files with 108 additions and 45 deletions

View File

@ -26,6 +26,8 @@ type HistlistSpec struct {
Dedup func() bool
// Configuration for the filter.
Filter FilterSpec
// RPrompt of the code area (first row of the widget).
CodeAreaRPrompt func() ui.Text
}
// NewHistlist creates a new histlist mode.
@ -60,6 +62,7 @@ func NewHistlist(app cli.App, spec HistlistSpec) (Histlist, error) {
}
return modeLine(content, true)
},
RPrompt: spec.CodeAreaRPrompt,
Highlighter: spec.Filter.Highlighter,
},
ListBox: tk.ListBoxSpec{

View File

@ -1,3 +1,6 @@
# Common binding table for [listing modes](#listing-modes).
var listing:binding { }
# Accepts the current selected listing item.
fn listing:accept { }
@ -21,30 +24,39 @@ fn listing:page-up { }
# Moves the cursor down one page.
fn listing:page-down { }
# Moves the cursor left in listing mode.
fn listing:left { }
# Starts the history listing mode.
fn histlist:start { }
# Moves the cursor right in listing mode.
fn listing:right { }
# ```elvish
# edit:location:hidden
# ```
# Toggles deduplication in history listing mode.
#
# When deduplication is on (the default), only the last occurrence of the same
# command is shown.
fn histlist:toggle-dedup { }
# Keybinding for the history listing mode.
#
# Keys bound to [edit:histlist:toggle-dedup](#edit:histlist:toggle-dedup)
# (Ctrl-D by default) will be shown in the history listing UI.
var histlist:binding
# Starts the last command mode.
fn lastcmd:start { }
# Keybinding for the last command mode.
var lastcmd:binding
# Starts the location mode.
fn location:start
# Keybinding for the location mode.
var location:binding
# A list of directories to hide in the location addon.
var location:hidden
# ```elvish
# edit:location:pinned
# ```
#
# A list of directories to always show at the top of the list of the location
# addon.
var location:pinned
# ```elvish
# edit:location:workspaces
# ```
#
# A map mapping types of workspaces to their patterns.
var location:workspaces

View File

@ -12,6 +12,7 @@ import (
"src.elv.sh/pkg/eval/vals"
"src.elv.sh/pkg/eval/vars"
"src.elv.sh/pkg/store/storedefs"
"src.elv.sh/pkg/ui"
)
func initListings(ed *Editor, ev *eval.Evaler, st storedefs.Store, histStore histutil.Store, nb eval.NsBuilder) {
@ -53,27 +54,32 @@ func initHistlist(ed *Editor, ev *eval.Evaler, histStore histutil.Store, commonB
bindingVar := newBindingVar(emptyBindingsMap)
bindings := newMapBindings(ed, ev, bindingVar, commonBindingVar)
dedup := newBoolVar(true)
nb.AddNs("histlist",
eval.BuildNsNamed("edit:histlist").
AddVar("binding", bindingVar).
AddGoFns(map[string]any{
"start": func() {
w, err := modes.NewHistlist(ed.app, modes.HistlistSpec{
Bindings: bindings,
AllCmds: histStore.AllCmds,
Dedup: func() bool {
return dedup.Get().(bool)
},
Filter: filterSpec,
})
startMode(ed.app, w, err)
},
"toggle-dedup": func() {
dedup.Set(!dedup.Get().(bool))
listingRefilter(ed.app)
ed.app.Redraw()
},
}))
var ns *eval.Ns
ns = eval.BuildNsNamed("edit:histlist").
AddVar("binding", bindingVar).
AddGoFns(map[string]any{
"start": func() {
w, err := modes.NewHistlist(ed.app, modes.HistlistSpec{
Bindings: bindings,
AllCmds: histStore.AllCmds,
Dedup: func() bool {
return dedup.Get().(bool)
},
Filter: filterSpec,
CodeAreaRPrompt: func() ui.Text {
return bindingHelp(bindingVar.Get().(bindingsMap), ns,
bindingHelpEntry{"dedup", "toggle-dedup"})
},
})
startMode(ed.app, w, err)
},
"toggle-dedup": func() {
dedup.Set(!dedup.Get().(bool))
listingRefilter(ed.app)
ed.app.Redraw()
},
}).Ns()
nb.AddNs("histlist", ns)
}
func initLastcmd(ed *Editor, ev *eval.Evaler, histStore histutil.Store, commonBindingVar vars.PtrVar, nb eval.NsBuilder) {

View File

@ -1,2 +1,36 @@
# Starts a custom listing addon.
fn listing:start-custom { }
# Starts custom listing mode.
#
# The `$items` argument can be as a list of maps, each map representing one item
# and having the following keys:
#
# - The value of the `to-show` key must be a string or a styled text. It is used
# in the listing UI.
#
# - The value of the `to-filter` key must be a string. It is used when filtering
# the item.
#
# - The value of the `to-accept` key must be a string. It is passed to the
# accept callback (see below).
#
# Alternatively, the `$items` argument can be a function taking one argument. It
# will be called with the value of the filter (initially an empty string), and
# can output any number of maps containing the `to-show` and `to-accept` keys,
# with the same semantics as above. Any other key is ignored.
#
# The `&binding` option, if specified, should be a binding map to use in the
# custom listing mode. Bindings from
# [`$edit:listing:binding`](#$edit:listing:binding) are also used, after this
# map if it is specified.
#
# The `&caption` option changes the caption of the mode. If empty, the caption
# defaults to `' LISTING '`.
#
# The `&keep-bottom` option, if true, makes the last item to get selected
# initially or when the filter changes.
#
# The `&accept` option specifies a function to call when an item is accepted. It
# is passed the value of the `to-accept` key of the item.
#
# The `&auto-accept` option, if true, accepts an item automatically when there
# is only one item being shown.
fn listing:start-custom {|items &binding=$nil &caption='' &keep-bottom=$false &accept=$nil &auto-accept=$false| }

View File

@ -84,7 +84,9 @@ func TestHistlistAddon(t *testing.T) {
f.TestTTY(t,
"~> \n",
" HISTORY (dedup on) ", Styles,
"******************** ", term.DotHere, "\n",
"******************** ", term.DotHere,
" Ctrl-D dedup\n", Styles,
" ++++++ ",
" 2 echo\n",
" 3 ls\n",
" 4 LS ", Styles,
@ -95,7 +97,9 @@ func TestHistlistAddon(t *testing.T) {
f.TestTTY(t,
"~> \n",
" HISTORY ", Styles,
"********* ", term.DotHere, "\n",
"********* ", term.DotHere,
" Ctrl-D dedup\n", Styles,
" ++++++ ",
" 1 ls\n",
" 2 echo\n",
" 3 ls\n",
@ -110,7 +114,9 @@ func TestHistlistAddon(t *testing.T) {
f.TestTTY(t,
"~> \n",
" HISTORY (dedup on) l", Styles,
"******************** ", term.DotHere, "\n",
"******************** ", term.DotHere,
" Ctrl-D dedup\n", Styles,
" ++++++ ",
" 3 ls\n",
" 4 LS ", Styles,
"++++++++++++++++++++++++++++++++++++++++++++++++++",
@ -121,7 +127,9 @@ func TestHistlistAddon(t *testing.T) {
f.TestTTY(t,
"~> \n",
" HISTORY (dedup on) L", Styles,
"******************** ", term.DotHere, "\n",
"******************** ", term.DotHere,
" Ctrl-D dedup\n", Styles,
" ++++++ ",
" 4 LS ", Styles,
"++++++++++++++++++++++++++++++++++++++++++++++++++",
)

View File

@ -227,8 +227,8 @@ You cannot write `Shift-m` as a synonym for `M`.
### Listing Modes
The modes `histlist`, `loc` and `lastcmd` are all **listing modes**: They all
show a list, and you can filter items and accept items.
The modes `histlist`, `location` and `lastcmd` are all **listing modes**: They
all show a list, and you can filter items and accept items.
Because they are very similar, you may want to change their bindings at the same
time. This is made possible by the `$edit:listing:binding` binding table