about summary refs log tree commit diff stats
path: root/ranger/api/commands.py
diff options
context:
space:
mode:
authornfnty <git@nfnty.se>2017-02-05 22:09:52 +0100
committernfnty <git@nfnty.se>2017-02-06 01:56:01 +0100
commit41478b10c5a0bace85c74bc7388b3818c8f86ab4 (patch)
tree120c3ef6ef13a4be430b90ec209e9a0529e7fe47 /ranger/api/commands.py
parent2dd8d48b9fa40438bedc6e59b7bd77a81fae2df2 (diff)
downloadranger-41478b10c5a0bace85c74bc7388b3818c8f86ab4.tar.gz
api.commands: Tab completion: Escape macros if `resolve_macros` is enabled
Fixes #460
Diffstat (limited to 'ranger/api/commands.py')
-rw-r--r--ranger/api/commands.py26
1 files changed, 23 insertions, 3 deletions
diff --git a/ranger/api/commands.py b/ranger/api/commands.py
index 7f5ce810..e486d234 100644
--- a/ranger/api/commands.py
+++ b/ranger/api/commands.py
@@ -13,6 +13,7 @@ from ranger.api import LinemodeBase, hook_init, hook_ready, register_linemode  #
 # pylint: enable=unused-import
 
 import ranger
+from ranger import MACRO_DELIMITER, MACRO_DELIMITER_ESC
 from ranger.core.shared import FileManagerAware
 from ranger.ext.lazy_property import lazy_property
 
@@ -22,6 +23,25 @@ _SETTINGS_RE = re.compile(r'^\s*([^\s]+?)=(.*)$')
 _ALIAS_LINE_RE = re.compile(r'(\s+)')
 
 
+def _command_init(cls):
+    # Escape macros for tab completion
+    if cls.resolve_macros:
+        tab_old = cls.tab
+
+        def tab(self, tabnum):
+            results = tab_old(self, tabnum)
+            if results is None:
+                return None
+            elif isinstance(results, str):
+                return results.replace(MACRO_DELIMITER, MACRO_DELIMITER_ESC)
+            elif hasattr(results, '__iter__'):
+                return (result.replace(MACRO_DELIMITER, MACRO_DELIMITER_ESC) for result in results)
+            return None
+        setattr(cls, 'tab', tab)
+
+    return cls
+
+
 class CommandContainer(FileManagerAware):
 
     def __init__(self):
@@ -37,13 +57,13 @@ class CommandContainer(FileManagerAware):
         except KeyError:
             self.fm.notify('alias failed: No such command: {0}'.format(cmd_name), bad=True)
             return None
-        self.commands[name] = command_alias_factory(name, cmd, full_command)
+        self.commands[name] = _command_init(command_alias_factory(name, cmd, full_command))
 
     def load_commands_from_module(self, module):
         for var in vars(module).values():
             try:
                 if issubclass(var, Command) and var != Command:
-                    self.commands[var.get_name()] = var
+                    self.commands[var.get_name()] = _command_init(var)
             except TypeError:
                 pass
 
@@ -53,7 +73,7 @@ class CommandContainer(FileManagerAware):
                 continue
             attribute = getattr(obj, attribute_name)
             if hasattr(attribute, '__call__'):
-                self.commands[attribute_name] = command_function_factory(attribute)
+                self.commands[attribute_name] = _command_init(command_function_factory(attribute))
 
     def get_command(self, name, abbrev=True):
         if abbrev: