summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/container/keymap.py93
-rw-r--r--ranger/ext/keybinding_parser.py96
-rw-r--r--test/tc_newkeys.py5
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"