diff options
-rw-r--r-- | ranger/container/keymap.py | 93 | ||||
-rw-r--r-- | ranger/ext/keybinding_parser.py | 96 | ||||
-rw-r--r-- | test/tc_newkeys.py | 5 |
3 files changed, 108 insertions, 86 deletions
diff --git a/ranger/container/keymap.py b/ranger/container/keymap.py index f09d9cfb..50568638 100644 --- a/ranger/container/keymap.py +++ b/ranger/container/keymap.py @@ -15,15 +15,13 @@ import curses.ascii from collections import deque -from string import ascii_lowercase from inspect import isfunction, getargspec from ranger.ext.tree import Tree from ranger.ext.direction import Direction +from ranger.ext.keybinding_parser import parse_keybinding, \ + DIRKEY, ANYKEY, PASSIVE_ACTION MAX_ALIAS_RECURSION = 20 -PASSIVE_ACTION = 9003 -DIRKEY = 9001 -ANYKEY = 9002 FUNC = 'func' DIRECTION = 'direction' DIRARG = 'dir' @@ -79,14 +77,14 @@ class KeyMap(Tree): assert keys bind = Binding(keys, actions) for key in keys: - self.set(translate_keys(key), bind) + self.set(parse_keybinding(key), bind) def unmap(self, *keys): for key in keys: - self.unset(translate_keys(key)) + self.unset(parse_keybinding(key)) def __getitem__(self, key): - return self.traverse(translate_keys(key)) + return self.traverse(parse_keybinding(key)) class KeyMapWithDirections(KeyMap): @@ -169,7 +167,7 @@ class Binding(object): except KeyError: self.alias = None else: - self.alias = tuple(translate_keys(alias)) + self.alias = tuple(parse_keybinding(alias)) class KeyBuffer(object): """The evaluator and storage for pressed keys""" @@ -224,7 +222,7 @@ class KeyBuffer(object): match = self.dir_tree_pointer if isinstance(self.dir_tree_pointer, Binding): if match.alias: - self.key_queue.extend(translate_keys(match.alias)) + self.key_queue.extend(parse_keybinding(match.alias)) self.dir_tree_pointer = self.direction_keys._tree self.max_alias_recursion -= 1 else: @@ -294,7 +292,7 @@ class KeyBuffer(object): self.tree_pointer = self.tree_pointer._tree if isinstance(self.tree_pointer, Binding): if self.tree_pointer.alias: - self.key_queue.extend(translate_keys(self.tree_pointer.alias)) + self.key_queue.extend(parse_keybinding(self.tree_pointer.alias)) self.tree_pointer = self.keymap._tree self.max_alias_recursion -= 1 else: @@ -324,83 +322,10 @@ class KeyBuffer(object): return "".join(to_string(c) for c in self.all_keys) def simulate_press(self, string): - for char in translate_keys(string): + for char in parse_keybinding(string): self.add(char) if self.done: return self.command if self.failure: break return self.command - -special_keys = { - 'dir': DIRKEY, - 'any': ANYKEY, - 'bg': PASSIVE_ACTION, - 'backspace': curses.KEY_BACKSPACE, - 'backspace2': curses.ascii.DEL, - 'delete': curses.KEY_DC, - 'cr': ord("\n"), - 'enter': ord("\n"), - 'space': ord(" "), - 'esc': curses.ascii.ESC, - 'down': curses.KEY_DOWN, - 'up': curses.KEY_UP, - 'left': curses.KEY_LEFT, - 'right': curses.KEY_RIGHT, - 'pagedown': curses.KEY_NPAGE, - 'pageup': curses.KEY_PPAGE, - 'home': curses.KEY_HOME, - 'end': curses.KEY_END, - 'tab': ord('\t'), - 's-tab': curses.KEY_BTAB, -} -for char in ascii_lowercase: - special_keys['c-' + char] = ord(char) - 96 - -for char in (ascii_lowercase + '0123456789'): - special_keys['a-' + char] = (27, ord(char)) - -def translate_keys(obj): - """ - Translate a keybinding to a sequence of integers - - Example: - lol<CR> => (108, 111, 108, 10) - """ - assert isinstance(obj, (tuple, int, str)) - if isinstance(obj, tuple): - for char in obj: - yield char - elif isinstance(obj, int): - yield obj - elif isinstance(obj, str): - in_brackets = False - bracket_content = None - for char in obj: - if in_brackets: - if char == '>': - in_brackets = False - string = ''.join(bracket_content).lower() - try: - keys = special_keys[string] - for key in keys: - yield key - except KeyError: - yield ord('<') - for c in bracket_content: - yield ord(c) - yield ord('>') - except TypeError: - yield keys # it was no tuple, just an int - else: - bracket_content.append(char) - else: - if char == '<': - in_brackets = True - bracket_content = [] - else: - yield ord(char) - if in_brackets: - yield ord('<') - for c in bracket_content: - yield ord(c) diff --git a/ranger/ext/keybinding_parser.py b/ranger/ext/keybinding_parser.py new file mode 100644 index 00000000..58d8fe5c --- /dev/null +++ b/ranger/ext/keybinding_parser.py @@ -0,0 +1,96 @@ +# Copyright (C) 2009, 2010 Roman Zimbelmann <romanz@lavabit.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import curses +from string import ascii_lowercase + +def parse_keybinding(obj): + """ + Translate a keybinding to a sequence of integers + + Example: + lol<CR> => (108, 111, 108, 10) + """ + assert isinstance(obj, (tuple, int, str)) + if isinstance(obj, tuple): + for char in obj: + yield char + elif isinstance(obj, int): + yield obj + elif isinstance(obj, str): + in_brackets = False + bracket_content = None + for char in obj: + if in_brackets: + if char == '>': + in_brackets = False + string = ''.join(bracket_content).lower() + try: + keys = special_keys[string] + for key in keys: + yield key + except KeyError: + yield ord('<') + for c in bracket_content: + yield ord(c) + yield ord('>') + except TypeError: + yield keys # it was no tuple, just an int + else: + bracket_content.append(char) + else: + if char == '<': + in_brackets = True + bracket_content = [] + else: + yield ord(char) + if in_brackets: + yield ord('<') + for c in bracket_content: + yield ord(c) + +# Arbitrary numbers which are not used with curses.KEY_XYZ +DIRKEY = 9001 +ANYKEY = 9002 +PASSIVE_ACTION = 9003 + +special_keys = { + 'dir': DIRKEY, + 'any': ANYKEY, + 'bg': PASSIVE_ACTION, + 'backspace': curses.KEY_BACKSPACE, + 'backspace2': curses.ascii.DEL, + 'delete': curses.KEY_DC, + 'cr': ord("\n"), + 'enter': ord("\n"), + 'space': ord(" "), + 'esc': curses.ascii.ESC, + 'down': curses.KEY_DOWN, + 'up': curses.KEY_UP, + 'left': curses.KEY_LEFT, + 'right': curses.KEY_RIGHT, + 'pagedown': curses.KEY_NPAGE, + 'pageup': curses.KEY_PPAGE, + 'home': curses.KEY_HOME, + 'end': curses.KEY_END, + 'tab': ord('\t'), + 's-tab': curses.KEY_BTAB, +} + +for char in ascii_lowercase: + special_keys['c-' + char] = ord(char) - 96 + +for char in (ascii_lowercase + '0123456789'): + special_keys['a-' + char] = (27, ord(char)) diff --git a/test/tc_newkeys.py b/test/tc_newkeys.py index c06c2894..06345450 100644 --- a/test/tc_newkeys.py +++ b/test/tc_newkeys.py @@ -19,6 +19,7 @@ from unittest import TestCase, main from ranger.ext.tree import Tree from ranger.container.keymap import * +from ranger.ext.keybinding_parser import parse_keybinding import sys @@ -87,7 +88,7 @@ class Test(PressTestCase): def test(string, *args): if not args: args = (string, ) - self.assertEqual(ordtuple(*args), tuple(translate_keys(string))) + self.assertEqual(ordtuple(*args), tuple(parse_keybinding(string))) def ordtuple(*args): lst = [] @@ -404,7 +405,7 @@ class Test(PressTestCase): self.assertEqual(1, press('xxx')) # corrupt the tree - tup = tuple(translate_keys('xxx')) + tup = tuple(parse_keybinding('xxx')) x = ord('x') km._tree[x][x][x] = "Boo" |