diff options
author | Kevin Van Brunt <kmvanbrunt@gmail.com> | 2018-05-23 11:16:27 -0400 |
---|---|---|
committer | Kevin Van Brunt <kmvanbrunt@gmail.com> | 2018-05-23 11:16:27 -0400 |
commit | 24aa66f1101d8ede2bbd8ae3a79d20cb398b1eec (patch) | |
tree | f8e0fb2d41f31dc3242bbdb56980b5158296f04e /cmd2/cmd2.py | |
parent | 4ce81a71de2aeb184f64d360d1774b8698d16ba3 (diff) | |
download | cmd2-git-24aa66f1101d8ede2bbd8ae3a79d20cb398b1eec.tar.gz |
Added tab completion of Python identifiers when running the Python console
Diffstat (limited to 'cmd2/cmd2.py')
-rw-r--r-- | cmd2/cmd2.py | 57 |
1 files changed, 51 insertions, 6 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index 620649cf..4359ef12 100644 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -64,6 +64,9 @@ if rl_type == RlType.NONE: else: from .rl_utils import rl_force_redisplay, readline + # Used by rlcompleter in Python console loaded by py command + orig_rl_delims = readline.get_completer_delims() + if rl_type == RlType.PYREADLINE: # Save the original pyreadline display completion function since we need to override it and restore it @@ -79,6 +82,9 @@ else: import ctypes from .rl_utils import readline_lib + rl_basic_quote_characters = ctypes.c_char_p.in_dll(readline_lib, "rl_basic_quote_characters") + orig_rl_basic_quotes = ctypes.cast(rl_basic_quote_characters, ctypes.c_void_p).value + from .argparse_completer import AutoCompleter, ACArgumentParser # Newer versions of pyperclip are released as a single file, but older versions had a more complicated structure @@ -2025,7 +2031,6 @@ class Cmd(cmd.Cmd): # 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. - rl_basic_quote_characters = ctypes.c_char_p.in_dll(readline_lib, "rl_basic_quote_characters") old_basic_quotes = ctypes.cast(rl_basic_quote_characters, ctypes.c_void_p).value rl_basic_quote_characters.value = None @@ -2586,8 +2591,36 @@ Usage: Usage: unalias [-a] name [name ...] readline.add_history(item) if self.use_rawinput and self.completekey: - # Disable tab completion while in interactive Python shell - readline.parse_and_bind(self.completekey + ": ") + # Set up tab completion for the Python console + # rlcompleter relies on the default settings of the Python readline module + if rl_type == RlType.GNU: + old_basic_quotes = ctypes.cast(rl_basic_quote_characters, ctypes.c_void_p).value + rl_basic_quote_characters.value = orig_rl_basic_quotes + + if 'gnureadline' in sys.modules: + # rlcompleter imports readline by name, so it won't use gnureadline + # Force rlcompleter to use gnureadline instead so it has our settings and history + saved_readline = None + if 'readline' in sys.modules: + saved_readline = sys.modules['readline'] + + sys.modules['readline'] = sys.modules['gnureadline'] + + old_delims = readline.get_completer_delims() + readline.set_completer_delims(orig_rl_delims) + + # rlcompleter will not need cmd2's custom display function + # This will be restored by cmd2 the next time complete() is called + if rl_type == RlType.GNU: + readline.set_completion_display_matches_hook(None) + elif rl_type == RlType.PYREADLINE: + readline.rl.mode._display_completions = self._display_matches_pyreadline + + # Load rlcompleter so it sets its completer function + old_completer = readline.get_completer() + import rlcompleter + import importlib + importlib.reload(rlcompleter) cprt = 'Type "help", "copyright", "credits" or "license" for more information.' keepstate = Statekeeper(sys, ('stdin', 'stdout')) @@ -2609,14 +2642,26 @@ Usage: Usage: unalias [-a] name [name ...] for i in range(1, readline.get_current_history_length() + 1): self.py_history.append(readline.get_history_item(i)) - # Restore cmd2 history + # Restore cmd2's history readline.clear_history() for item in saved_cmd2_history: readline.add_history(item) if self.use_rawinput and self.completekey: - # Enable tab completion since we are returning to cmd2 - readline.parse_and_bind(self.completekey + ": complete") + # Restore cmd2's tab completion settings + readline.set_completer(old_completer) + readline.set_completer_delims(old_delims) + + if rl_type == RlType.GNU: + rl_basic_quote_characters.value = old_basic_quotes + + if 'gnureadline' in sys.modules: + # Restore what the readline module pointed to + if saved_readline is None: + del(sys.modules['readline']) + else: + sys.modules['readline'] = saved_readline + except Exception: pass finally: |