diff options
Diffstat (limited to 'ranger/core/actions.py')
-rw-r--r-- | ranger/core/actions.py | 86 |
1 files changed, 79 insertions, 7 deletions
diff --git a/ranger/core/actions.py b/ranger/core/actions.py index a298b304..c93fa0a5 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -16,19 +16,25 @@ import os import re import shutil +import string from os.path import join, isdir from os import symlink, getcwd from inspect import cleandoc import ranger from ranger.ext.direction import Direction +from ranger.ext.shell_escape import shell_quote from ranger import fsobject from ranger.shared import FileManagerAware, EnvironmentAware, SettingsAware -from ranger.gui.widgets import console_mode as cmode from ranger.fsobject import File from ranger.ext import shutil_generatorized as shutil_g from ranger.core.loader import LoadableObject +class _MacroTemplate(string.Template): + """A template for substituting macros in commands""" + delimiter = '%' + idpattern = '\d?[a-z]' + class Actions(FileManagerAware, EnvironmentAware, SettingsAware): search_method = 'ctime' search_forward = False @@ -69,17 +75,80 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): """Redraw the window""" self.ui.redraw_window() - def open_console(self, mode=cmode.COMMAND, string='', prompt=None): + def open_console(self, string='', prompt=None, position=None): """Open the console if the current UI supports that""" if hasattr(self.ui, 'open_console'): - self.ui.open_console(mode, string, prompt=prompt) + self.ui.open_console(string, prompt=prompt, position=position) - def execute_console(self, string='', mode=cmode.COMMAND): + def execute_console(self, string=''): """Execute a command for the console""" - self.open_console(mode=mode, string=string) + self.open_console(string=string) self.ui.console.line = string self.ui.console.execute() + def substitute_metachars(self, string): + return _MacroTemplate(string).safe_substitute(self._get_macros()) + + def _get_macros(self): + macros = {} + + if self.fm.env.cf: + macros['f'] = shell_quote(self.fm.env.cf.basename) + else: + macros['f'] = '' + + macros['s'] = ' '.join(shell_quote(fl.basename) \ + for fl in self.fm.env.get_selection()) + + macros['c'] = ' '.join(shell_quote(fl.path) + for fl in self.fm.env.copy) + + macros['t'] = ' '.join(shell_quote(fl.basename) + for fl in self.fm.env.cwd.files + if fl.realpath in self.fm.tags) + + if self.fm.env.cwd: + macros['d'] = shell_quote(self.fm.env.cwd.path) + else: + macros['d'] = '.' + + # define d/f/s macros for each tab + for i in range(1,10): + try: + tab_dir_path = self.fm.tabs[i] + except: + continue + 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()) + + # define D/F/S for the next tab + found_current_tab = False + next_tab_path = None + first_tab = None + for tab in self.fm.tabs: + if not first_tab: + first_tab = tab + if found_current_tab: + next_tab_path = self.fm.tabs[tab] + break + if self.fm.current_tab == tab: + found_current_tab = True + if found_current_tab and not next_tab_path: + next_tab_path = self.fm.tabs[first_tab] + 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) + macros['S'] = ' '.join(shell_quote(fl.path) + for fl in next_tab.get_selection()) + + return macros + + def execute_file(self, files, **kw): """Execute a file. app is the name of a method in Applications, without the "app_" @@ -134,7 +203,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): selection = self.env.get_selection() if not self.env.enter_dir(cf) and selection: if self.execute_file(selection, mode=mode) is False: - self.open_console(cmode.OPEN_QUICK) + self.open_console('open_with ') elif direction.vertical(): newpos = direction.move( direction=direction.down(), @@ -297,7 +366,10 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): def search_file(self, text, regexp=True): if isinstance(text, str) and regexp: - text = re.compile(text, re.L | re.U | re.I) + try: + text = re.compile(text, re.L | re.U | re.I) + except: + return False self.env.last_search = text self.search(order='search') |