diff --git a/Doc/library/cmd.rst b/Doc/library/cmd.rst index fd5df96dfd0b3d..ebfa9f48bc0295 100644 --- a/Doc/library/cmd.rst +++ b/Doc/library/cmd.rst @@ -15,7 +15,7 @@ command interpreters. These are often useful for test harnesses, administrative tools, and prototypes that will later be wrapped in a more sophisticated interface. -.. class:: Cmd(completekey='tab', stdin=None, stdout=None) +.. class:: Cmd(completekey=r'"\t"', stdin=None, stdout=None) A :class:`Cmd` instance or subclass instance is a line-oriented interpreter framework. There is no good reason to instantiate :class:`Cmd` itself; rather, @@ -23,7 +23,7 @@ interface. to inherit :class:`Cmd`'s methods and encapsulate action methods. The optional argument *completekey* is the :mod:`readline` name of a completion - key; it defaults to :kbd:`Tab`. If *completekey* is not :const:`None` and + key; it defaults to "\\t"(:kbd:`tab`). If *completekey* is not :const:`None` and :mod:`readline` is available, command completion is done automatically. The optional arguments *stdin* and *stdout* specify the input and output file diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index ef52370bff8058..c9665e8ba3b236 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -183,7 +183,7 @@ The ``run*`` functions and :func:`set_trace` are aliases for instantiating the :class:`Pdb` class and calling the method of the same name. If you want to access further features, you have to do this yourself: -.. class:: Pdb(completekey='tab', stdin=None, stdout=None, skip=None, \ +.. class:: Pdb(completekey=r'"\t"', stdin=None, stdout=None, skip=None, \ nosigint=False, readrc=True) :class:`Pdb` is the debugger class. diff --git a/Doc/library/readline.rst b/Doc/library/readline.rst index 8fb0eca8df74d8..d4e1a1fb11565e 100644 --- a/Doc/library/readline.rst +++ b/Doc/library/readline.rst @@ -17,6 +17,21 @@ made using this module affect the behaviour of both the interpreter's interactive prompt and the prompts offered by the built-in :func:`input` function. +Compatible keybindings +---------------------- + +To support compatible keybindings between GNU readline and Libedit, use the +following backslashed escape sequences or octal escape sequences in quotes. :: + + \a bell + \b backspace + \f form feed + \n newline + \r carriage return + \t horizontal tab + \v vertical tab + \nnn octal escape sequences + Readline keybindings may be configured via an initialization file, typically ``.inputrc`` in your home directory. See `Readline Init File `_ @@ -39,10 +54,10 @@ Readline library in general. If you use *editline*/``libedit`` readline emulation on macOS, the initialization file located in your home directory is named ``.editrc``. For example, the following content in ``~/.editrc`` will - turn ON *vi* keybindings and TAB completion:: + turn ON *vi* keybindings and "\\t"(:kbd:`tab`) completion:: python:bind -v - python:bind ^I rl_complete + python:bind "\t" rl_complete Init file @@ -56,6 +71,16 @@ The following functions relate to the init file and user configuration: Execute the init line provided in the *string* argument. This calls :c:func:`rl_parse_and_bind` in the underlying library. +.. note:: + The syntax and command of *string* argument may be different depends on the readline library. + + For GNU readline:: + + readline.parse_and_bind(r'"\t": complete') + + For Libedit:: + + readline.parse_and_bind(r'bind "\t" rl_complete') .. function:: read_init_file([filename]) @@ -348,7 +373,12 @@ support history save/restore. :: self.init_history(histfile) def init_history(self, histfile): - readline.parse_and_bind("tab: complete") + + readline_doc = getattr(readline, '__doc__', '') + if readline_doc is not None and 'libedit' in readline_doc: + readline.parse_and_bind(r'bind "\t" rl_complete') + else: + readline.parse_and_bind(r'"\t": complete') if hasattr(readline, "read_history_file"): try: readline.read_history_file(histfile) diff --git a/Doc/library/rlcompleter.rst b/Doc/library/rlcompleter.rst index 40b09ce897880e..fd521cc5de1365 100644 --- a/Doc/library/rlcompleter.rst +++ b/Doc/library/rlcompleter.rst @@ -21,7 +21,7 @@ Example:: >>> import rlcompleter >>> import readline - >>> readline.parse_and_bind("tab: complete") + >>> readline.parse_and_bind(r'"\t": complete') >>> readline. readline.__doc__ readline.get_line_buffer( readline.read_init_file( readline.__file__ readline.insert_text( readline.set_completer( diff --git a/Lib/cmd.py b/Lib/cmd.py index 88ee7d3ddc4694..da97e520a9f202 100644 --- a/Lib/cmd.py +++ b/Lib/cmd.py @@ -73,7 +73,7 @@ class Cmd: nohelp = "*** No help on %s" use_rawinput = 1 - def __init__(self, completekey='tab', stdin=None, stdout=None): + def __init__(self, completekey='"\t"', stdin=None, stdout=None): """Instantiate a line-oriented interpreter framework. The optional argument 'completekey' is the readline name of a @@ -108,7 +108,11 @@ def cmdloop(self, intro=None): import readline self.old_completer = readline.get_completer() readline.set_completer(self.complete) - readline.parse_and_bind(self.completekey+": complete") + readline_doc = getattr(readline, '__doc__', '') + if readline_doc is not None and 'libedit' in readline_doc: + readline.parse_and_bind("bind "+self.completekey+" rl_complete") + else: + readline.parse_and_bind(self.completekey+": complete") except ImportError: pass try: diff --git a/Lib/pdb.py b/Lib/pdb.py index 3db3e6a5be1a7b..e92e6604803c9b 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -209,7 +209,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): _previous_sigint_handler = None - def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, + def __init__(self, completekey=r'"\t"', stdin=None, stdout=None, skip=None, nosigint=False, readrc=True): bdb.Bdb.__init__(self, skip=skip) cmd.Cmd.__init__(self, completekey, stdin, stdout) diff --git a/Lib/site.py b/Lib/site.py index 672fa7b000ad02..342f9e71b8a519 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -446,9 +446,9 @@ def register_readline(): # completion key, so we set one first and then read the file. readline_doc = getattr(readline, '__doc__', '') if readline_doc is not None and 'libedit' in readline_doc: - readline.parse_and_bind('bind ^I rl_complete') + readline.parse_and_bind(r'bind "\t" rl_complete') else: - readline.parse_and_bind('tab: complete') + readline.parse_and_bind(r'"\t": complete') try: readline.read_init_file() diff --git a/Misc/ACKS b/Misc/ACKS index 8b8c5ad8434bd7..0aea3e42754086 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -784,6 +784,7 @@ Thomas Holmes Craig Holmquist Philip Homburg Naofumi Honda +Constantin Hong Weipeng Hong Jeffrey Honig Rob Hooft diff --git a/Misc/NEWS.d/next/Library/2023-08-07-19-57-34.gh-issue-102130._UyI5i.rst b/Misc/NEWS.d/next/Library/2023-08-07-19-57-34.gh-issue-102130._UyI5i.rst new file mode 100644 index 00000000000000..a4215c10596930 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-08-07-19-57-34.gh-issue-102130._UyI5i.rst @@ -0,0 +1 @@ +Support a tab completion for Libedit in :mod:`cmd `, :mod:`site`, and :mod:`pdb`.