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'])
/ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - 026assert.cc</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v1">
<meta name="syntax" content="cpp">
<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
<meta name="colorscheme" content="minimal">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
.traceContains { color: #008000; }
.cSpecial { color: #008000; }
.Constant { color: #00a0a0; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
.Identifier { color: #804000; }
-->
</style>

<script type='text/javascript'>
<!--

-->
</script>
</head>
<body>
<pre id='vimCodeElement'>
<span class="Delimiter">:(scenario assert)</span>
<span class="Special">% Hide_warnings = true;  // '%' lines insert arbitrary C code into tests before calling 'run' with the lines below. Must be immediately after :(scenario) line.</span>
recipe main [
  assert <span class="Constant">0</span>:literal<span class="Delimiter">,</span> [this is an assert in mu]
]
<span class="traceContains">+warn: this is an assert in mu</span>

<span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
ASSERT<span class="Delimiter">,</span>
<span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
Recipe_number[<span class="Constant">&quot;assert&quot;</span>] = ASSERT<span class="Delimiter">;</span>
<span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
case ASSERT: <span class="Delimiter">{</span>
  assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> == <span class="Constant">2</span><span class="Delimiter">);</span>
  assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
  if <span class="Delimiter">(</span>!ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
    assert<span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
    raise &lt;&lt; current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; die<span class="Delimiter">();</span>
  <span class="Delimiter">}</span>
  <span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->