summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/container/history.py21
-rw-r--r--ranger/core/actions.py2
-rw-r--r--ranger/defaults/commands.py2
-rw-r--r--ranger/defaults/options.py2
-rw-r--r--ranger/gui/widgets/console.py13
-rw-r--r--ranger/help/console.py24
-rw-r--r--test/tc_history.py19
7 files changed, 56 insertions, 27 deletions
diff --git a/ranger/container/history.py b/ranger/container/history.py
index ba13775d..5d4da07a 100644
--- a/ranger/container/history.py
+++ b/ranger/container/history.py
@@ -63,7 +63,7 @@ class History(object):
 			self.history_forward.appendleft( self.history.pop() )
 		return self.current()
 
-	def move(self, n):
+	def move(self, n, pattern=None):
 		if n > 0:
 			return self.forward()
 		if n < 0:
@@ -84,3 +84,22 @@ class History(object):
 		if self.history_forward:
 			self.history.extend(self.history_forward)
 			self.history_forward.clear()
+
+	def unique(self):
+		found = []
+		i = len(self.history)
+		while i:
+			i -= 1
+			item = self.history[i]
+			if item in found:
+				del self.history[i]
+			else:
+				found.append(item)
+		i = len(self.history_forward)
+		while i:
+			i -= 1
+			item = self.history_forward[i]
+			if item in found:
+				del self.history_forward[i]
+			else:
+				found.append(item)
diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index 6b8fc13c..d12d9c6c 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -86,7 +86,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 		self.ui.console.line = string
 		self.ui.console.execute()
 
-	def substitute_metachars(self, string):
+	def substitute_macros(self, string):
 		return _MacroTemplate(string).safe_substitute(self._get_macros())
 
 	def _get_macros(self):
diff --git a/ranger/defaults/commands.py b/ranger/defaults/commands.py
index 8005100c..b6e77697 100644
--- a/ranger/defaults/commands.py
+++ b/ranger/defaults/commands.py
@@ -117,7 +117,7 @@ class shell(Command):
 		if not command and 'p' in flags: command = 'cat %f'
 		if command:
 			if '%' in command:
-				command = self.fm.substitute_metachars(command)
+				command = self.fm.substitute_macros(command)
 			self.fm.execute_command(command, flags=flags)
 
 	def tab(self):
diff --git a/ranger/defaults/options.py b/ranger/defaults/options.py
index 23752d97..d3c420af 100644
--- a/ranger/defaults/options.py
+++ b/ranger/defaults/options.py
@@ -85,7 +85,7 @@ tilde_in_titlebar = True
 
 # How many directory-changes or console-commands should be kept in history?
 max_history_size = 20
-max_console_history_size = 20
+max_console_history_size = 50
 
 # Try to keep so much space between the top/bottom border when scrolling:
 scroll_offset = 8
diff --git a/ranger/gui/widgets/console.py b/ranger/gui/widgets/console.py
index 636073fc..2efb059d 100644
--- a/ranger/gui/widgets/console.py
+++ b/ranger/gui/widgets/console.py
@@ -34,6 +34,7 @@ import ranger
 class Console(Widget):
 	visible = False
 	last_cursor_mode = None
+	history_search_pattern = None
 	prompt = ':'
 	copy = ''
 	tab_deque = None
@@ -51,16 +52,16 @@ class Console(Widget):
 		if not ranger.arg.clean:
 			self.historypath = relpath_conf('history')
 			try:
-				f = open(path, 'r')
+				f = open(self.historypath, 'r')
 			except:
 				pass
 			else:
 				for line in f:
-					hist.add(line[:-1])
+					self.history.add(line[:-1])
 				f.close()
 
 	def destroy(self):
-		# save histories from files
+		# save history to files
 		if ranger.arg.clean or not self.settings.save_console_history:
 			return
 		if self.historypath:
@@ -69,7 +70,7 @@ class Console(Widget):
 			except:
 				pass
 			else:
-				for entry in self.histories[i]:
+				for entry in self.history:
 					f.write(entry + '\n')
 				f.close()
 
@@ -173,6 +174,7 @@ class Console(Widget):
 
 		self.pos += len(key)
 		self.on_line_change()
+		self.history_search_pattern = self.line
 
 	def history_move(self, n):
 		try:
@@ -182,7 +184,7 @@ class Console(Widget):
 		else:
 			if self.line != current and self.line != self.history.top():
 				self.history.modify(self.line)
-			self.history.move(n)
+			self.history.move(n, self.history_search_pattern)
 			current = self.history.current()
 			if self.line != current:
 				self.line = self.history.current()
@@ -191,6 +193,7 @@ class Console(Widget):
 	def add_to_history(self):
 		self.history.fast_forward()
 		self.history.modify(self.line)
+		self.history.unique()
 
 	def move(self, **keywords):
 		direction = Direction(keywords)
diff --git a/ranger/help/console.py b/ranger/help/console.py
index bc69f7fb..f03491db 100644
--- a/ranger/help/console.py
+++ b/ranger/help/console.py
@@ -139,29 +139,17 @@ done typing and executes the command right away.
 The key "f" opens the console with ":find "
 
 3.3.2. "shell"
-The shell command accepts flags |25?| as the first argument if it starts
-with a "-". Example: ":shell -p cat somefile.txt" will use the "p"-flag,
-which pipes the output to the pager.
-There are some keys which open the console with the shell command:
+The shell command accepts flags |25?| as the first argument. This example
+will use the "p"-flag, which pipes the output to the pager:
+	:shell -p cat somefile.txt
+
+There are some shortcuts which open the console with the shell command:
 	"!" opens ":shell "
 	"@" opens ":shell  %s"
 	"#" opens ":shell -p "
 
 3.3.3. "open_with"
-The open_with command opens the current file with the specified program,
-mode |24?| and flags |25?|. 
-The programs and the meaning of modes can be defined in the apps.py,
-giving you a high level interface for running files.
-Pressing "r" will open the console with ":open_with "
-
-Examples:
-
-:open_with mplayer D     open the selection in mplayer, but not detached
-:open_with 1             open it with the default handler in mode 1
-:open_with d             open it detached with the default handler
-:open_with p             open it as usual, but pipe the output to "less"
-:open_with totem 1 Ds    open in totem in mode 1, will not detach the
-                         process (flag D) but discard the output (flag s)
+The open_with command is explained in detail in chapter 2.2. |22?|
 
 ==============================================================================
 """
diff --git a/test/tc_history.py b/test/tc_history.py
index 33784e14..b1161f2a 100644
--- a/test/tc_history.py
+++ b/test/tc_history.py
@@ -54,4 +54,23 @@ class Test(TestCase):
 		self.assertEqual(4, hist.bottom())
 		self.assertEqual([4,5,6], list(hist))
 
+		hist.back()
+		hist.fast_forward()
+		self.assertEqual([4,5,6], list(hist))
+		hist.back()
+		hist.back()
+		hist.fast_forward()
+		self.assertEqual([4,5,6], list(hist))
+		hist.back()
+		hist.back()
+		hist.back()
+		hist.fast_forward()
+		self.assertEqual([4,5,6], list(hist))
+		hist.back()
+		hist.back()
+		hist.back()
+		hist.back()
+		hist.fast_forward()
+		self.assertEqual([4,5,6], list(hist))
+
 if __name__ == '__main__': main()