From dbf190e492336c836f75debc8cc8dff9158f0968 Mon Sep 17 00:00:00 2001 From: Loric ANDRE Date: Sat, 18 Jul 2026 19:59:00 +0200 Subject: [PATCH] docs: document new binds --- man/man1/sk.1 | 45 ++++++++++++++++++++++++++++++++++++------- shell/completion.fish | 2 +- shell/completion.nu | 2 +- shell/completion.zsh | 4 ++-- src/manpage.rs | 34 ++++++++++++++++++++++++++++++-- src/options.rs | 11 ++++++----- 6 files changed, 80 insertions(+), 18 deletions(-) diff --git a/man/man1/sk.1 b/man/man1/sk.1 index 2bf76634..3559a093 100644 --- a/man/man1/sk.1 +++ b/man/man1/sk.1 @@ -197,13 +197,14 @@ history: History scheme: will force index as the first tiebreak .SH INTERFACE .TP \fB\-b\fR, \fB\-\-bind\fR [\fI...\fR] [default: ] -Comma separated list of bindings +Comma\-separated key, event, and action bindings -You can customize key bindings of sk with `\-\-bind` option which takes a comma\-separated list of -key binding expressions. Each key binding expression follows the following format: `:` -See the [KEYBINDS] section for details +`\-\-bind` takes comma\-separated `:` expressions. A trigger can be a key, a finder +event (`change`, `start`, `load`, `result`, `focus`, `zero`, or `one`), or an action name. Use the +`act\-` prefix for action triggers; it is recommended to avoid ambiguity and required when the action +name is also a key, for example `act\-up:last`. See the [KEYBINDS] section for details. -**Example**: `sk \-\-bind=ctrl\-j:accept,ctrl\-k:kill\-line` +**Example**: `sk \-\-bind=ctrl\-j:accept,load:last,act\-up:down` ## Multiple actions can be chained using + separator. @@ -752,9 +753,9 @@ If a term is prefixed by `!`, sk will exclude the items that match this term. .SH KEYBINDS .br -Keybinds can be set by the `\-\-bind` option, which takes a comma\-separated list of [key]:[action[+action2]. +Bindings can be set by the `\-\-bind` option, which takes a comma\-separated list of `:[+action2]` expressions. A trigger can be a key, a finder event, or an action name. .br -Actions can take arguments, specified either between parentheses `reload(ls)` or after a colon `reload:ls` +Actions can take arguments, specified either between parentheses `reload(ls)` or after a colon `reload:ls`. .br .SS "Available keys (aliases in parentheses)" @@ -837,6 +838,34 @@ Actions can take arguments, specified either between parentheses `reload(ls)` or * any single character .br +.SS "Bindable finder events" + +.br +* change: the query changes +.br +* start: skim enters its event loop; fired once +.br +* load: the reader and matcher finish consuming the current input; fired once per read, including reloads +.br +* result: filtering for the current query completes +.br +* focus: the focused item changes because of cursor movement or a result update +.br +* zero: a completed search has no matches +.br +* one: a completed search has exactly one match +.br + +.SS "Actions as binding triggers" + +.br +Actions can also be used as binding triggers. A follow\-up chain bound to an action name runs immediately after that action. Use the `act\-` prefix for action triggers; it is recommended to avoid ambiguity and required when the action name is also a key, for example `act\-up:last`. +.br + +.br +Follow\-up chains use non\-recursive (`noremap`) semantics: their actions do not trigger further action bindings. Add `suppress` to skip the triggering action\*(Aqs default behavior, for example `act\-up:suppress+down`. +.br + .SS "Actions[:default keys][*notes]" .br @@ -932,6 +961,8 @@ Actions can take arguments, specified either between parentheses `reload(ls)` or .br * set\-query(...): *arg will be a expanded expression, see COMMAND EXPANSION for details .br +* suppress: *if bound to an action (e.g. `act\-up:suppress`), suppresses that action\*(Aqs default behavior so the rest of the non\-recursive chain runs once in its place; if bound to a key, equivalent to `ignore` +.br * toggle .br * toggle\-all diff --git a/shell/completion.fish b/shell/completion.fish index c9ef6235..26594e61 100644 --- a/shell/completion.fish +++ b/shell/completion.fish @@ -28,7 +28,7 @@ complete -c sk -l split-match -d 'Enable split matching and set delimiter' -r complete -c sk -l scheme -r -f -a "default\t'Default scheme, no modifications to the options' path\t'Path scheme: will find the furthest match in the item and set pathname as the main tiebreak' history\t'History scheme: will force index as the first tiebreak'" -complete -c sk -s b -l bind -d 'Comma separated list of bindings' -r +complete -c sk -s b -l bind -d 'Comma-separated key, event, and action bindings' -r complete -c sk -s c -l cmd -d 'Command to invoke dynamically in interactive mode' -r complete -c sk -s I -d 'Replace replstr with the selected item in commands' -r complete -c sk -l color -d 'Set color theme' -r diff --git a/shell/completion.nu b/shell/completion.nu index 97d580c7..8f2a3992 100644 --- a/shell/completion.nu +++ b/shell/completion.nu @@ -56,7 +56,7 @@ module completions { --split-match: string # Enable split matching and set delimiter --last-match # Highlight the last match found, not the first one This makes tiebreak more pertinent on path items where we want to prioritize a match on the last parts --scheme: string@"nu-complete sk scheme" - --bind(-b): string # Comma separated list of bindings + --bind(-b): string # Comma-separated key, event, and action bindings --multi(-m) # Enable multiple selection --no-multi # Disable multiple selection --no-mouse # Disable mouse diff --git a/shell/completion.zsh b/shell/completion.zsh index 6fbbbb9a..eb57378f 100644 --- a/shell/completion.zsh +++ b/shell/completion.zsh @@ -37,8 +37,8 @@ smart\:"Smart case\: case-insensitive unless query contains uppercase"))' \ '--scheme=[]:SCHEME:((default\:"Default scheme, no modifications to the options" path\:"Path scheme\: will find the furthest match in the item and set pathname as the main tiebreak" history\:"History scheme\: will force index as the first tiebreak"))' \ -'*-b+[Comma separated list of bindings]::BIND:_default' \ -'*--bind=[Comma separated list of bindings]::BIND:_default' \ +'*-b+[Comma-separated key, event, and action bindings]::BIND:_default' \ +'*--bind=[Comma-separated key, event, and action bindings]::BIND:_default' \ '-c+[Command to invoke dynamically in interactive mode]:CMD:_default' \ '--cmd=[Command to invoke dynamically in interactive mode]:CMD:_default' \ '-I+[Replace replstr with the selected item in commands]:REPLSTR:_default' \ diff --git a/src/manpage.rs b/src/manpage.rs index 02221d83..6e0a189f 100644 --- a/src/manpage.rs +++ b/src/manpage.rs @@ -121,6 +121,22 @@ const KEYS_SS: &str = " * alt-shift-right * any single character "; +const BINDABLE_EVENTS_SS: &str = " +* change: the query changes +* start: skim enters its event loop; fired once +* load: the reader and matcher finish consuming the current input; fired once per read, including reloads +* result: filtering for the current query completes +* focus: the focused item changes because of cursor movement or a result update +* zero: a completed search has no matches +* one: a completed search has exactly one match +"; + +const ACTION_BINDINGS_SS: &str = " +Actions can also be used as binding triggers. A follow-up chain bound to an action name runs immediately after that action. Use the `act-` prefix for action triggers; it is recommended to avoid ambiguity and required when the action name is also a key, for example `act-up:last`. + +Follow-up chains use non-recursive (`noremap`) semantics: their actions do not trigger further action bindings. Add `suppress` to skip the triggering action's default behavior, for example `act-up:suppress+down`. +"; + const ACTIONS_SS: &str = " * abort: ctrl-c ctrl-q esc * accept(...): enter *the argument will be printed when the binding is triggered* @@ -286,11 +302,13 @@ Exact search can be enabled by default by the `--exact` command-line flag. In ex &mut custom, "KEYBINDS", " -Keybinds can be set by the `--bind` option, which takes a comma-separated list of [key]:[action[+action2]. -Actions can take arguments, specified either between parentheses `reload(ls)` or after a colon `reload:ls` +Bindings can be set by the `--bind` option, which takes a comma-separated list of `:[+action2]` expressions. A trigger can be a key, a finder event, or an action name. +Actions can take arguments, specified either between parentheses `reload(ls)` or after a colon `reload:ls`. ", ); subsection(&mut custom, "Available keys (aliases in parentheses)", KEYS_SS); + subsection(&mut custom, "Bindable finder events", BINDABLE_EVENTS_SS); + subsection(&mut custom, "Actions as binding triggers", ACTION_BINDINGS_SS); subsection(&mut custom, "Actions[:default keys][*notes]", ACTIONS_SS); section( @@ -408,4 +426,16 @@ mod tests { assert!(out.contains(section), "manpage should contain section '{section}'"); } } + + #[test] + fn manpage_documents_bindable_events_and_actions() { + let out = manpage_str(); + for event in ["change", "start", "load", "result", "focus", "zero", "one"] { + assert!(out.contains(event), "manpage should document the '{event}' event"); + } + assert!(out.contains("Actions as binding triggers")); + assert!(out.contains("act\\-")); + assert!(out.contains("noremap")); + assert!(out.contains("suppress")); + } } diff --git a/src/options.rs b/src/options.rs index abaed942..0e184fc1 100644 --- a/src/options.rs +++ b/src/options.rs @@ -319,13 +319,14 @@ pub struct SkimOptions { scheme: Option, // --- Interface --- - /// Comma separated list of bindings + /// Comma-separated key, event, and action bindings /// - /// You can customize key bindings of sk with `--bind` option which takes a comma-separated list of - /// key binding expressions. Each key binding expression follows the following format: `:` - /// See the [KEYBINDS] section for details + /// `--bind` takes comma-separated `:` expressions. A trigger can be a key, a finder + /// event (`change`, `start`, `load`, `result`, `focus`, `zero`, or `one`), or an action name. Use the + /// `act-` prefix for action triggers; it is recommended to avoid ambiguity and required when the action + /// name is also a key, for example `act-up:last`. See the [KEYBINDS] section for details. /// - /// **Example**: `sk --bind=ctrl-j:accept,ctrl-k:kill-line` + /// **Example**: `sk --bind=ctrl-j:accept,load:last,act-up:down` /// /// ## Multiple actions can be chained using + separator. ///