From d492db527bd0a610bef85682615de2c25d5145d6 Mon Sep 17 00:00:00 2001
From: hut <hut@lavabit.com>
Date: Tue, 13 Apr 2010 17:47:34 +0200
Subject: Started implementing dirarg

---
 ranger/api/keys.py     | 22 +++++++++++++++++-----
 ranger/core/actions.py | 16 +++++++++++-----
 2 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/ranger/api/keys.py b/ranger/api/keys.py
index d7a688b9..92a0269c 100644
--- a/ranger/api/keys.py
+++ b/ranger/api/keys.py
@@ -34,10 +34,11 @@ class Wrapper(object):
 			def function(command_argument):
 				args, kws = real_args, real_keywords
 				number = command_argument.n
+				direction = command_argument.direction
 				obj = getattr(command_argument, self.__firstattr__)
 				fnc = getattr(obj, attr)
-				if number is not None:
-					args, kws = replace_narg(number, fnc, args, kws)
+				if number is not None or direction is not None:
+					args, kws = replace_narg(number, direction, fnc, args, kws)
 				return fnc(*args, **kws)
 			return function
 		return wrapper
@@ -63,6 +64,7 @@ fm = Wrapper('fm')
 wdg = Wrapper('wdg')
 
 
+DIRARG_KEYWORD = 'dirarg'
 NARG_KEYWORD = 'narg'
 
 def narg(number_, function_, *args_, **keywords_):
@@ -78,7 +80,7 @@ def narg(number_, function_, *args_, **keywords_):
 	args, keywords = replace_narg(number_, function_, args_, keywords_)
 	return function_(*args, **keywords)
 
-def replace_narg(number, function, args, keywords):
+def replace_narg(number, direction, function, args, keywords):
 	"""
 	This function returns (args, keywords) with one little change:
 	if <function> has a named argument called "narg", args and keywords
@@ -93,10 +95,10 @@ def replace_narg(number, function, args, keywords):
 	=> (1, 666), {}
 	"""
 	argspec = getargspec(function).args
-	if NARG_KEYWORD in argspec:
+	args = list(args)
+	if number is not None and NARG_KEYWORD in argspec:
 		try:
 			# is narg in args?
-			args = list(args)
 			index = argspec.index(NARG_KEYWORD)
 			if ismethod(function):
 				index -= 1  # because of 'self'
@@ -105,4 +107,14 @@ def replace_narg(number, function, args, keywords):
 			# is narg in keywords?
 			keywords = dict(keywords)
 			keywords[NARG_KEYWORD] = number
+	if direction is not None and DIRARG_KEYWORD in argspec:
+		try:
+			index = argspec.index(DIRARG_KEYWORD)
+			if ismethod(function):
+				index -= 1  # because of 'self'
+			args[index] = direction
+		except (ValueError, IndexError):
+			# is narg in keywords?
+			keywords = dict(keywords)
+			keywords[DIRARG_KEYWORD] = direction
 	return args, keywords
diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index ac6cfc95..7b8d192d 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -542,16 +542,22 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 		self.env.cut = False
 		self.ui.browser.main_column.request_redraw()
 
-	def copy(self):
+	def copy(self, narg=None, dirarg=None):
 		"""Copy the selected items"""
-
-		selected = self.env.get_selection()
+		direction = Direction(dirarg or {})
+		selected = direction.select(
+				override=narg,
+				lst=self.env.cwd.files,
+				current=self.env.cwd.pointer,
+				pagesize=self.env.termsize[0])
+
+		selected = selected or self.env.get_selection()
 		self.env.copy = set(f for f in selected if f in self.env.cwd.files)
 		self.env.cut = False
 		self.ui.browser.main_column.request_redraw()
 
-	def cut(self):
-		self.copy()
+	def cut(self, narg=None, dirarg=None):
+		self.copy(narg=narg, dirarg=dirarg)
 		self.env.cut = True
 		self.ui.browser.main_column.request_redraw()
 
-- 
cgit 1.4.1-2-gfad0


From 447cbcd65588eafdb85b407750602c0fdd591ef4 Mon Sep 17 00:00:00 2001
From: hut <hut@lavabit.com>
Date: Tue, 13 Apr 2010 17:57:46 +0200
Subject: dirarg: added unit test and almost working implementaiton

---
 ranger/core/actions.py | 6 +++++-
 test/tc_direction.py   | 7 +++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index 7b8d192d..df623c77 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -545,7 +545,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 	def copy(self, narg=None, dirarg=None):
 		"""Copy the selected items"""
 		direction = Direction(dirarg or {})
-		selected = direction.select(
+		pos, selected = direction.select(
 				override=narg,
 				lst=self.env.cwd.files,
 				current=self.env.cwd.pointer,
@@ -553,7 +553,11 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 
 		selected = selected or self.env.get_selection()
 		self.env.copy = set(f for f in selected if f in self.env.cwd.files)
+		self.env.copy.add(self.env.cwd.pointed_obj)
 		self.env.cut = False
+		self.env.cwd.pointer = pos
+		self.env.cwd.correct_pointer()
+		self.env.copy.add(self.env.cwd.pointed_obj)
 		self.ui.browser.main_column.request_redraw()
 
 	def cut(self, narg=None, dirarg=None):
diff --git a/test/tc_direction.py b/test/tc_direction.py
index 18f9eb4c..124a7001 100644
--- a/test/tc_direction.py
+++ b/test/tc_direction.py
@@ -76,6 +76,13 @@ class TestDirections(unittest.TestCase):
 		d2 = Direction(absolute=True)
 		self.assertEqual(5, d2.move(direction=9, override=5))
 
+	def test_select(self):
+		d = Direction(down=3)
+		lst = list(range(100))
+		self.assertEqual((6, [3,4,5]), d.select(current=3, pagesize=10, override=None, lst=lst))
+		d = Direction(down=3, pages=True)
+		self.assertEqual((9, [3,4,5,6,7,8]), d.select(current=3, pagesize=2, override=None, lst=lst))
+
 if __name__ == '__main__':
 	unittest.main()
 
-- 
cgit 1.4.1-2-gfad0


From 661ab7a384bbff355c3ee44c824ba8205afc23f5 Mon Sep 17 00:00:00 2001
From: hut <hut@lavabit.com>
Date: Tue, 13 Apr 2010 19:32:11 +0200
Subject: dirarg: tmp

---
 ranger/core/actions.py | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index df623c77..929dec31 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -544,15 +544,16 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 
 	def copy(self, narg=None, dirarg=None):
 		"""Copy the selected items"""
+		cwd = self.env.cwd
 		direction = Direction(dirarg or {})
-		pos, selected = direction.select(
-				override=narg,
-				lst=self.env.cwd.files,
-				current=self.env.cwd.pointer,
-				pagesize=self.env.termsize[0])
-
-		selected = selected or self.env.get_selection()
-		self.env.copy = set(f for f in selected if f in self.env.cwd.files)
+		if direction.vertical():
+			pos, selected = direction.select(
+					override=narg, lst=cwd.files, current=currentpos,
+					pagesize=self.env.termsize[0])
+		else:
+			pos = currentpos + (narg or 0)
+			selected = (f for f in self.env.get_selection() if f in cwd.files)
+		self.env.copy = set(selected)
 		self.env.copy.add(self.env.cwd.pointed_obj)
 		self.env.cut = False
 		self.env.cwd.pointer = pos
-- 
cgit 1.4.1-2-gfad0


From 656c2bf6deb5dfbbd971880154f109ceb2be87c3 Mon Sep 17 00:00:00 2001
From: hut <hut@lavabit.com>
Date: Wed, 14 Apr 2010 00:39:48 +0200
Subject: dirarg: fully functioning now

---
 ranger/core/actions.py  | 31 ++++++++++++++++++-------------
 ranger/ext/direction.py |  4 +++-
 2 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index 929dec31..e8634099 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -545,20 +545,25 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 	def copy(self, narg=None, dirarg=None):
 		"""Copy the selected items"""
 		cwd = self.env.cwd
-		direction = Direction(dirarg or {})
-		if direction.vertical():
-			pos, selected = direction.select(
-					override=narg, lst=cwd.files, current=currentpos,
-					pagesize=self.env.termsize[0])
-		else:
-			pos = currentpos + (narg or 0)
+		if not narg and not dirarg:
 			selected = (f for f in self.env.get_selection() if f in cwd.files)
-		self.env.copy = set(selected)
-		self.env.copy.add(self.env.cwd.pointed_obj)
-		self.env.cut = False
-		self.env.cwd.pointer = pos
-		self.env.cwd.correct_pointer()
-		self.env.copy.add(self.env.cwd.pointed_obj)
+			self.env.copy = set(selected)
+			self.env.cut = False
+		else:
+			direction = Direction(dirarg or {})
+			offset = 0
+			if not direction.vertical():
+				direction = Direction(down=1)
+				offset = -1
+			pos, selected = direction.select(
+					override=narg, lst=cwd.files, current=cwd.pointer,
+					pagesize=self.env.termsize[0], offset=offset)
+			self.env.copy = set(selected)
+			self.env.copy.add(self.env.cwd.pointed_obj)
+			self.env.cut = False
+			self.env.cwd.pointer = pos
+			self.env.cwd.correct_pointer()
+			self.env.copy.add(self.env.cwd.pointed_obj)
 		self.ui.browser.main_column.request_redraw()
 
 	def cut(self, narg=None, dirarg=None):
diff --git a/ranger/ext/direction.py b/ranger/ext/direction.py
index f96ee90f..5a22d553 100644
--- a/ranger/ext/direction.py
+++ b/ranger/ext/direction.py
@@ -134,9 +134,11 @@ class Direction(dict):
 			pos += current
 		return int(max(min(pos, maximum + offset - 1), minimum))
 
-	def select(self, lst, override, current, pagesize):
+	def select(self, lst, override, current, pagesize, offset=0):
 		destination = self.move(direction=self.down(), override=override,
 			current=current, pagesize=pagesize, minimum=0, maximum=len(lst))
 		if destination > current:
+			destination += offset
 			return destination, lst[current:destination]
+		destination -= offset
 		return destination, lst[destination:current]
-- 
cgit 1.4.1-2-gfad0


From f99b82c1ae6fc7bc927ad0f216579162574d4fbe Mon Sep 17 00:00:00 2001
From: hut <hut@lavabit.com>
Date: Wed, 14 Apr 2010 00:43:10 +0200
Subject: dirarg: cleanup

---
 ranger/core/actions.py  | 5 +----
 ranger/ext/direction.py | 4 ++--
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index e8634099..15d0d017 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -548,7 +548,6 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 		if not narg and not dirarg:
 			selected = (f for f in self.env.get_selection() if f in cwd.files)
 			self.env.copy = set(selected)
-			self.env.cut = False
 		else:
 			direction = Direction(dirarg or {})
 			offset = 0
@@ -559,11 +558,9 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 					override=narg, lst=cwd.files, current=cwd.pointer,
 					pagesize=self.env.termsize[0], offset=offset)
 			self.env.copy = set(selected)
-			self.env.copy.add(self.env.cwd.pointed_obj)
-			self.env.cut = False
 			self.env.cwd.pointer = pos
 			self.env.cwd.correct_pointer()
-			self.env.copy.add(self.env.cwd.pointed_obj)
+		self.env.cut = False
 		self.ui.browser.main_column.request_redraw()
 
 	def cut(self, narg=None, dirarg=None):
diff --git a/ranger/ext/direction.py b/ranger/ext/direction.py
index 5a22d553..cefd32bc 100644
--- a/ranger/ext/direction.py
+++ b/ranger/ext/direction.py
@@ -139,6 +139,6 @@ class Direction(dict):
 			current=current, pagesize=pagesize, minimum=0, maximum=len(lst))
 		if destination > current:
 			destination += offset
-			return destination, lst[current:destination]
+			return destination, lst[current:destination + 1]
 		destination -= offset
-		return destination, lst[destination:current]
+		return destination, lst[destination:current + 1]
-- 
cgit 1.4.1-2-gfad0


From 3dd1793a9f60b318c73e1a0d5eade6349ad322fa Mon Sep 17 00:00:00 2001
From: hut <hut@lavabit.com>
Date: Wed, 14 Apr 2010 00:53:39 +0200
Subject: dirarg: improved

---
 ranger/core/actions.py  | 12 ++++++------
 ranger/ext/direction.py | 11 ++++-------
 2 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index 15d0d017..b320396a 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -547,19 +547,19 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 		cwd = self.env.cwd
 		if not narg and not dirarg:
 			selected = (f for f in self.env.get_selection() if f in cwd.files)
-			self.env.copy = set(selected)
 		else:
-			direction = Direction(dirarg or {})
-			offset = 0
-			if not direction.vertical():
+			if not dirarg and narg:
 				direction = Direction(down=1)
-				offset = -1
+				offset = 0
+			else:
+				direction = Direction(dirarg)
+				offset = 1
 			pos, selected = direction.select(
 					override=narg, lst=cwd.files, current=cwd.pointer,
 					pagesize=self.env.termsize[0], offset=offset)
-			self.env.copy = set(selected)
 			self.env.cwd.pointer = pos
 			self.env.cwd.correct_pointer()
+		self.env.copy = set(selected)
 		self.env.cut = False
 		self.ui.browser.main_column.request_redraw()
 
diff --git a/ranger/ext/direction.py b/ranger/ext/direction.py
index cefd32bc..b9fbcac9 100644
--- a/ranger/ext/direction.py
+++ b/ranger/ext/direction.py
@@ -134,11 +134,8 @@ class Direction(dict):
 			pos += current
 		return int(max(min(pos, maximum + offset - 1), minimum))
 
-	def select(self, lst, override, current, pagesize, offset=0):
-		destination = self.move(direction=self.down(), override=override,
+	def select(self, lst, override, current, pagesize, offset=1):
+		dest = self.move(direction=self.down(), override=override,
 			current=current, pagesize=pagesize, minimum=0, maximum=len(lst))
-		if destination > current:
-			destination += offset
-			return destination, lst[current:destination + 1]
-		destination -= offset
-		return destination, lst[destination:current + 1]
+		selection = lst[min(current, dest):max(current, dest) + offset]
+		return dest + offset - 1, selection
-- 
cgit 1.4.1-2-gfad0