diff options
-rw-r--r-- | ranger/container/environment.py | 4 | ||||
-rw-r--r-- | ranger/container/keybuffer.py | 57 | ||||
-rw-r--r-- | ranger/defaults/keys.py | 39 | ||||
-rw-r--r-- | ranger/gui/ui.py | 9 | ||||
-rw-r--r-- | ranger/gui/widgets/console.py | 2 |
5 files changed, 92 insertions, 19 deletions
diff --git a/ranger/container/environment.py b/ranger/container/environment.py index b766a4c9..1b26d48e 100644 --- a/ranger/container/environment.py +++ b/ranger/container/environment.py @@ -36,11 +36,11 @@ class Environment(SettingsAware): def key_append(self, key): """Append a key to the keybuffer""" from ranger import log - self.keybuffer = KeyBuffer(self.keybuffer + (key, )) + self.keybuffer.append(key) def key_clear(self): """Clear the keybuffer""" - self.keybuffer = KeyBuffer() + self.keybuffer.clear() def at_level(self, level): """Returns the FileSystemObject at the given level. diff --git a/ranger/container/keybuffer.py b/ranger/container/keybuffer.py index 10c9c40c..048a5083 100644 --- a/ranger/container/keybuffer.py +++ b/ranger/container/keybuffer.py @@ -1,11 +1,56 @@ -class KeyBuffer(tuple): - """Extension of tuple suited to be used as a keybuffer""" - def __str__(self): - """returns a concatenation of all characters""" - return "".join( map( to_string, self ) ) - def to_string(i): try: return chr(i) except ValueError: return '?' + +from collections import deque +from curses.ascii import ascii + +ZERO = ord('0') +NINE = ord('9') + +class KeyBuffer(object): + def __init__(self): + self.number = None + self.queue = deque() + self.queue_with_numbers = deque() + + def clear(self): + """Clear the keybuffer and restore the initial state""" + self.number = None + self.queue.clear() + self.queue_with_numbers.clear() + + def append(self, key): + """ + Append a key to the keybuffer, or initial numbers to + the number attribute. + """ + self.queue_with_numbers.append(key) + + if not self.queue and key >= ZERO and key <= NINE: + if self.number is None: + self.number = 0 + try: + self.number = self.number * 10 + int(chr(key)) + except ValueError: + return + else: + self.queue.append(key) + + def tuple_with_numbers(self): + """Get a tuple of ascii codes.""" + return tuple(self.queue_with_numbers) + + def tuple_without_numbers(self): + """ + Get a tuple of ascii codes. + If the keybuffer starts with numbers, those will + be left out. To access them, use keybuffer.number + """ + return tuple(self.queue) + + def __str__(self): + """returns a concatenation of all characters""" + return "".join( map( to_string, self.queue_with_numbers ) ) diff --git a/ranger/defaults/keys.py b/ranger/defaults/keys.py index 98ecd6c1..e3be795d 100644 --- a/ranger/defaults/keys.py +++ b/ranger/defaults/keys.py @@ -1,12 +1,10 @@ import curses from curses.ascii import * from ranger import RANGERDIR +from ranger import log from ranger.gui.widgets.console import Console from ranger.container.bookmarks import ALLOWED_KEYS as ALLOWED_BOOKMARK_KEYS -def do(method, *args, **kw): - return lambda fm: getattr(fm, method)(*args, **kw) - # syntax for binding keys: bind(*keys, fnc) # fnc is a function which is called with the FM instance, # keys are one or more key-combinations which are either: @@ -20,6 +18,9 @@ def do(method, *args, **kw): def initialize_commands(command_list): """Initialize the commands for the main user interface""" + def do(method, *args, **kw): + return lambda fm, n: getattr(fm, method)(*args, **kw) + def bind(*args): command_list.bind(args[-1], *args[:-1]) @@ -28,15 +29,12 @@ def initialize_commands(command_list): bind(curses.KEY_ENTER, ctrl('j'), do('move_right', mode=1)) bind('H', do('history_go', -1)) bind('L', do('history_go', 1)) - bind('j', do('move_pointer', relative = 1)) bind('J', do('move_pointer_by_pages', 0.5)) - bind('k', do('move_pointer', relative = -1)) bind('K', do('move_pointer_by_pages', -0.5)) - bind('gg', do('move_pointer', absolute = 0)) - bind('G', do('move_pointer', absolute = -1)) bind('E', do('edit_file')) bind('o', do('force_load_preview')) + bind('yy', 'cp', do('copy')) bind('cut', do('cut')) bind('p', do('paste')) @@ -85,11 +83,33 @@ def initialize_commands(command_list): bind('!', do('open_console', '!')) bind('r', do('open_console', '@')) - def test(fm): + + # definitions which require their own function: + def test(fm, n): from ranger import log log(fm.bookmarks.dct) bind('x', test) + def ggG(default): + # moves to an absolute point, or to a predefined default + # if no number is specified. + return lambda fm, n: \ + fm.move_pointer(absolute=(n or default)) + + bind('gg', ggG(0)) + bind('G', ggG(-1)) + + bind('%', lambda fm, n: fm.move_pointer_by_percentage(absolute=n or 0)) + + def jk(direction): + # moves up or down by the specified number or one, in + # the predefined direction + return lambda fm, n: \ + fm.move_pointer(relative=(n or 1) * direction) + + bind('j', jk(1)) + bind('k', jk(-1)) + command_list.rebuild_paths() @@ -99,6 +119,9 @@ def initialize_console_commands(command_list): def bind(*args): command_list.bind(args[-1], *args[:-1]) + def do(method, *args, **kw): + return lambda fm: getattr(fm, method)(*args, **kw) + def do_fm(method, *args, **kw): return lambda con: getattr(con.fm, method)(*args, **kw) diff --git a/ranger/gui/ui.py b/ranger/gui/ui.py index da633698..cdb58ad5 100644 --- a/ranger/gui/ui.py +++ b/ranger/gui/ui.py @@ -111,7 +111,12 @@ class UI(DisplayableContainer): return try: - cmd = self.commandlist[tuple(self.env.keybuffer)] + tup = self.env.keybuffer.tuple_without_numbers() + + if tup: + cmd = self.commandlist[tup] + else: + return except KeyError: self.env.key_clear() return @@ -119,7 +124,7 @@ class UI(DisplayableContainer): if cmd == self.commandlist.dummy_object: return - cmd.execute(self.fm) + cmd.execute(self.fm, self.env.keybuffer.number) self.env.key_clear() def get_next_key(self): diff --git a/ranger/gui/widgets/console.py b/ranger/gui/widgets/console.py index bed9f031..f2c15426 100644 --- a/ranger/gui/widgets/console.py +++ b/ranger/gui/widgets/console.py @@ -79,7 +79,7 @@ class Console(Widget): from curses.ascii import ctrl, ESC try: - cmd = self.commandlist[self.env.keybuffer] + cmd = self.commandlist[self.env.keybuffer.tuple_with_numbers()] except KeyError: self.env.key_clear() return |