Show set-cmd-text command bindings in completion.
Fixes #5942. For bindings like `o -> :set-cmd-text -s :open`, the user conceptually expects that `o` maps to `open`, yet they do not show in the command completion UI. With this patch, a binding to a command of form `set-cmd-text [flags...] :<cmd> [cmdargs]` will be treated as if it were bound to `<cmd> [cmdargs]` instead for the purpose of completion. Bindings to `set-cmd-text --append` are ignored.
This commit is contained in:
parent
8e7f24bc0c
commit
2c4bb064e6
|
|
@ -162,13 +162,40 @@ class KeyConfig:
|
|||
bindings[key] = binding
|
||||
return bindings
|
||||
|
||||
def _strip_leading_flags(self, cmdline: str) -> List[str]:
|
||||
"""Split cmdline at whitespace until the first non-flag."""
|
||||
first, _, rest = cmdline.partition(" ")
|
||||
if first.startswith("-"):
|
||||
return [first] + self._strip_leading_flags(rest)
|
||||
return [cmdline]
|
||||
|
||||
def _implied_cmd(self, cmdline: str) -> str:
|
||||
"""Return cmdline, or the implied cmd if cmdline is a set-cmd-text."""
|
||||
if not cmdline.startswith("set-cmd-text "):
|
||||
return cmdline
|
||||
cmdline = cmdline[len("set-cmd-text "):]
|
||||
*flags, cmd = self._strip_leading_flags(cmdline)
|
||||
if "-a" in flags or "--append" in flags or not cmd.startswith(":"):
|
||||
return "" # doesn't look like this sets a command
|
||||
return cmd.lstrip(":")
|
||||
|
||||
def get_reverse_bindings_for(self, mode: str) -> '_ReverseBindings':
|
||||
"""Get a dict of commands to a list of bindings for the mode."""
|
||||
"""Get a dict of commands to a list of bindings for the mode.
|
||||
|
||||
This is intented for user-facing display of keybindings.
|
||||
As such, bindings for 'set-cmd-text [flags] :<cmd> ...' are translated
|
||||
to '<cmd> ...', as from the user's perspective these keys behave like
|
||||
bindings for '<cmd>' (that allow for further input before running).
|
||||
|
||||
See #5942.
|
||||
"""
|
||||
cmd_to_keys: KeyConfig._ReverseBindings = {}
|
||||
bindings = self.get_bindings_for(mode)
|
||||
for seq, full_cmd in sorted(bindings.items()):
|
||||
for cmd in full_cmd.split(';;'):
|
||||
cmd = cmd.strip()
|
||||
cmd = self._implied_cmd(cmd.strip())
|
||||
if not cmd:
|
||||
continue
|
||||
cmd_to_keys.setdefault(cmd, [])
|
||||
# Put bindings involving modifiers last
|
||||
if any(info.modifiers for info in seq):
|
||||
|
|
|
|||
|
|
@ -198,6 +198,26 @@ class TestKeyConfig:
|
|||
# Chained command
|
||||
({'a': 'message-info foo ;; message-info bar'},
|
||||
{'message-info foo': ['a'], 'message-info bar': ['a']}),
|
||||
# Command using set-cmd-text (#5942)
|
||||
(
|
||||
{
|
||||
"o": "set-cmd-text -s :open",
|
||||
"O": "set-cmd-text -s :open -t",
|
||||
"go": "set-cmd-text :open {url:pretty}",
|
||||
# all of these should be ignored
|
||||
"/": "set-cmd-text /",
|
||||
"?": "set-cmd-text ?",
|
||||
":": "set-cmd-text :",
|
||||
"a": "set-cmd-text no_leading_colon",
|
||||
"b": "set-cmd-text -s -a :skip_cuz_append",
|
||||
"c": "set-cmd-text --append :skip_cuz_append",
|
||||
},
|
||||
{
|
||||
"open": ["o"],
|
||||
"open -t": ["O"],
|
||||
"open {url:pretty}": ["go"],
|
||||
}
|
||||
),
|
||||
])
|
||||
def test_get_reverse_bindings_for(self, key_config_stub, config_stub,
|
||||
no_bindings, bindings, expected):
|
||||
|
|
|
|||
Loading…
Reference in New Issue