diff options
| author | Kevin Van Brunt <kmvanbrunt@gmail.com> | 2022-02-17 10:12:01 -0500 |
|---|---|---|
| committer | Kevin Van Brunt <kmvanbrunt@gmail.com> | 2022-02-17 11:13:34 -0500 |
| commit | 07f059c17b4cb6577fbc7a2ce42d7c5bf98a83c8 (patch) | |
| tree | 0dfa541765f0844da16471936d753a138687ddb4 /cmd2 | |
| parent | f217861feae45a0a1abb56436e68c5dd859d64c0 (diff) | |
| download | cmd2-git-07f059c17b4cb6577fbc7a2ce42d7c5bf98a83c8.tar.gz | |
Improved some readline-related comments
Diffstat (limited to 'cmd2')
| -rw-r--r-- | cmd2/cmd2.py | 7 | ||||
| -rw-r--r-- | cmd2/rl_utils.py | 26 |
2 files changed, 25 insertions, 8 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index 88e2492c..7fc2d4a3 100644 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -3066,9 +3066,10 @@ class Cmd(cmd.Cmd): # Set up readline for our tab completion needs if rl_type == RlType.GNU: - # Set GNU readline's rl_basic_quote_characters to NULL so it won't automatically add a closing quote - # We don't need to worry about setting rl_completion_suppress_quote since we never declared - # rl_completer_quote_characters. + # GNU readline automatically adds a closing quote if the text being completed has an opening quote. + # We don't want this behavior since cmd2 only adds a closing quote when self.allow_closing_quote is True. + # To fix this behavior, set readline's rl_basic_quote_characters to NULL. We don't need to worry about setting + # rl_completion_suppress_quote since we never declared rl_completer_quote_characters. readline_settings.basic_quotes = cast(bytes, ctypes.cast(rl_basic_quote_characters, ctypes.c_void_p).value) rl_basic_quote_characters.value = None diff --git a/cmd2/rl_utils.py b/cmd2/rl_utils.py index d2a7c54b..cb73e836 100644 --- a/cmd2/rl_utils.py +++ b/cmd2/rl_utils.py @@ -10,13 +10,29 @@ from typing import ( Union, ) -# Prefer statically linked gnureadline if available (for macOS compatibility due to issues with libedit) +######################################################################################################################### +# NOTE ON LIBEDIT: +# +# On Linux/Mac, the underlying readline API may be implemented by libedit instead of GNU readline. +# We don't support libedit because it doesn't implement all the readline features cmd2 needs. +# +# For example: +# cmd2 sets a custom display function using Python's readline.set_completion_display_matches_hook() to +# support many of its advanced tab completion features (e.g. tab completion tables, displaying path basenames, +# colored results, etc.). This function "sets or clears the rl_completion_display_matches_hook callback in the +# underlying library". libedit has never implemented rl_completion_display_matches_hook. It merely sets it to NULL +# and never references it. +# +# The workaround for Python environments using libedit is to install the gnureadline Python library. +######################################################################################################################### + +# Prefer statically linked gnureadline if available due to issues with libedit try: # noinspection PyPackageRequirements import gnureadline as readline # type: ignore[import] except ImportError: - # Try to import readline, but allow failure for convenience in Windows unit testing - # Note: If this actually fails, you should install readline on Linux or Mac or pyreadline on Windows + # Try to import readline, but allow failure for convenience in Windows unit testing. + # Note: If this actually fails, you should install gnureadline on Linux/Mac or pyreadline on Windows. try: # noinspection PyUnresolvedReferences import readline # type: ignore[no-redef] @@ -125,7 +141,7 @@ if 'pyreadline' in sys.modules or 'pyreadline3' in sys.modules: readline.remove_history_item = pyreadline_remove_history_item elif 'gnureadline' in sys.modules or 'readline' in sys.modules: - # We don't support libedit + # We don't support libedit. See top of this file for why. if 'libedit' not in readline.__doc__: try: # Load the readline lib so we can access members of it @@ -146,7 +162,7 @@ if rl_type == RlType.NONE: # pragma: no cover if not _rl_warn_reason: _rl_warn_reason = ( "no supported version of readline was found. To resolve this, install\n" - "pyreadline on Windows or gnureadline on Mac." + "pyreadline on Windows or gnureadline on Linux/Mac." ) rl_warning = "Readline features including tab completion have been disabled because\n" + _rl_warn_reason + '\n\n' else: |
