summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/defaults/keys.py24
-rw-r--r--ranger/ext/direction.py31
-rw-r--r--ranger/ext/move.py23
-rw-r--r--ranger/gui/widgets/pager.py72
4 files changed, 71 insertions, 79 deletions
diff --git a/ranger/defaults/keys.py b/ranger/defaults/keys.py
index 7fbc7ce9..32e3e142 100644
--- a/ranger/defaults/keys.py
+++ b/ranger/defaults/keys.py
@@ -288,13 +288,13 @@ def _base_pager_commands(map):
 	_system_functions(map)
 
 	# -------------------------------------------------------- movement
-	map(KEY_LEFT, wdg.move_horizontal(relative=-4))
-	map(KEY_RIGHT, wdg.move_horizontal(relative=4))
-	map(KEY_NPAGE, ctrl('f'), wdg.move(relative=1, pages=True))
-	map(KEY_PPAGE, ctrl('b'), wdg.move(relative=-1, pages=True))
-	map(ctrl('d'), wdg.move(relative=0.5, pages=True))
-	map(ctrl('u'), wdg.move(relative=-0.5, pages=True))
-	map(' ', wdg.move(relative=0.8, pages=True))
+	map(KEY_LEFT, wdg.move(left=4))
+	map(KEY_RIGHT, wdg.move(right=4))
+	map(KEY_NPAGE, ctrl('f'), wdg.move(down=1, pages=True))
+	map(KEY_PPAGE, ctrl('b'), wdg.move(up=1, pages=True))
+	map(ctrl('d'), wdg.move(down=0.5, pages=True))
+	map(ctrl('u'), wdg.move(up=0.5, pages=True))
+	map(' ', wdg.move(down=0.8, pages=True))
 
 	# ---------------------------------------------------------- others
 	map('E', fm.edit_file())
@@ -313,7 +313,9 @@ def _system_functions(map):
 
 
 def _basic_movement(map):
-	map(KEY_DOWN, wdg.move(relative=1))
-	map(KEY_UP, wdg.move(relative=-1))
-	map(KEY_HOME, wdg.move(absolute=0))
-	map(KEY_END, wdg.move(absolute=-1))
+	map(KEY_DOWN, wdg.move(down=1))
+	map(KEY_UP, wdg.move(up=1))
+	map(KEY_RIGHT, wdg.move(right=1))
+	map(KEY_LEFT, wdg.move(left=1))
+	map(KEY_HOME, wdg.move(to=0))
+	map(KEY_END, wdg.move(to=-1))
diff --git a/ranger/ext/direction.py b/ranger/ext/direction.py
index 8be4fcaa..600476ff 100644
--- a/ranger/ext/direction.py
+++ b/ranger/ext/direction.py
@@ -72,12 +72,26 @@ class Direction(dict):
 	def relative(self):
 		return not Direction.absolute(self)
 
+	def vertical_direction(self):
+		down = Direction.down(self)
+		return (down > 0) - (down < 0)
+
+	def horizontal_direction(self):
+		right = Direction.right(self)
+		return (right > 0) - (right < 0)
+
 	def vertical(self):
 		return set(self) & set(['up', 'down'])
 
 	def horizontal(self):
 		return set(self) & set(['left', 'right'])
 
+	def pages(self):
+		return 'pages' in self and self['pages']
+
+	def percentage(self):
+		return 'percentage' in self and self['percentage']
+
 	def multiply(self, n):
 		for key in ('up', 'right', 'down', 'left'):
 			try:
@@ -89,3 +103,20 @@ class Direction(dict):
 		for key in ('up', 'right', 'down', 'left'):
 			if key in self:
 				self[key] = n
+
+	def move(self, direction, override, minimum, maximum,
+			current, pagesize=10, offset=0):
+		pos = direction
+		if override is not None:
+			if self.absolute():
+				pos = override
+			else:
+				pos *= override
+		if self.pages():
+			pos *= pagesize
+		if self.absolute():
+			if pos < minimum:
+				pos += maximum
+		else:
+			pos += current
+		return int(max(min(pos, maximum + offset), minimum))
diff --git a/ranger/ext/move.py b/ranger/ext/move.py
deleted file mode 100644
index 948adae6..00000000
--- a/ranger/ext/move.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2009, 2010  Roman Zimbelmann <romanz@lavabit.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-def move_between(current, minimum, maximum, relative=0, absolute=None):
-	i = current
-	if isinstance(absolute, int):
-		i = absolute
-	if isinstance(relative, int):
-		i += relative
-	i = max(minimum, min(maximum - 1, i))
-	return i
diff --git a/ranger/gui/widgets/pager.py b/ranger/gui/widgets/pager.py
index 2fc8ecda..34d01261 100644
--- a/ranger/gui/widgets/pager.py
+++ b/ranger/gui/widgets/pager.py
@@ -19,7 +19,7 @@ The pager displays text and allows you to scroll inside it.
 import re
 from . import Widget
 from ranger.container.commandlist import CommandList
-from ranger.ext.move import move_between
+from ranger.ext.direction import Direction
 
 BAR_REGEXP = re.compile(r'\|\d+\?\|')
 QUOTES_REGEXP = re.compile(r'"[^"]+?"')
@@ -116,50 +116,28 @@ class Pager(Widget):
 			if TITLE_REGEXP.match(line):
 				self.color_at(i, 0, -1, 'title', *baseclr)
 
-
-	def move(self, relative=0, absolute=None, pages=None, narg=None):
-		i = self.scroll_begin
-		if isinstance(absolute, int):
-			if isinstance(narg, int):
-				absolute = narg
-			if absolute < 0:
-				i = absolute + len(self.lines)
-			else:
-				i = absolute
-
-		if relative != 0:
-			if isinstance(pages, int):
-				relative *= pages * self.hei
-			if isinstance(narg, int):
-				relative *= narg
-		i = int(i + relative)
-
-		length = len(self.lines) - self.hei
-		if i >= length:
-			self._get_line(i+self.hei)
-
-		length = len(self.lines) - self.hei
-		if i >= length:
-			i = length
-
-		if i < 0:
-			i = 0
-
-		self.scroll_begin = i
-
-	def move_horizontal(self, relative=0, absolute=None, narg=None):
-		if narg is not None:
-			if absolute is None:
-				relative = relative < 0 and -narg or narg
-			else:
-				absolute = narg
-
-		self.startx = move_between(
-				current=self.startx,
-				minimum=0,
-				maximum=999,
-				relative=relative,
-				absolute=absolute)
+	def move(self, narg=None, **kw):
+		direction = Direction(kw)
+		if direction.horizontal():
+			self.startx = direction.move(
+					direction=direction.right(),
+					override=narg,
+					minimum=0,
+					maximum=self._get_max_width(),
+					current=self.startx,
+					pagesize=self.wid,
+					offset=-self.wid)
+		if direction.vertical():
+			if self.source_is_stream:
+				self._get_line(self.scroll_begin + self.hei * 2)
+			self.scroll_begin = direction.move(
+					direction=direction.down(),
+					override=narg,
+					minimum=0,
+					maximum=len(self.lines),
+					current=self.scroll_begin,
+					pagesize=self.hei,
+					offset=-self.hei)
 
 	def press(self, key):
 		try:
@@ -211,6 +189,7 @@ class Pager(Widget):
 		return True
 
 	def _get_line(self, n, attempt_to_read=True):
+		assert isinstance(n, int), n
 		try:
 			return self.lines[n]
 		except (KeyError, IndexError):
@@ -237,3 +216,6 @@ class Pager(Widget):
 			except IndexError:
 				raise StopIteration
 			i += 1
+
+	def _get_max_width(self):
+		return max(len(line) for line in self.lines)