diff options
author | hut <hut@lavabit.com> | 2011-09-30 01:43:27 +0200 |
---|---|---|
committer | hut <hut@lavabit.com> | 2011-09-30 01:46:09 +0200 |
commit | b1d25114617f41538f1e9e1740229f5e326c9f88 (patch) | |
tree | 5fe8b438759ea2a9a6495e57d7266a7bd36f340a | |
parent | 5e41c8479cfba986f6dad0e68aed3c1d7b51d3ae (diff) | |
download | ranger-b1d25114617f41538f1e9e1740229f5e326c9f88.tar.gz |
define keybindings in rc.conf (list of commands, loaded on startup)
-rw-r--r-- | ranger/api/commands.py | 49 | ||||
-rw-r--r-- | ranger/container/settingobject.py | 1 | ||||
-rw-r--r-- | ranger/core/actions.py | 40 | ||||
-rw-r--r-- | ranger/core/helper.py | 26 | ||||
-rw-r--r-- | ranger/defaults/commands.py | 31 | ||||
-rw-r--r-- | ranger/defaults/options.py | 4 | ||||
-rw-r--r-- | ranger/defaults/rc.conf | 15 | ||||
-rw-r--r-- | ranger/gui/ui.py | 3 |
8 files changed, 151 insertions, 18 deletions
diff --git a/ranger/api/commands.py b/ranger/api/commands.py index 9a353eef..94b7f341 100644 --- a/ranger/api/commands.py +++ b/ranger/api/commands.py @@ -17,6 +17,7 @@ import os from collections import deque from ranger.api import * from ranger.core.shared import FileManagerAware +from ranger.ext.lazy_property import lazy_property from ranger.ext.command_parser import LazyParser as parse # A dummy that allows the generation of docstrings in ranger.defaults.commands @@ -73,8 +74,11 @@ class Command(FileManagerAware): """Abstract command class""" name = None allow_abbrev = True + _shifted = 0 + def __init__(self, line): self.line = line + self.args = line.split() def execute(self): """Override this""" @@ -88,6 +92,51 @@ class Command(FileManagerAware): def cancel(self): """Override this""" + # Easy ways to get information + def arg(self, n): + """Returns the nth space separated word""" + try: + return self.args[n] + except IndexError: + return "" + + def rest(self, n): + """Returns everything from and after arg(n)""" + got_space = False + word_count = 0 + for i in range(len(self.line)): + if self.line[i] == " ": + if not got_space: + got_space = True + word_count += 1 + elif got_space: + got_space = False + if word_count == n + self._shifted: + return self.line[i:] + return "" + + def start(self, n): + """Returns everything until (inclusively) arg(n)""" + return ' '.join(self.args[:n]) + " " # XXX + + def shift(self): + del self.args[0] + self._shifted += 1 + + def tabinsert(self, word): + return ''.join([self._tabinsert_left, word, self._tabinsert_right]) + + @lazy_property + def _tabinsert_left(self): + try: + return self.line[:self.line[0:self.pos].rindex(' ') + 1] + except ValueError: + return '' + + @lazy_property + def _tabinsert_right(self): + return self.line[self.pos:] + # COMPAT: this is still used in old commands.py configs def _tab_only_directories(self): from os.path import dirname, basename, expanduser, join, isdir diff --git a/ranger/container/settingobject.py b/ranger/container/settingobject.py index 6b6fbae7..a245db21 100644 --- a/ranger/container/settingobject.py +++ b/ranger/container/settingobject.py @@ -31,6 +31,7 @@ ALLOWED_SETTINGS = { 'draw_borders': bool, 'flushinput': bool, 'hidden_filter': lambda x: isinstance(x, str) or hasattr(x, 'match'), + 'load_default_rc': bool, 'max_console_history_size': (int, type(None)), 'max_history_size': (int, type(None)), 'mouse_enabled': bool, diff --git a/ranger/core/actions.py b/ranger/core/actions.py index 96e23189..0314888d 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -70,7 +70,19 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): bad = True text = str(text) self.log.appendleft(text) - self.ui.status.notify(text, duration=duration, bad=bad) + if self.ui and self.ui.is_on: + self.ui.status.notify(text, duration=duration, bad=bad) + else: + print(text) + + def abort(self): + try: + item = self.loader.queue[0] + except: + self.notify("Type Q or :quit<Enter> to exit Ranger") + else: + self.notify("Aborting: " + item.get_description()) + self.loader.remove(index=0) def redraw_window(self): """Redraw the window""" @@ -78,14 +90,20 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): 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(string, prompt=prompt, position=position) + self.ui.open_console(string, prompt=prompt, position=position) def execute_console(self, string=''): """Execute a command for the console""" - self.open_console(string=string) - self.ui.console.line = string - self.ui.console.execute() + command_name = string.split()[0] + try: + cmd_class = self.commands.get_command(command_name) + except: + self.notify("Command not found: `%s'" % command_name) + else: + try: + cmd_class(string).execute() + except Exception as error: + self.notify(error) def substitute_macros(self, string): return _MacroTemplate(string).safe_substitute(self._get_macros()) @@ -149,6 +167,16 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): return macros + def source_cmdlist(self, filename, narg=None): + for line in open(filename, 'r'): + line = line.rstrip("\r\n") + try: + self.execute_console(line) + except Exception as e: + if ranger.arg.debug: + raise + else: + self.notify('Error in line `%s\':\n %s' % (line, str(e)), bad=True) def execute_file(self, files, **kw): """Execute a file. diff --git a/ranger/core/helper.py b/ranger/core/helper.py index 910c0241..62ab9091 100644 --- a/ranger/core/helper.py +++ b/ranger/core/helper.py @@ -103,22 +103,27 @@ def load_settings(fm, clean): pass from ranger.defaults import commands comcont.load_commands_from_module(commands) - commands = comcont + fm.commands = comcont # Load apps try: import apps except ImportError: from ranger.defaults import apps + fm.apps = apps.CustomApplications() - # Load keys + # Setup keymanager keymanager = ranger.core.shared.EnvironmentAware.env.keymanager ranger.api.keys.keymanager = keymanager - from ranger.defaults import keys - try: - import keys - except ImportError: - pass + + # Load rc.conf + conf = fm.confpath('rc.conf') + if os.access(conf, os.R_OK): + fm.source_cmdlist(conf) + if fm.settings.load_default_rc: + conf = fm.relpath('defaults', 'rc.conf') + if os.access(conf, os.R_OK): + fm.source_cmdlist(conf) # Load plugins try: @@ -148,15 +153,12 @@ def load_settings(fm, clean): else: comcont = ranger.api.commands.CommandContainer() ranger.api.commands.alias = comcont.alias - from ranger.api import keys keymanager = ranger.core.shared.EnvironmentAware.env.keymanager ranger.api.keys.keymanager = keymanager from ranger.defaults import commands, keys, apps comcont.load_commands_from_module(commands) - commands = comcont - fm.commands = commands - fm.keys = keys - fm.apps = apps.CustomApplications() + fm.commands = comcont + fm.apps = apps.CustomApplications() def load_apps(fm, clean): diff --git a/ranger/defaults/commands.py b/ranger/defaults/commands.py index 2c85226b..d2c02865 100644 --- a/ranger/defaults/commands.py +++ b/ranger/defaults/commands.py @@ -755,6 +755,37 @@ class bulkrename(Command): cmdfile.close() +class help_(Command): + """ + :help + + Display ranger's manual page. + """ + name = 'help' + def execute(self): + self.fm.display_help() + + +class map_(Command): + """ + :map <keysequence> <command> + Maps a command to a keysequence in the "browser" context. + + Example: + map j move down + map J move down 10 + """ + name = 'map' + context = 'browser' + resolve_macros = False + def execute(self): + command = self.rest(2) + self.fm.env.keymanager.map(self.context, self.arg(1), + func=lambda arg: arg.fm.execute_console(command), +# func=lambda arg: arg.fm.cmd(command, n=arg.n, any=arg.matches), + help=command) + + class filter(Command): """ :filter <string> diff --git a/ranger/defaults/options.py b/ranger/defaults/options.py index c9cbf8ad..8b2395da 100644 --- a/ranger/defaults/options.py +++ b/ranger/defaults/options.py @@ -33,6 +33,10 @@ of the values stay the same. from ranger.api.options import * +# Load the deault rc.conf file? If you've copied it to your configuration +# direcory, then you should deactivate this option. +load_default_rc = True + # Which files should be hidden? Toggle this by typing `zh' or # changing the setting `show_hidden' hidden_filter = regexp( diff --git a/ranger/defaults/rc.conf b/ranger/defaults/rc.conf new file mode 100644 index 00000000..c462bb65 --- /dev/null +++ b/ranger/defaults/rc.conf @@ -0,0 +1,15 @@ +# VIM +map j eval fm.move(down=1) +map k eval fm.move(up=1) +map h eval fm.move(left=1) +map l eval fm.move(right=1) +map q quit +map Q quit + +map R eval fm.reload_cwd() +map <c-r> eval fm.reset() +map <c-l> eval fm.redraw_window() +map H eval fm.history_go(-1) +map L eval fm.history_go(1) +map <c-c> eval fm.abort() +map ? help diff --git a/ranger/gui/ui.py b/ranger/gui/ui.py index 128a3434..cd11a0d0 100644 --- a/ranger/gui/ui.py +++ b/ranger/gui/ui.py @@ -48,6 +48,7 @@ def _setup_mouse(signal): class UI(DisplayableContainer): is_set_up = False load_mode = False + is_on = False def __init__(self, env=None, fm=None): self._draw_title = os.environ["TERM"] in TERMINALS_WITH_TITLE os.environ['ESCDELAY'] = '25' # don't know a cleaner way @@ -86,6 +87,7 @@ class UI(DisplayableContainer): self.is_set_up = True self.setup() self.update_size() + self.is_on = True def suspend(self): """Turn off curses""" @@ -99,6 +101,7 @@ class UI(DisplayableContainer): if self.settings.mouse_enabled: _setup_mouse(dict(value=False)) curses.endwin() + self.is_on = False def set_load_mode(self, boolean): boolean = bool(boolean) |