summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorConstantin Hong <hongconstantin@gmail.com>2023-12-05 07:24:56 (GMT)
committerGitHub <noreply@github.com>2023-12-05 07:24:56 (GMT)
commitaa5bee30abb28d73a838399f4c3a8bcdc5108fe3 (patch)
tree98d459e7dcd3e011709aa7f82d2e5919cce697f7
parentdc824c5dc120ffed84bafd23f95e95a99678ed6a (diff)
downloadcpython-aa5bee30abb28d73a838399f4c3a8bcdc5108fe3.zip
cpython-aa5bee30abb28d73a838399f4c3a8bcdc5108fe3.tar.gz
cpython-aa5bee30abb28d73a838399f4c3a8bcdc5108fe3.tar.bz2
gh-102130: Support tab completion in cmd for Libedit. (GH-107748)
--- Co-authored-by: Tian Gao <gaogaotiantian@hotmail.com>
-rw-r--r--Doc/library/cmd.rst10
-rw-r--r--Lib/cmd.py10
-rw-r--r--Lib/test/test_cmd.py30
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS.d/next/Library/2023-08-07-21-11-24.gh-issue-102130._UyI5i.rst1
5 files changed, 51 insertions, 1 deletions
diff --git a/Doc/library/cmd.rst b/Doc/library/cmd.rst
index fd5df96..1318ffe 100644
--- a/Doc/library/cmd.rst
+++ b/Doc/library/cmd.rst
@@ -26,6 +26,13 @@ interface.
key; it defaults to :kbd:`Tab`. If *completekey* is not :const:`None` and
:mod:`readline` is available, command completion is done automatically.
+ The default, ``'tab'``, is treated specially, so that it refers to the
+ :kbd:`Tab` key on every :data:`readline.backend`.
+ Specifically, if :data:`readline.backend` is ``editline``,
+ ``Cmd`` will use ``'^I'`` instead of ``'tab'``.
+ Note that other values are not treated this way, and might only work
+ with a specific backend.
+
The optional arguments *stdin* and *stdout* specify the input and output file
objects that the Cmd instance or subclass instance will use for input and
output. If not specified, they will default to :data:`sys.stdin` and
@@ -35,6 +42,9 @@ interface.
:attr:`use_rawinput` attribute to ``False``, otherwise *stdin* will be
ignored.
+ .. versionchanged:: 3.13
+ ``completekey='tab'`` is replaced by ``'^I'`` for ``editline``.
+
.. _cmd-objects:
diff --git a/Lib/cmd.py b/Lib/cmd.py
index e933b8d..2e358d6 100644
--- a/Lib/cmd.py
+++ b/Lib/cmd.py
@@ -108,7 +108,15 @@ class Cmd:
import readline
self.old_completer = readline.get_completer()
readline.set_completer(self.complete)
- readline.parse_and_bind(self.completekey+": complete")
+ if readline.backend == "editline":
+ if self.completekey == 'tab':
+ # libedit uses "^I" instead of "tab"
+ command_string = "bind ^I rl_complete"
+ else:
+ command_string = f"bind {self.completekey} rl_complete"
+ else:
+ command_string = f"{self.completekey}: complete"
+ readline.parse_and_bind(command_string)
except ImportError:
pass
try:
diff --git a/Lib/test/test_cmd.py b/Lib/test/test_cmd.py
index 951336f..46ec82b 100644
--- a/Lib/test/test_cmd.py
+++ b/Lib/test/test_cmd.py
@@ -9,7 +9,10 @@ import sys
import doctest
import unittest
import io
+import textwrap
from test import support
+from test.support.import_helper import import_module
+from test.support.pty_helper import run_pty
class samplecmdclass(cmd.Cmd):
"""
@@ -259,6 +262,33 @@ class CmdPrintExceptionClass(cmd.Cmd):
def default(self, line):
print(sys.exc_info()[:2])
+
+@support.requires_subprocess()
+class CmdTestReadline(unittest.TestCase):
+ def setUpClass():
+ # Ensure that the readline module is loaded
+ # If this fails, the test is skipped because SkipTest will be raised
+ readline = import_module('readline')
+
+ def test_basic_completion(self):
+ script = textwrap.dedent("""
+ import cmd
+ class simplecmd(cmd.Cmd):
+ def do_tab_completion_test(self, args):
+ print('tab completion success')
+ return True
+
+ simplecmd().cmdloop()
+ """)
+
+ # 't' and complete 'ab_completion_test' to 'tab_completion_test'
+ input = b"t\t\n"
+
+ output = run_pty(script, input)
+
+ self.assertIn(b'ab_completion_test', output)
+ self.assertIn(b'tab completion success', output)
+
def load_tests(loader, tests, pattern):
tests.addTest(doctest.DocTestSuite())
return tests
diff --git a/Misc/ACKS b/Misc/ACKS
index 1c67d96..12335c9 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -788,6 +788,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-21-11-24.gh-issue-102130._UyI5i.rst b/Misc/NEWS.d/next/Library/2023-08-07-21-11-24.gh-issue-102130._UyI5i.rst
new file mode 100644
index 0000000..f582ad5
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-08-07-21-11-24.gh-issue-102130._UyI5i.rst
@@ -0,0 +1 @@
+Support tab completion in :mod:`cmd` for ``editline``.