about summary refs log tree commit diff stats
path: root/ranger
diff options
context:
space:
mode:
authorhut <hut@lavabit.com>2010-04-09 01:29:09 +0200
committerhut <hut@lavabit.com>2010-04-09 01:29:09 +0200
commit93ecd88d9ad4231ab4926c2df43e00047900cd99 (patch)
tree7cb68934d7b280a71516e851f8a9ff4fe9423331 /ranger
parent4537ca72633b0c60e6fd4700adb6b96c0a823c7b (diff)
downloadranger-93ecd88d9ad4231ab4926c2df43e00047900cd99.tar.gz
partially fix tc_newkeys
Diffstat (limited to 'ranger')
-rw-r--r--ranger/container/keymap.py62
-rw-r--r--ranger/defaults/keys.py16
-rw-r--r--ranger/ext/tree.py1
3 files changed, 44 insertions, 35 deletions
diff --git a/ranger/container/keymap.py b/ranger/container/keymap.py
index 930800ff..29d6e629 100644
--- a/ranger/container/keymap.py
+++ b/ranger/container/keymap.py
@@ -14,6 +14,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import curses.ascii
+from collections import deque
 from string import ascii_lowercase
 from inspect import isfunction, getargspec
 from ranger.ext.tree import Tree
@@ -155,27 +156,28 @@ class KeyBuffer(object):
 		self.direction_keys = direction_keys
 
 	def add(self, key):
-		if self.failure:
-			return None
 		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 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 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 (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)
+			# evaluate direction keys {j,k,gg,pagedown,...}
+			if not self.eval_command:
+				self._do_eval_direction(key)
 
 	def _do_eval_direction(self, key):
 		try:
@@ -186,8 +188,8 @@ class KeyBuffer(object):
 		else:
 			self._direction_try_to_finish()
 
-	def _direction_try_to_finish(self, rec=MAX_ALIAS_RECURSION):
-		if rec <= 0:
+	def _direction_try_to_finish(self):
+		if self.max_alias_recursion <= 0:
 			self.failure = True
 			return None
 		match = self.dir_tree_pointer
@@ -197,12 +199,9 @@ class KeyBuffer(object):
 			match = self.dir_tree_pointer
 		if isinstance(self.dir_tree_pointer, Binding):
 			if match.alias:
-				try:
-					self.dir_tree_pointer = self.direction_keys[match.alias]
-					self._direction_try_to_finish(rec - 1)
-				except KeyError:
-					self.failure = True
-					return None
+				self.key_queue.extend(translate_keys(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:
@@ -232,11 +231,11 @@ class KeyBuffer(object):
 		try:
 			self.tree_pointer = self.tree_pointer[key]
 		except TypeError:
-			print(self.tree_pointer)
 			self.failure = True
 			return None
 		except KeyError:
 			try:
+				is_ascii_digit(key) or self.direction_keys._tree[key]
 				self.tree_pointer = self.tree_pointer[DIRKEY]
 			except KeyError:
 				try:
@@ -261,8 +260,8 @@ class KeyBuffer(object):
 					self.command = None
 			self._try_to_finish()
 
-	def _try_to_finish(self, rec=MAX_ALIAS_RECURSION):
-		if rec <= 0:
+	def _try_to_finish(self):
+		if self.max_alias_recursion <= 0:
 			self.failure = True
 			return None
 		assert isinstance(self.tree_pointer, (Binding, dict, KeyMap))
@@ -270,17 +269,15 @@ class KeyBuffer(object):
 			self.tree_pointer = self.tree_pointer._tree
 		if isinstance(self.tree_pointer, Binding):
 			if self.tree_pointer.alias:
-				try:
-					self.tree_pointer = self.keymap[self.tree_pointer.alias]
-					self._try_to_finish(rec - 1)
-				except KeyError:
-					self.failure = True
-					return None
+				self.key_queue.extend(translate_keys(self.tree_pointer.alias))
+				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
@@ -292,6 +289,8 @@ class KeyBuffer(object):
 		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
 
@@ -318,6 +317,7 @@ special_keys = {
 	'cr': ord("\n"),
 	'enter': ord("\n"),
 	'space': ord(" "),
+	'esc': curses.ascii.ESC,
 	'down': curses.KEY_DOWN,
 	'up': curses.KEY_UP,
 	'left': curses.KEY_LEFT,
diff --git a/ranger/defaults/keys.py b/ranger/defaults/keys.py
index 70521e1e..57a0d415 100644
--- a/ranger/defaults/keys.py
+++ b/ranger/defaults/keys.py
@@ -265,8 +265,6 @@ map('w', 'q', ESC, ctrl('d'), ctrl('c'),
 map = keymanager.get_context('console')
 map.merge(global_keys)
 map.merge(readline_aliases)
-map.unmap('Q')  # don't quit with Q in console, so we can type it
-map.unmap('<dir>')  # define my own direction keys
 
 map('<up>', wdg.history_move(-1))
 map('<down>', wdg.history_move(1))
@@ -274,7 +272,7 @@ map('<home>', wdg.move(right=0, absolute=True))
 map('<end>', wdg.move(right=-1, absolute=True))
 map('<tab>', wdg.tab())
 map('<s-tab>', wdg.tab(-1))
-map('<c-c>', wdg.close())
+map('<c-c>', '<esc>', wdg.close())
 map('<CR>', '<c-j>', wdg.execute())
 map('<F1>', lambda arg: arg.fm.display_command_help(arg.wdg))
 
@@ -285,14 +283,24 @@ map('<C-K>', wdg.delete_rest(1))
 map('<C-U>', wdg.delete_rest(-1))
 map('<C-Y>', wdg.paste())
 
-map('<any>')
+# Any key which is still undefined will simply be typed in.
+@map('<any>')
 def type_key(arg):
 	arg.wdg.type_key(arg.match)
 
+# Override some global keys so we can type them:
+override = ('Q', '%')
+for key in override:
+	map(key, wdg.type_key(key))
+
 
 # ===================================================================
 # == Define direction keys
 # ===================================================================
+# Note that direction keys point to no functions, but Direction objects.
+# Direction keys are completely independent and can not be merged into
+# other keymaps.  You can't define or unmap direction keys on
+# a per-context-basis, instead use aliases.
 map = keymanager.get_context('directions')
 map('<down>', dir=Direction(down=1))
 map('<up>', dir=Direction(down=-1))
diff --git a/ranger/ext/tree.py b/ranger/ext/tree.py
index 6d841c2a..a954136b 100644
--- a/ranger/ext/tree.py
+++ b/ranger/ext/tree.py
@@ -81,6 +81,7 @@ class Tree(object):
 			if first or isinstance(subtree, Tree) and subtree.empty():
 				top = chars.pop()
 				subtree = self.traverse(chars)
+				assert top in subtree._tree, "no such key: " + chr(top)
 				del subtree._tree[top]
 			else:
 				break