From fca2f8a20cb3cd953beab58e7173a76b07fc0b96 Mon Sep 17 00:00:00 2001 From: Matthew Davidson Date: Tue, 10 Dec 2024 15:47:35 +0700 Subject: [PATCH] Add bind -x skeleton code --- builtin/readline_osh.py | 4 +--- frontend/py_readline.py | 18 ++++++++++++++++++ pyext/line_input.pyi | 1 + 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/builtin/readline_osh.py b/builtin/readline_osh.py index 4a87abbaf0..93ad838a75 100644 --- a/builtin/readline_osh.py +++ b/builtin/readline_osh.py @@ -142,9 +142,7 @@ def Run(self, cmd_val): readline.unbind_keyseq(arg.r) if arg.x is not None: - self.errfmt.Print_("warning: bind -x isn't implemented", - blame_loc=cmd_val.arg_locs[0]) - return 1 + readline.bind_shell_command(arg.x) if arg.X: readline.print_shell_cmd_map() diff --git a/frontend/py_readline.py b/frontend/py_readline.py index 5c7eafad5f..e124c66717 100644 --- a/frontend/py_readline.py +++ b/frontend/py_readline.py @@ -137,6 +137,24 @@ def print_shell_cmd_map(self): def unbind_keyseq(self, keyseq): # type: (str) -> None line_input.unbind_keyseq(keyseq) + + def bind_shell_command(self, cmdseq): + # type: (str) -> None + cmdseq_split = cmdseq.strip().split(":", 1) + if len(cmdseq_split) != 2: + raise ValueError("%s: missing colon separator" % cmdseq) + + # Below checks prevent need to do so in C, but also ensure rl_generic_bind + # will not try to incorrectly xfree `cmd`/`data`, which doesn't belong to it + keyseq = cmdseq_split[0].rstrip() + if len(keyseq) <= 2: + raise ValueError("%s: empty binding key sequence" % keyseq) + if keyseq[0] != '"' or keyseq[-1] != '"': + raise ValueError("%s: missing double-quotes around the binding" % keyseq) + keyseq = keyseq[1:-1] + + cmd = cmdseq_split[1] + line_input.bind_shell_command(keyseq, cmd) def MaybeGetReadline(): diff --git a/pyext/line_input.pyi b/pyext/line_input.pyi index 4061f68593..88fd6414d0 100644 --- a/pyext/line_input.pyi +++ b/pyext/line_input.pyi @@ -55,3 +55,4 @@ def print_shell_cmd_map() -> None: ... def unbind_keyseq(keyseq: str) -> None: ... +def bind_shell_command(keyseq: str, cmd: str) -> None: ...