Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-102130: Support tab completion in cmd for Libedit. #107748

Merged
merged 29 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
1374212
gh-102130: Support a tab completion for Libedit in cmd, site, and pdb.
Constantin1489 Aug 7, 2023
d11ec11
📜🤖 Added by blurb_it.
blurb-it[bot] Aug 7, 2023
5047de4
Merge branch 'main' into fix_libedit
Constantin1489 Aug 7, 2023
a7443e8
Revert "gh-102130: Support a tab completion for Libedit in cmd, site,…
Constantin1489 Nov 6, 2023
339b274
gh-102130: Support a tab completion in cmd for Libedit
Constantin1489 Nov 6, 2023
0c270b1
Merge branch 'main' into fix_libedit
Constantin1489 Nov 6, 2023
8cc60fa
Update Lib/cmd.py
Constantin1489 Nov 6, 2023
21ee6eb
Update 2023-08-07-21-11-24.gh-issue-102130._UyI5i.rst
Constantin1489 Nov 6, 2023
1e93c3b
Merge branch 'main' into fix_libedit
Constantin1489 Nov 14, 2023
1e8eae7
test_cmd/test: Add basic cmd module tab completion test.
Constantin1489 Nov 15, 2023
03a7462
test/test_pdb/test: Enable pdb test for both readline and libedit.
Constantin1489 Nov 15, 2023
4667ea4
Revert "test/test_pdb/test: Enable pdb test for both readline and lib…
Constantin1489 Nov 15, 2023
e71fcf0
test_cmd/test: Refine a cmd tab completion test to make it intuitive.
Constantin1489 Nov 15, 2023
e4b4260
Merge branch 'main' into fix_libedit
Constantin1489 Nov 15, 2023
e280b14
Update Misc/NEWS.d/next/Library/2023-08-07-21-11-24.gh-issue-102130._…
Constantin1489 Nov 15, 2023
bc20b5f
cmd/docs: Add the fact about the special treatment for the string 'tab'.
Constantin1489 Nov 27, 2023
ccbc5c5
Update Lib/cmd.py
Constantin1489 Nov 27, 2023
72a5a66
Merge branch 'main' into fix_libedit
Constantin1489 Nov 27, 2023
19ef391
Update Doc/library/cmd.rst
Constantin1489 Nov 30, 2023
a3b6135
Update Lib/cmd.py
Constantin1489 Nov 30, 2023
239bf25
Merge branch 'main' into fix_libedit
Constantin1489 Dec 1, 2023
22f1f20
cmd/fix: Apply new API
Constantin1489 Dec 1, 2023
ede178a
cmd/docs: Fix library name.
Constantin1489 Dec 1, 2023
c00c188
cmd.rst/docs: Add a blank line.
Constantin1489 Dec 1, 2023
2dff7ca
cmd/docs: Add a versionchanged note
Constantin1489 Dec 1, 2023
37e6e6d
2023-08-07-21-11-24.gh-issue-102130._UyI5i/docs: Fix library name in …
Constantin1489 Dec 1, 2023
4bb11a9
Merge branch 'main' into fix_libedit
Constantin1489 Dec 4, 2023
652100f
Update Lib/test/test_cmd.py
Constantin1489 Dec 4, 2023
ebb8167
Update cmd.rst
Constantin1489 Dec 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Doc/library/cmd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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``,
Constantin1489 marked this conversation as resolved.
Show resolved Hide resolved
``Cmd`` will use ``'^I'`` instead of ``'tab'``.
Note that other values are not treated this way, and might only work
with a specific backend.

encukou marked this conversation as resolved.
Show resolved Hide resolved
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
Expand All @@ -35,6 +42,9 @@ interface.
:attr:`use_rawinput` attribute to ``False``, otherwise *stdin* will be
ignored.

.. versionchanged:: 3.11
Constantin1489 marked this conversation as resolved.
Show resolved Hide resolved
``completekey='tab'`` is replaced by ``'^I'`` for ``editline``.
Constantin1489 marked this conversation as resolved.
Show resolved Hide resolved


.. _cmd-objects:

Expand Down
10 changes: 9 additions & 1 deletion Lib/cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,15 @@ 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")
if readline.backend == "editline":
encukou marked this conversation as resolved.
Show resolved Hide resolved
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:
Expand Down
30 changes: 30 additions & 0 deletions Lib/test/test_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
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):
"""
Expand Down Expand Up @@ -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'tab_completion_test', output)
Constantin1489 marked this conversation as resolved.
Show resolved Hide resolved
self.assertIn(b'tab completion success', output)

def load_tests(loader, tests, pattern):
tests.addTest(doctest.DocTestSuite())
return tests
Expand Down
1 change: 1 addition & 0 deletions Misc/ACKS
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,7 @@ Thomas Holmes
Craig Holmquist
Philip Homburg
Naofumi Honda
Constantin Hong
Weipeng Hong
Jeffrey Honig
Rob Hooft
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Support tab completion in :mod:`cmd` for ``editline``.
Loading