From 58ef5c2164a08d7d64aee348bcf71c989f9f69c3 Mon Sep 17 00:00:00 2001 From: hut Date: Fri, 7 Oct 2011 18:08:41 +0200 Subject: core.actions: Fixed crash when %f/%F macros are undefined --- ranger/core/actions.py | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/ranger/core/actions.py b/ranger/core/actions.py index 87961cc5..79292a06 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -33,6 +33,8 @@ from ranger.core.shared import FileManagerAware, EnvironmentAware, \ from ranger.fsobject import File from ranger.core.loader import CommandLoader +MACRO_FAIL = "<\x01\x01MACRO_HAS_NO_VALUE\x01\01>" + class _MacroTemplate(string.Template): """A template for substituting macros in commands""" delimiter = '%' @@ -108,12 +110,27 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): for i, char in enumerate(wildcards)) if 'any0' in macros: macros['any'] = macros['any0'] - string = self.substitute_macros(string, additional=macros) - cmd_class(string, quantifier=quantifier).execute() + try: + string = self.substitute_macros(string, additional=macros) + except ValueError as e: + if ranger.arg.debug: + raise + else: + return self.notify(e) + try: + cmd_class(string, quantifier=quantifier).execute() + except Exception as e: + if ranger.arg.debug: + raise + else: + self.notify(e) def substitute_macros(self, string, additional=dict()): - return _MacroTemplate(string).safe_substitute(self._get_macros(), + result = _MacroTemplate(string).safe_substitute(self._get_macros(), **additional) + if MACRO_FAIL in result: + raise ValueError("Could not apply macros to `%s'" % string) + return result def _get_macros(self): macros = {} @@ -123,7 +140,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): if self.fm.env.cf: macros['f'] = shell_quote(self.fm.env.cf.basename) else: - macros['f'] = '' + macros['f'] = MACRO_FAIL macros['s'] = ' '.join(shell_quote(fl.basename) \ for fl in self.fm.env.get_selection()) @@ -140,6 +157,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): else: macros['d'] = '.' + # define d/f/s macros for each tab for i in range(1,10): try: @@ -149,9 +167,12 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): tab_dir = self.fm.env.get_directory(tab_dir_path) i = str(i) macros[i + 'd'] = shell_quote(tab_dir_path) - macros[i + 'f'] = shell_quote(tab_dir.pointed_obj.path) macros[i + 's'] = ' '.join(shell_quote(fl.path) for fl in tab_dir.get_selection()) + if tab_dir.pointed_obj: + macros[i + 'f'] = shell_quote(tab_dir.pointed_obj.path) + else: + macros[i + 'f'] = MACRO_FAIL # define D/F/S for the next tab found_current_tab = False @@ -170,7 +191,10 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): next_tab = self.fm.env.get_directory(next_tab_path) macros['D'] = shell_quote(next_tab) - macros['F'] = shell_quote(next_tab.pointed_obj.path) + if next_tab.pointed_obj: + macros['F'] = shell_quote(next_tab.pointed_obj.path) + else: + macros['F'] = MACRO_FAIL macros['S'] = ' '.join(shell_quote(fl.path) for fl in next_tab.get_selection()) -- cgit 1.4.1-2-gfad0