From bfac461b7954101296fe95f4d2531174a60df5d2 Mon Sep 17 00:00:00 2001 From: hut Date: Fri, 16 Apr 2010 16:07:44 +0200 Subject: keymap: move translate_keys to ranger.ext.keybinding_parser --- test/tc_newkeys.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'test') 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" -- cgit 1.4.1-2-gfad0 From 2c9557d5164b0e31b9f7c1a36c0ac8bf8f002944 Mon Sep 17 00:00:00 2001 From: hut Date: Fri, 16 Apr 2010 16:12:47 +0200 Subject: keymap: moved simulate_press to where it belongs: tc_newkeys --- ranger/container/keymap.py | 9 --------- test/tc_newkeys.py | 19 ++++++++++++++----- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'test') diff --git a/ranger/container/keymap.py b/ranger/container/keymap.py index ab87ae36..b718c2a7 100644 --- a/ranger/container/keymap.py +++ b/ranger/container/keymap.py @@ -313,12 +313,3 @@ class KeyBuffer(object): def __str__(self): """returns a concatenation of all characters""" return "".join(to_string(c) for c in self.all_keys) - - def simulate_press(self, string): - for char in parse_keybinding(string): - self.add(char) - if self.done: - return self.command - if self.failure: - break - return self.command diff --git a/test/tc_newkeys.py b/test/tc_newkeys.py index 06345450..9bfb43b0 100644 --- a/test/tc_newkeys.py +++ b/test/tc_newkeys.py @@ -23,12 +23,21 @@ from ranger.ext.keybinding_parser import parse_keybinding import sys +def simulate_press(self, string): + for char in parse_keybinding(string): + self.add(char) + if self.done: + return self.command + if self.failure: + break + return self.command + class PressTestCase(TestCase): """Some useful methods for the actual test""" def _mkpress(self, keybuffer, _=0): def press(keys): keybuffer.clear() - match = keybuffer.simulate_press(keys) + match = simulate_press(keybuffer, keys) self.assertFalse(keybuffer.failure, "parsing keys '"+keys+"' did fail!") self.assertTrue(keybuffer.done, @@ -41,13 +50,13 @@ class PressTestCase(TestCase): def assertPressFails(self, kb, keys): kb.clear() - kb.simulate_press(keys) + simulate_press(kb, keys) self.assertTrue(kb.failure, "Keypress did not fail as expected") kb.clear() def assertPressIncomplete(self, kb, keys): kb.clear() - kb.simulate_press(keys) + simulate_press(kb, keys) self.assertFalse(kb.failure, "Keypress failed, expected incomplete") self.assertFalse(kb.done, "Keypress done which was unexpected") kb.clear() @@ -78,7 +87,7 @@ class Test(PressTestCase): self.assertEqual(2, press('ppj')) kb.clear() - match = kb.simulate_press('pp') + match = simulate_press(kb, 'pp') args = CommandArgs(0, 0, kb) self.assert_(match) self.assert_(match.function) @@ -414,7 +423,7 @@ class Test(PressTestCase): self.assertPressIncomplete(kb, 'xx') self.assertPressIncomplete(kb, 'x') if not sys.flags.optimize: - self.assertRaises(AssertionError, kb.simulate_press, 'xxx') + self.assertRaises(AssertionError, simulate_press, kb, 'xxx') kb.clear() def test_directions_as_functions(self): -- cgit 1.4.1-2-gfad0 From 175290dbbba5e7bc5d416bc0ba87b687238976c4 Mon Sep 17 00:00:00 2001 From: hut Date: Fri, 16 Apr 2010 16:37:31 +0200 Subject: moved container.keymap.KeyBuffer into seperate module --- ranger/container/__init__.py | 3 +- ranger/container/keybuffer.py | 176 ++++++++++++++++++++++++++++++++++++++++ ranger/container/keymap.py | 163 +------------------------------------ ranger/ext/keybinding_parser.py | 2 +- test/tc_newkeys.py | 1 + 5 files changed, 182 insertions(+), 163 deletions(-) create mode 100644 ranger/container/keybuffer.py (limited to 'test') diff --git a/ranger/container/__init__.py b/ranger/container/__init__.py index c1bb8194..3351cc63 100644 --- a/ranger/container/__init__.py +++ b/ranger/container/__init__.py @@ -17,5 +17,6 @@ used to manage stored data """ from ranger.container.history import History -from .keymap import KeyMap, KeyBuffer, KeyManager +from .keymap import KeyMap, KeyManager +from .keybuffer import KeyBuffer from .bookmarks import Bookmarks diff --git a/ranger/container/keybuffer.py b/ranger/container/keybuffer.py new file mode 100644 index 00000000..50914f84 --- /dev/null +++ b/ranger/container/keybuffer.py @@ -0,0 +1,176 @@ +# Copyright (C) 2009, 2010 Roman Zimbelmann +# +# 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 . + +import curses.ascii +from collections import deque +from string import digits +from ranger.ext.keybinding_parser import parse_keybinding, \ + DIRKEY, ANYKEY, PASSIVE_ACTION +from ranger.container.keymap import Binding, KeyMap + +MAX_ALIAS_RECURSION = 20 + +class KeyBuffer(object): + """The evaluator and storage for pressed keys""" + def __init__(self, keymap, direction_keys): + self.assign(keymap, direction_keys) + + def assign(self, keymap, direction_keys): + self.keymap = keymap + self.direction_keys = direction_keys + + def add(self, key): + assert isinstance(key, int) + assert key >= 0 + self.all_keys.append(key) + self.key_queue.append(key) + while self.key_queue: + key = self.key_queue.popleft() + + # evaluate quantifiers + if self.eval_quantifier and self._do_eval_quantifier(key): + return + + # evaluate the command + if self.eval_command and self._do_eval_command(key): + return + + # evaluate (the first number of) the direction-quantifier + if self.eval_quantifier and self._do_eval_quantifier(key): + return + + # evaluate direction keys {j,k,gg,pagedown,...} + if not self.eval_command: + self._do_eval_direction(key) + + def _do_eval_direction(self, key): + try: + assert isinstance(self.dir_tree_pointer, dict) + self.dir_tree_pointer = self.dir_tree_pointer[key] + except KeyError: + self.failure = True + else: + self._direction_try_to_finish() + + def _direction_try_to_finish(self): + if self.max_alias_recursion <= 0: + self.failure = True + return None + match = self.dir_tree_pointer + assert isinstance(match, (Binding, dict, KeyMap)) + if isinstance(match, KeyMap): + self.dir_tree_pointer = self.dir_tree_pointer._tree + match = self.dir_tree_pointer + if isinstance(self.dir_tree_pointer, Binding): + if match.alias: + self.key_queue.extend(parse_keybinding(match.alias)) + self.dir_tree_pointer = self.direction_keys._tree + self.max_alias_recursion -= 1 + else: + direction = match.actions['dir'].copy() + if self.direction_quant is not None: + direction.multiply(self.direction_quant) + self.directions.append(direction) + self.direction_quant = None + self.eval_command = True + self._try_to_finish() + + def _do_eval_quantifier(self, key): + if self.eval_command: + tree = self.tree_pointer + else: + tree = self.dir_tree_pointer + if chr(key) in digits and ANYKEY not in tree: + attr = self.eval_command and 'quant' or 'direction_quant' + if getattr(self, attr) is None: + setattr(self, attr, 0) + setattr(self, attr, getattr(self, attr) * 10 + key - 48) + else: + self.eval_quantifier = False + return None + return True + + def _do_eval_command(self, key): + assert isinstance(self.tree_pointer, dict), self.tree_pointer + try: + self.tree_pointer = self.tree_pointer[key] + except TypeError: + self.failure = True + return None + except KeyError: + try: + chr(key) in digits or self.direction_keys._tree[key] + self.tree_pointer = self.tree_pointer[DIRKEY] + except KeyError: + try: + self.tree_pointer = self.tree_pointer[ANYKEY] + except KeyError: + self.failure = True + return None + else: + self.matches.append(key) + assert isinstance(self.tree_pointer, (Binding, dict)) + self._try_to_finish() + else: + assert isinstance(self.tree_pointer, (Binding, dict)) + self.eval_command = False + self.eval_quantifier = True + self.dir_tree_pointer = self.direction_keys._tree + else: + if isinstance(self.tree_pointer, dict): + try: + self.command = self.tree_pointer[PASSIVE_ACTION] + except (KeyError, TypeError): + self.command = None + self._try_to_finish() + + def _try_to_finish(self): + if self.max_alias_recursion <= 0: + self.failure = True + return None + assert isinstance(self.tree_pointer, (Binding, dict, KeyMap)) + if isinstance(self.tree_pointer, KeyMap): + self.tree_pointer = self.tree_pointer._tree + if isinstance(self.tree_pointer, Binding): + if self.tree_pointer.alias: + keys = parse_keybinding(self.tree_pointer.alias) + self.key_queue.extend(keys) + self.tree_pointer = self.keymap._tree + self.max_alias_recursion -= 1 + else: + self.command = self.tree_pointer + self.done = True + + def clear(self): + self.max_alias_recursion = MAX_ALIAS_RECURSION + self.failure = False + self.done = False + self.quant = None + self.matches = [] + self.command = None + self.direction_quant = None + self.directions = [] + self.all_keys = [] + self.tree_pointer = self.keymap._tree + self.dir_tree_pointer = self.direction_keys._tree + + self.key_queue = deque() + + self.eval_quantifier = True + self.eval_command = True + + def __str__(self): + """returns a concatenation of all characters""" + return "".join("{0:c}".format(c) for c in self.all_keys) diff --git a/ranger/container/keymap.py b/ranger/container/keymap.py index 60272be0..167ba160 100644 --- a/ranger/container/keymap.py +++ b/ranger/container/keymap.py @@ -13,16 +13,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import curses.ascii -from collections import deque -from string import digits -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 +from ranger.ext.keybinding_parser import parse_keybinding, DIRKEY, ANYKEY -MAX_ALIAS_RECURSION = 20 FUNC = 'func' DIRARG = 'dir' ALIASARG = 'alias' @@ -52,7 +46,7 @@ class KeyMap(Tree): if keywords: return self._add_binding(*args, **keywords) firstarg = args[-1] - if isfunction(firstarg): + if hasattr(firstarg, '__call__'): keywords[FUNC] = firstarg return self._add_binding(*args[:-1], **keywords) def decorator_function(func): @@ -151,156 +145,3 @@ class Binding(object): self.alias = None else: self.alias = tuple(parse_keybinding(alias)) - -class KeyBuffer(object): - """The evaluator and storage for pressed keys""" - def __init__(self, keymap, direction_keys): - self.assign(keymap, direction_keys) - - def assign(self, keymap, direction_keys): - self.keymap = keymap - self.direction_keys = direction_keys - - def add(self, key): - assert isinstance(key, int) - assert key >= 0 - self.all_keys.append(key) - self.key_queue.append(key) - while self.key_queue: - key = self.key_queue.popleft() - - # evaluate quantifiers - if self.eval_quantifier and self._do_eval_quantifier(key): - return - - # evaluate the command - if self.eval_command and self._do_eval_command(key): - return - - # evaluate (the first number of) the direction-quantifier - if self.eval_quantifier and self._do_eval_quantifier(key): - return - - # evaluate direction keys {j,k,gg,pagedown,...} - if not self.eval_command: - self._do_eval_direction(key) - - def _do_eval_direction(self, key): - try: - assert isinstance(self.dir_tree_pointer, dict) - self.dir_tree_pointer = self.dir_tree_pointer[key] - except KeyError: - self.failure = True - else: - self._direction_try_to_finish() - - def _direction_try_to_finish(self): - if self.max_alias_recursion <= 0: - self.failure = True - return None - match = self.dir_tree_pointer - assert isinstance(match, (Binding, dict, KeyMap)) - if isinstance(match, KeyMap): - self.dir_tree_pointer = self.dir_tree_pointer._tree - match = self.dir_tree_pointer - if isinstance(self.dir_tree_pointer, Binding): - if match.alias: - self.key_queue.extend(parse_keybinding(match.alias)) - self.dir_tree_pointer = self.direction_keys._tree - self.max_alias_recursion -= 1 - else: - direction = match.actions['dir'].copy() - if self.direction_quant is not None: - direction.multiply(self.direction_quant) - self.directions.append(direction) - self.direction_quant = None - self.eval_command = True - self._try_to_finish() - - def _do_eval_quantifier(self, key): - if self.eval_command: - tree = self.tree_pointer - else: - tree = self.dir_tree_pointer - if chr(key) in digits and ANYKEY not in tree: - attr = self.eval_command and 'quant' or 'direction_quant' - if getattr(self, attr) is None: - setattr(self, attr, 0) - setattr(self, attr, getattr(self, attr) * 10 + key - 48) - else: - self.eval_quantifier = False - return None - return True - - def _do_eval_command(self, key): - assert isinstance(self.tree_pointer, dict), self.tree_pointer - try: - self.tree_pointer = self.tree_pointer[key] - except TypeError: - self.failure = True - return None - except KeyError: - try: - chr(key) in digits or self.direction_keys._tree[key] - self.tree_pointer = self.tree_pointer[DIRKEY] - except KeyError: - try: - self.tree_pointer = self.tree_pointer[ANYKEY] - except KeyError: - self.failure = True - return None - else: - self.matches.append(key) - assert isinstance(self.tree_pointer, (Binding, dict)) - self._try_to_finish() - else: - assert isinstance(self.tree_pointer, (Binding, dict)) - self.eval_command = False - self.eval_quantifier = True - self.dir_tree_pointer = self.direction_keys._tree - else: - if isinstance(self.tree_pointer, dict): - try: - self.command = self.tree_pointer[PASSIVE_ACTION] - except (KeyError, TypeError): - self.command = None - self._try_to_finish() - - def _try_to_finish(self): - if self.max_alias_recursion <= 0: - self.failure = True - return None - assert isinstance(self.tree_pointer, (Binding, dict, KeyMap)) - if isinstance(self.tree_pointer, KeyMap): - self.tree_pointer = self.tree_pointer._tree - if isinstance(self.tree_pointer, Binding): - if self.tree_pointer.alias: - keys = parse_keybinding(self.tree_pointer.alias) - self.key_queue.extend(keys) - self.tree_pointer = self.keymap._tree - self.max_alias_recursion -= 1 - else: - self.command = self.tree_pointer - self.done = True - - def clear(self): - self.max_alias_recursion = MAX_ALIAS_RECURSION - self.failure = False - self.done = False - self.quant = None - self.matches = [] - self.command = None - self.direction_quant = None - self.directions = [] - self.all_keys = [] - self.tree_pointer = self.keymap._tree - self.dir_tree_pointer = self.direction_keys._tree - - self.key_queue = deque() - - self.eval_quantifier = True - self.eval_command = True - - def __str__(self): - """returns a concatenation of all characters""" - return "".join("{0:c}".format(c) for c in self.all_keys) diff --git a/ranger/ext/keybinding_parser.py b/ranger/ext/keybinding_parser.py index 58d8fe5c..c33ac12f 100644 --- a/ranger/ext/keybinding_parser.py +++ b/ranger/ext/keybinding_parser.py @@ -13,7 +13,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import curses +import curses.ascii from string import ascii_lowercase def parse_keybinding(obj): diff --git a/test/tc_newkeys.py b/test/tc_newkeys.py index 9bfb43b0..8aa043ae 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.container.keybuffer import KeyBuffer from ranger.ext.keybinding_parser import parse_keybinding import sys -- cgit 1.4.1-2-gfad0