summaryrefslogtreecommitdiffstats
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
parent2dd8d48b9fa40438bedc6e59b7bd77a81fae2df2 (diff)
api.commands: Tab completion: Escape macros if `resolve_macros` is enabled
Fixes #460
-rw-r--r--ranger/__init__.py1
-rw-r--r--ranger/api/commands.py26
-rwxr-xr-xranger/config/commands.py6
-rw-r--r--ranger/gui/widgets/console.py8
4 files changed, 31 insertions, 10 deletions
diff --git a/ranger/__init__.py b/ranger/__init__.py
index e497ae06..0cb94a69 100644
--- a/ranger/__init__.py
+++ b/ranger/__init__.py
@@ -25,6 +25,7 @@ TICKS_BEFORE_COLLECTING_GARBAGE = 100
TIME_BEFORE_FILE_BECOMES_GARBAGE = 1200
MAX_RESTORABLE_TABS = 3
MACRO_DELIMITER = '%'
+MACRO_DELIMITER_ESC = '%%'
DEFAULT_PAGER = 'less'
USAGE = '%prog [options] [path]'
VERSION = 'ranger-master %s\n\nPython %s' % (__version__, sys.version)
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:
diff --git a/ranger/config/commands.py b/ranger/config/commands.py
index 6fa5b904..aa955605 100755
--- a/ranger/config/commands.py
+++ b/ranger/config/commands.py
@@ -852,9 +852,11 @@ class rename_append(Command):
self._flag_remove = 'r' in flags
def execute(self):
+ from ranger import MACRO_DELIMITER, MACRO_DELIMITER_ESC
+
tfile = self.fm.thisfile
- relpath = tfile.relative_path.replace('%', '%%')
- basename = tfile.basename.replace('%', '%%')
+ relpath = tfile.relative_path.replace(MACRO_DELIMITER, MACRO_DELIMITER_ESC)
+ basename = tfile.basename.replace(MACRO_DELIMITER, MACRO_DELIMITER_ESC)
if basename.find('.') <= 0:
self.fm.open_console('rename ' + relpath)
diff --git a/ranger/gui/widgets/console.py b/ranger/gui/widgets/console.py
index 5d7f6b0e..b3fa7151 100644
--- a/ranger/gui/widgets/console.py
+++ b/ranger/gui/widgets/console.py
@@ -465,14 +465,12 @@ class Console(Widget): # pylint: disable=too-many-instance-attributes,too-many-
if self.tab_deque is None:
tab_result = self._get_tab(tabnum)
- if isinstance(tab_result, str):
+ if tab_result is None:
+ pass
+ elif isinstance(tab_result, str):
self.line = tab_result
self.pos = len(tab_result)
self.on_line_change()
-
- elif tab_result is None:
- pass
-
elif hasattr(tab_result, '__iter__'):
self.tab_deque = deque(tab_result)
self.tab_deque.appendleft(self.line)