summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorhut <hut@lavabit.com>2011-10-03 05:58:11 +0200
committerhut <hut@lavabit.com>2011-10-03 05:58:11 +0200
commit4bea11d661ee302257966bc9fc60c712b72f4e7d (patch)
tree892a9ceb7890a43fe0540584132d3ca99de81ec2
parentd07c8c124a084d3e4e2c2c34b86d199fc0387f7f (diff)
downloadranger-4bea11d661ee302257966bc9fc60c712b72f4e7d.tar.gz
defaults.commands: Added unmap command
-rw-r--r--ranger/core/main.py5
-rw-r--r--ranger/defaults/commands.py14
-rw-r--r--ranger/ext/keybindings.py36
3 files changed, 43 insertions, 12 deletions
diff --git a/ranger/core/main.py b/ranger/core/main.py
index 6595fbf2..bed5d82d 100644
--- a/ranger/core/main.py
+++ b/ranger/core/main.py
@@ -108,7 +108,10 @@ def main():
 		return error.args[0]
 	finally:
 		if crash_traceback:
-			filepath = fm.env.cf.path if fm.env.cf else "None"
+			try:
+				filepath = fm.env.cf.path if fm.env.cf else "None"
+			except:
+				filepath = "None"
 		try:
 			fm.ui.destroy()
 		except (AttributeError, NameError):
diff --git a/ranger/defaults/commands.py b/ranger/defaults/commands.py
index 870fd127..60e3279d 100644
--- a/ranger/defaults/commands.py
+++ b/ranger/defaults/commands.py
@@ -821,10 +821,22 @@ class copymap(Command):
 		if not self.arg(1) or not self.arg(2):
 			return self.notify("Not enough arguments", bad=True)
 
-		for arg in self.args[1:]:
+		for arg in self.args[2:]:
 			self.fm.env.keymaps.copy(self.context, self.arg(1), arg)
 
 
+class unmap(Command):
+	"""
+	:unmap <keys> [<keys2>, ...]
+	Remove the given mappings
+	"""
+	context = 'browser'
+
+	def execute(self):
+		for arg in self.args[1:]:
+			self.fm.env.keymaps.unbind(self.context, arg)
+
+
 class map_(Command):
 	"""
 	:map <keysequence> <command>
diff --git a/ranger/ext/keybindings.py b/ranger/ext/keybindings.py
index fba025f8..950cae1d 100644
--- a/ranger/ext/keybindings.py
+++ b/ranger/ext/keybindings.py
@@ -22,6 +22,20 @@ PY3 = sys.version > '3'
 
 digits = set(range(ord('0'), ord('9')+1))
 
+def _unbind_traverse(pointer, keys, pos=0):
+	if keys[pos] not in pointer:
+		return
+	if len(keys) > pos+1 and isinstance(pointer, dict):
+		_unbind_traverse(pointer[keys[pos]], keys, pos=pos+1)
+		if not pointer[keys[pos]]:
+			del pointer[keys[pos]]
+	elif len(keys) == pos+1:
+		try:
+			del pointer[keys[pos]]
+			keys.pop()
+		except:
+			pass
+
 class KeyMaps(dict):
 	def __init__(self, keybuffer=None):
 		dict.__init__(self)
@@ -34,14 +48,17 @@ class KeyMaps(dict):
 			self.used_keymap = keymap_name
 			self.keybuffer.clear()
 
-	def bind(self, context, keys, leaf):
+	def _clean_input(self, context, keys):
 		try:
 			pointer = self[context]
 		except:
 			self[context] = pointer = dict()
 		if PY3:
 			keys = keys.encode('utf-8').decode('latin-1')
-		keys = list(parse_keybinding(keys))
+		return list(parse_keybinding(keys)), pointer
+
+	def bind(self, context, keys, leaf):
+		keys, pointer = self._clean_input(context, keys)
 		if not keys:
 			return
 		last_key = keys[-1]
@@ -53,20 +70,19 @@ class KeyMaps(dict):
 		pointer[last_key] = leaf
 
 	def copy(self, context, source, target):
-		try:
-			pointer = self[context]
-		except:
-			self[context] = pointer = dict()
-		if PY3:
-			source = source.encode('utf-8').decode('latin-1')
-		source = list(parse_keybinding(source))
+		source, pointer = self._clean_input(context, source)
 		if not source:
 			return
-
 		for key in source:
 			pointer = pointer[key]
 		self.bind(context, target, copy.deepcopy(pointer))
 
+	def unbind(self, context, keys):
+		keys, pointer = self._clean_input(context, keys)
+		if not keys:
+			return
+		_unbind_traverse(pointer, keys)
+
 
 class KeyBuffer(object):
 	any_key             = ANYKEY