summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/core/actions.py112
-rw-r--r--ranger/defaults/keys.py25
-rw-r--r--ranger/ext/direction.py22
3 files changed, 106 insertions, 53 deletions
diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index b64ef316..d01397a7 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -18,6 +18,7 @@ import shutil
 from inspect import cleandoc
 
 import ranger
+from ranger.ext.direction import Direction
 from ranger.shared import EnvironmentAware, SettingsAware
 from ranger import fsobject
 from ranger.gui.widgets import console_mode as cmode
@@ -36,6 +37,29 @@ class Actions(EnvironmentAware, SettingsAware):
 
 	handle_mouse = resize = dummy
 
+	def move_left(self, narg=1):
+		"""Enter the parent directory"""
+		self.move(left=1, narg=narg)
+
+	def move_right(self, narg=None):
+		"""Enter the current directory or execute the current file"""
+		self.move(right=1, narg=narg)
+
+	def move_pointer(self, relative = 0, absolute = None, narg=None):
+		"""Move the pointer down by <relative> or to <absolute>"""
+		dct = dict(down=relative, narg=narg)
+		if absolute is not None:
+			dct['to'] = absolute
+		self.move(**dct)
+
+	def move_pointer_by_pages(self, relative):
+		"""Move the pointer down by <relative> pages"""
+		self.move(down=relative, pages=True)
+
+	def move_pointer_by_percentage(self, relative=0, absolute=None, narg=None):
+		"""Move the pointer down to <absolute>%"""
+		self.move(to=absolute, percentage=True, narg=narg)
+
 	# --------------------------
 	# -- Basic Commands
 	# --------------------------
@@ -95,48 +119,60 @@ class Actions(EnvironmentAware, SettingsAware):
 	# -- Moving Around
 	# --------------------------
 
-	def move_left(self, narg=1):
-		"""Enter the parent directory"""
-		try:
-			directory = os.path.join(*(['..'] * narg))
-		except:
-			return
-		self.env.enter_dir(directory)
-
-	def move_right(self, mode=0, narg=None):
-		"""Enter the current directory or execute the current file"""
-		cf = self.env.cf
-		sel = self.env.get_selection()
-
-		if isinstance(narg, int):
-			mode = narg
-		if not self.env.enter_dir(cf):
-			if sel:
-				if self.execute_file(sel, mode=mode) is False:
-					self.open_console(cmode.OPEN_QUICK)
-
-	def move_pointer(self, relative = 0, absolute = None, narg=None):
-		"""Move the pointer down by <relative> or to <absolute>"""
-		self.env.cwd.move(relative=relative,
-				absolute=absolute, narg=narg)
+	def move(self, narg=None, **kw):
+		"""
+		A universal movement method.
 
-	def move_pointer_by_pages(self, relative):
-		"""Move the pointer down by <relative> pages"""
-		self.env.cwd.move(relative=int(relative * self.env.termsize[0]))
+		Accepts these parameters:
+		(int) down, (int) up, (int) left, (int) right, (int) to,
+		(bool) absolute, (bool) relative, (bool) pages,
+		(bool) percentage
 
-	def move_pointer_by_percentage(self, relative=0, absolute=None, narg=None):
-		"""Move the pointer down by <relative>% or to <absolute>%"""
-		try:
-			factor = len(self.env.cwd) / 100.0
-		except:
-			return
+		to=X is translated to down=X, absolute=True
 
-		if narg is not None:
-			absolute = narg
+		Example:
+		self.move(down=4, pages=True)  # moves down by 4 pages.
+		self.move(to=2, pages=True)  # moves to page 2.
+		self.move(right=1, percentage=True)  # moves to 80%
+		"""
+		direction = Direction(kw)
+		if 'left' in direction:
+			steps = direction.left()
+			if narg is not None:
+				steps *= narg
+			try:
+				directory = os.path.join(*(['..'] * steps))
+			except:
+				return
+			self.env.enter_dir(directory)
+
+		elif 'right' in direction:
+			mode = direction.right()
+			if narg is not None:
+				mode = narg
+			cf = self.env.cf
+			selection = self.env.get_selection()
+			if not self.env.enter_dir(cf) and selection:
+				if self.execute_file(selection, mode=mode) is False:
+					self.open_console(cmode.OPEN_QUICK)
 
-		self.env.cwd.move(
-				relative=int(relative * factor),
-				absolute=int(absolute * factor))
+		elif direction.vertical():
+			if narg is not None:
+				if direction.absolute():
+					direction.set(narg)
+				else:
+					direction.multiply(narg)
+			if 'pages' in direction:
+				direction.multiply(self.env.termsize[0])
+			elif 'percentage' in direction:
+				factor = len(self.env.cwd) / 100.0
+				direction.multiply(factor)
+			dct = {}
+			if direction.absolute():
+				dct['absolute'] = int(direction.down())
+			else:
+				dct['relative'] = int(direction.down())
+			self.env.cwd.move(**dct)
 
 	def history_go(self, relative):
 		"""Move back and forth in the history"""
diff --git a/ranger/defaults/keys.py b/ranger/defaults/keys.py
index 2e0e1eb7..12b943c6 100644
--- a/ranger/defaults/keys.py
+++ b/ranger/defaults/keys.py
@@ -60,19 +60,18 @@ def initialize_commands(map):
 	_vimlike_aliases(map)
 	map.alias(KEY_LEFT, KEY_BACKSPACE, DEL)
 
-	map(KEY_DOWN, fm.move_pointer(relative=1))
-	map(KEY_UP, fm.move_pointer(relative=-1))
-	map(KEY_RIGHT, KEY_ENTER, ctrl('j'), fm.move_right())
-	map(KEY_LEFT, KEY_BACKSPACE, DEL, fm.move_left(1))
-
-	map(KEY_HOME, fm.move_pointer(absolute=0))
-	map(KEY_END, fm.move_pointer(absolute=-1))
-
-	map('%', fm.move_pointer_by_percentage(absolute=50))
-	map(KEY_NPAGE, ctrl('f'), fm.move_pointer_by_pages(1))
-	map(KEY_PPAGE, ctrl('b'), fm.move_pointer_by_pages(-1))
-	map(ctrl('d'), 'J', fm.move_pointer_by_pages(0.5))
-	map(ctrl('u'), 'K', fm.move_pointer_by_pages(-0.5))
+	map(KEY_DOWN, fm.move(down=1))
+	map(KEY_UP, fm.move(up=1))
+	map(KEY_RIGHT, KEY_ENTER, ctrl('j'), fm.move(right=1))
+	map(KEY_LEFT, KEY_BACKSPACE, DEL, fm.move(left=1))
+	map(KEY_HOME, fm.move(to=0))
+	map(KEY_END, fm.move(to=-1))
+
+	map('%', fm.move(to=50, percentage=True))
+	map(KEY_NPAGE, ctrl('f'), fm.move(down=1, pages=True))
+	map(KEY_PPAGE, ctrl('b'), fm.move(up=1, pages=True))
+	map(ctrl('d'), 'J', fm.move(down=0.5, pages=True))
+	map(ctrl('u'), 'K', fm.move(up=0.5, pages=True))
 
 	map(']', fm.traverse())
 	map('[', fm.history_go(-1))
diff --git a/ranger/ext/direction.py b/ranger/ext/direction.py
index 1cdaa97b..8be4fcaa 100644
--- a/ranger/ext/direction.py
+++ b/ranger/ext/direction.py
@@ -30,8 +30,14 @@ print(bool(d.horizontal())) # False, since no horizontal direction is defined
 class Direction(dict):
 	__doc__ = __doc__  # for nicer pydoc
 
-	def __init__(self, **keywords):
-		dict.__init__(self, keywords)
+	def __init__(self, dictionary=None, **keywords):
+		if dictionary is not None:
+			dict.__init__(self, dictionary)
+		else:
+			dict.__init__(self, keywords)
+		if 'to' in self:
+			self['down'] = self['to']
+			self['absolute'] = True
 
 	def copy(self):
 		return Direction(**self)
@@ -71,3 +77,15 @@ class Direction(dict):
 
 	def horizontal(self):
 		return set(self) & set(['left', 'right'])
+
+	def multiply(self, n):
+		for key in ('up', 'right', 'down', 'left'):
+			try:
+				self[key] *= n
+			except:
+				pass
+
+	def set(self, n):
+		for key in ('up', 'right', 'down', 'left'):
+			if key in self:
+				self[key] = n