summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/container/keymap.py27
-rw-r--r--ranger/defaults/keys.py72
-rw-r--r--ranger/ext/tree.py4
-rw-r--r--ranger/gui/ui.py2
-rw-r--r--test/tc_newkeys.py14
5 files changed, 77 insertions, 42 deletions
diff --git a/ranger/container/keymap.py b/ranger/container/keymap.py
index e49da6ee..f9be5e95 100644
--- a/ranger/container/keymap.py
+++ b/ranger/container/keymap.py
@@ -66,6 +66,7 @@ class CommandArgs(object):
 		self.directions = keybuffer.directions
 		self.keys = str(keybuffer)
 		self.matches = keybuffer.matches
+		self.match = keybuffer.matches and keybuffer.matches[0] or None
 		self.binding = keybuffer.command
 
 	@staticmethod
@@ -88,6 +89,8 @@ class KeyMap(Tree):
 			return func
 		return decorator_function
 
+	__call__ = map
+
 	def add_binding(self, *keys, **actions):
 		assert keys
 		bind = Binding(keys, actions)
@@ -181,10 +184,13 @@ class KeyBuffer(object):
 			self.dir_tree_pointer = self.dir_tree_pointer._tree
 			match = self.dir_tree_pointer
 		if isinstance(self.dir_tree_pointer, Binding):
-			if 'alias' in match.actions:
-				self.dir_tree_pointer = self.direction_keys.traverse(
-					match.alias)
-				self._direction_try_to_finish(rec - 1)
+			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
 			else:
 				direction = match.actions['dir'] * self.direction_quant
 				self.directions.append(direction)
@@ -246,10 +252,13 @@ class KeyBuffer(object):
 		if isinstance(self.tree_pointer, KeyMap):
 			self.tree_pointer = self.tree_pointer._tree
 		if isinstance(self.tree_pointer, Binding):
-			if 'alias' in self.tree_pointer.actions:
-				self.tree_pointer = self.keymap.traverse(
-					translate_keys(self.tree_pointer.actions['alias']))
-				self._try_to_finish(rec - 1)
+			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
 			else:
 				self.command = self.tree_pointer
 				self.done = True
@@ -285,7 +294,7 @@ class KeyBuffer(object):
 special_keys = {
 	'dir': DIRKEY,
 	'any': ANYKEY,
-	'psv': PASSIVE_ACTION,
+	'bg': PASSIVE_ACTION,
 	'cr': ord("\n"),
 	'enter': ord("\n"),
 	'space': ord(" "),
diff --git a/ranger/defaults/keys.py b/ranger/defaults/keys.py
index aaa332b9..f2d93c58 100644
--- a/ranger/defaults/keys.py
+++ b/ranger/defaults/keys.py
@@ -36,6 +36,7 @@ Check ranger.keyapi for more information
 
 from ranger.api.keys import *
 
+
 def _vimlike_aliases(command_list):
 	bind, alias = make_abbreviations(command_list)
 
@@ -334,31 +335,43 @@ def _basic_movement(command_list):
 	bind(KEY_HOME, wdg.move(absolute=0))
 	bind(KEY_END, wdg.move(absolute=-1))
 
-def get_directions():
-	k = KeyMap()
-	map = k.map
 
+def base_directions():
+	map = KeyMap()
 	map('<down>', dir=Direction(down=1))
 	map('<up>', dir=Direction(down=-1))
 	map('<left>', dir=Direction(right=-1))
 	map('<right>', dir=Direction(right=1))
 
+	return map
+
+def vim():
+	map = KeyMap()
+	map.merge(base_directions())
 	map('j', alias='<down>')
 	map('k', alias='<up>')
 	map('h', alias='<left>')
 	map('l', alias='<right>')
-	return k
 
-def move(arg):
-	arg.fm.move_pointer(relative=arg.direction.down)
+	return map
+
+def system_keys():
+	map = KeyMap()
+	map('Q', fm.exit())
+	map('<mouse>', fm.handle_mouse())
+	map('<C-L>', fm.redraw_window())
+	map('<resize>', fm.resize())
+
+	return map
 
-def get_ui_keys():
-	k = KeyMap()
-	k.merge(system_keys())
-	map = k.map
+def browser_keys():
+	map = KeyMap()
+	map.merge(system_keys())
 
-	map('<dir>', move)
-	map('<C-c>', 'Q', fm.exit())
+	@map('<dir>')
+	def move(arg):
+		arg.fm.move_pointer(relative=arg.direction.down)
+	map(fm.exit(), 'Q')
 
 	# --------------------------------------------------------- history
 	map('H', fm.history_go(-1))
@@ -378,29 +391,38 @@ def get_ui_keys():
 	map('pp', fm.paste())
 	map('po', fm.paste(overwrite=True))
 	map('pl', fm.paste_symlink())
-	map('p<psv>', fm.notify('press //p// once again to confirm pasting' \
+	map('p<bg>', fm.notify('press //p// once again to confirm pasting' \
 			', or //l// to create symlinks'))
 
 	# ---------------------------------------------------- run programs
 	map('s', fm.execute_command(os.environ['SHELL']))
 	map('E', fm.edit_file())
-	map('term', fm.execute_command('x-terminal-emulator', flags='d'))
+	map('.term', fm.execute_command('x-terminal-emulator', flags='d'))
 	map('du', fm.execute_command('du --max-depth=1 -h | less'))
 
-	return k
+	map(':', ';', fm.open_console(cmode.COMMAND))
 
-def system_keys():
-	k = KeyMap()
-	k.map(fm.exit(), 'Q')
-	k.map(fm.handle_mouse(), '<mouse>')
-	k.map(fm.redraw_window(), '<C-L>')
-	k.map(fm.resize(), '<resize>')
-	return k
+	return map
+
+def console_keys():
+	map = KeyMap()
+	map.merge(system_keys())
+
+	@map('<any>')
+	def type_key(arg):
+		arg.wdg.type_key(arg.match)
+	
+	map('<up>', wdg.history_move(-1))
+	map('<down>', wdg.history_move(1))
+	map('<tab>', wdg.tab())
 
+#from pprint import pprint
+#pprint(browser_keys()._tree[106].__dict__)
+#raise SystemExit()
 
-ui_keys = get_ui_keys()
+ui_keys = browser_keys()
 taskview_keys = ui_keys
 pager_keys = ui_keys
 embedded_pager_keys = ui_keys
-console_keys = ui_keys
-directions = get_directions()
+console_keys = console_keys()
+directions = vim()
diff --git a/ranger/ext/tree.py b/ranger/ext/tree.py
index d7b08cd7..54505f06 100644
--- a/ranger/ext/tree.py
+++ b/ranger/ext/tree.py
@@ -36,7 +36,7 @@ class Tree(object):
 			newtree._tree = self._tree
 		return newtree
 
-	def merge(self, other, copy=True):
+	def merge(self, other, copy=False):
 		"""Merge another Tree into a copy of self"""
 		def deep_merge(branch, otherbranch):
 			assert isinstance(otherbranch, dict)
@@ -125,7 +125,7 @@ class Tree(object):
 			except TypeError:
 				raise KeyError("trying to enter leaf")
 			except KeyError:
-				raise KeyError(str(char) + " not in tree " + str(tree))
+				raise KeyError(repr(char) + " not in tree " + str(tree))
 		if isinstance(tree, dict):
 			return type(self)(tree, parent=last_tree, key=char)
 		else:
diff --git a/ranger/gui/ui.py b/ranger/gui/ui.py
index a972eca9..2b406113 100644
--- a/ranger/gui/ui.py
+++ b/ranger/gui/ui.py
@@ -36,7 +36,7 @@ class UI(DisplayableContainer):
 			self.fm = fm
 
 		if keymap is None:
-			self.keymap = self.settings.keys.ui_keys
+			self.keymap = self.settings.keys.browser_keys()
 		else:
 			self.keymap = keymap
 		self.win = curses.initscr()
diff --git a/test/tc_newkeys.py b/test/tc_newkeys.py
index 45ac4e33..a4d69805 100644
--- a/test/tc_newkeys.py
+++ b/test/tc_newkeys.py
@@ -51,7 +51,7 @@ class Test(PressTestCase):
 			return fnc
 
 		km.map('ppp', n(5))
-		km.map('pp<psv>', n(8))
+		km.map('pp<bg>', n(8))
 		km.map('pp<dir>', n(2))
 		directions.map('j', dir=Direction(down=1))
 
@@ -116,6 +116,7 @@ class Test(PressTestCase):
 		directions.map('j', dir=Direction(down=1))
 		directions.map('k', dir=Direction(down=-1))
 		directions.map('<CR>', alias='j')
+		directions.map('@', alias='<CR>')
 
 		base = KeyMap()
 		base.map('a<dir>', add_dirs)
@@ -130,7 +131,7 @@ class Test(PressTestCase):
 		other.map('c<dir>', add_dirs)
 		other.map('g', alias='f')
 
-		km = base.merge(other)
+		km = base.merge(other, copy=True)
 		kb = KeyBuffer(km, directions)
 
 		press = self._mkpress(kb, km)
@@ -142,6 +143,9 @@ class Test(PressTestCase):
 
 		self.assertEqual(5, press('f'))
 		self.assertEqual(5, press('g'))
+		self.assertEqual(press('c<CR>'), press('c@'))
+		self.assertEqual(press('c<CR>'), press('c@'))
+		self.assertEqual(press('c<CR>'), press('c@'))
 
 		for n in range(1, 50):
 			self.assertPressIncomplete(kb, 'y' * n)
@@ -205,19 +209,19 @@ class Test(PressTestCase):
 		# test 1
 		t = Tree('a')
 		u = Tree('b')
-		merged = t.merge(u)
+		merged = t.merge(u, copy=True)
 		self.assertEqual('b', merged._tree)
 
 		# test 2
 		t = Tree('a')
 		u = makeTreeA()
-		merged = t.merge(u)
+		merged = t.merge(u, copy=True)
 		self.assertEqual(u._tree, merged._tree)
 
 		# test 3
 		t = makeTreeA()
 		u = makeTreeB()
-		v = t.merge(u)
+		v = t.merge(u, copy=True)
 
 		self.assertEqual(0, v['aaaX'])
 		self.assertEqual(2, v['aaaY'])