diff options
| author | Kevin Van Brunt <kmvanbrunt@gmail.com> | 2018-04-28 01:11:43 -0400 |
|---|---|---|
| committer | Kevin Van Brunt <kmvanbrunt@gmail.com> | 2018-04-28 01:11:43 -0400 |
| commit | e906a0530f3e1cd898bdd6fa00904dd51fe8e144 (patch) | |
| tree | 25cb5594e6f9405c120fc7ef16f73d637cfeac7d /cmd2.py | |
| parent | 09e0fc0b37d0a16c845c18f9118dbb38250c2b5a (diff) | |
| download | cmd2-git-e906a0530f3e1cd898bdd6fa00904dd51fe8e144.tar.gz | |
Fixed issue where completion display function was overwritten when a submenu quits.
Fixed issue where submenus did not pass up all completion parameters to complete().
Diffstat (limited to 'cmd2.py')
| -rwxr-xr-x | cmd2.py | 67 |
1 files changed, 35 insertions, 32 deletions
@@ -164,10 +164,6 @@ elif 'gnureadline' in sys.modules or 'readline' in sys.modules: import ctypes readline_lib = ctypes.CDLL(readline.__file__) - # Save address that rl_basic_quote_characters is pointing to since we need to override and restore it - rl_basic_quote_characters = ctypes.c_char_p.in_dll(readline_lib, "rl_basic_quote_characters") - orig_rl_basic_quote_characters_addr = ctypes.cast(rl_basic_quote_characters, ctypes.c_void_p).value - # BrokenPipeError and FileNotFoundError exist only in Python 3. Use IOError for Python 2. if six.PY3: @@ -889,11 +885,22 @@ class AddSubmenu(object): try: # copy over any shared attributes self._copy_in_shared_attrs(_self) + + # Reset the submenu's tab completion parameters + submenu.allow_appended_space = True + submenu.allow_closing_quote = True + submenu.display_matches = [] + return _complete_from_cmd(submenu, text, line, begidx, endidx) finally: # copy back original attributes self._copy_out_shared_attrs(_self, original_attributes) + # Pass the submenu's tab completion parameters back up to the menu that called complete() + _self.allow_appended_space = submenu.allow_appended_space + _self.allow_closing_quote = submenu.allow_closing_quote + _self.display_matches = copy.copy(submenu.display_matches) + original_do_help = cmd_obj.do_help original_complete_help = cmd_obj.complete_help @@ -1324,6 +1331,11 @@ class Cmd(cmd.Cmd): self.allow_closing_quote = True self.display_matches = [] + if rl_type == RlType.GNU: + readline.set_completion_display_matches_hook(self._display_matches_gnu_readline) + elif rl_type == RlType.PYREADLINE: + readline.rl.mode._display_completions = self._display_matches_pyreadline + def tokens_for_completion(self, line, begidx, endidx): """ Used by tab completion functions to get all tokens through the one being completed @@ -2699,38 +2711,33 @@ class Cmd(cmd.Cmd): """ # An almost perfect copy from Cmd; however, the pseudo_raw_input portion # has been split out so that it can be called separately - if self.use_rawinput and self.completekey: + if self.use_rawinput and self.completekey and rl_type != RlType.NONE: # Set up readline for our tab completion needs if rl_type == RlType.GNU: - readline.set_completion_display_matches_hook(self._display_matches_gnu_readline) - # 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.value = None + basic_quote_characters = ctypes.c_char_p.in_dll(readline_lib, "rl_basic_quote_characters") + old_basic_quote_characters = ctypes.cast(basic_quote_characters, ctypes.c_void_p).value + basic_quote_characters.value = None - elif rl_type == RlType.PYREADLINE: - readline.rl.mode._display_completions = self._display_matches_pyreadline + old_completer = readline.get_completer() + old_delims = readline.get_completer_delims() + readline.set_completer(self.complete) - try: - self.old_completer = readline.get_completer() - self.old_delims = readline.get_completer_delims() - readline.set_completer(self.complete) + # Break words on whitespace and quotes when tab completing + completer_delims = " \t\n" + ''.join(QUOTES) - # Break words on whitespace and quotes when tab completing - completer_delims = " \t\n" + ''.join(QUOTES) + if self.allow_redirection: + # If redirection is allowed, then break words on those characters too + completer_delims += ''.join(REDIRECTION_CHARS) - if self.allow_redirection: - # If redirection is allowed, then break words on those characters too - completer_delims += ''.join(REDIRECTION_CHARS) + readline.set_completer_delims(completer_delims) - readline.set_completer_delims(completer_delims) + # Enable tab completion + readline.parse_and_bind(self.completekey + ": complete") - # Enable tab completion - readline.parse_and_bind(self.completekey + ": complete") - except NameError: - pass stop = None try: while not stop: @@ -2754,19 +2761,15 @@ class Cmd(cmd.Cmd): # Run the command along with all associated pre and post hooks stop = self.onecmd_plus_hooks(line) finally: - if self.use_rawinput and self.completekey: + if self.use_rawinput and self.completekey and rl_type != RlType.NONE: # Restore what we changed in readline - try: - readline.set_completer(self.old_completer) - readline.set_completer_delims(self.old_delims) - except NameError: - pass + readline.set_completer(old_completer) + readline.set_completer_delims(old_delims) if rl_type == RlType.GNU: readline.set_completion_display_matches_hook(None) - rl_basic_quote_characters.value = orig_rl_basic_quote_characters_addr - + basic_quote_characters.value = old_basic_quote_characters elif rl_type == RlType.PYREADLINE: readline.rl.mode._display_completions = orig_pyreadline_display |
