about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/commands.py4
-rw-r--r--ranger/defaults/keys.py17
-rw-r--r--ranger/gui/widgets/console.py42
-rw-r--r--ranger/gui/widgets/console_mode.py40
4 files changed, 76 insertions, 27 deletions
diff --git a/ranger/commands.py b/ranger/commands.py
index 66e43064..26c96e1b 100644
--- a/ranger/commands.py
+++ b/ranger/commands.py
@@ -1,5 +1,6 @@
 import os
 from ranger.shared import FileManagerAware
+from ranger.gui.widgets import console_mode as cmode
 
 # -------------------------------- helper classes
 
@@ -27,7 +28,6 @@ class parse(object):
 class Command(FileManagerAware):
 	"""Abstract command class"""
 	name = None
-	mode = ':'
 	line = ''
 	def __init__(self, line, mode):
 		self.line = line
@@ -126,7 +126,7 @@ class find(Command):
 	"""
 	count = 0
 	def execute(self):
-		if self.mode != '>':
+		if self.mode != cmode.COMMAND_QUICK:
 			self._search()
 
 		import re
diff --git a/ranger/defaults/keys.py b/ranger/defaults/keys.py
index faa85388..9837d2a2 100644
--- a/ranger/defaults/keys.py
+++ b/ranger/defaults/keys.py
@@ -3,6 +3,7 @@ from curses import *
 from curses.ascii import *
 from ranger import RANGERDIR
 from ranger import log
+from ranger.gui.widgets import console_mode as cmode
 from ranger.gui.widgets.console import Console
 from ranger.container.bookmarks import ALLOWED_KEYS as ALLOWED_BOOKMARK_KEYS
 
@@ -71,8 +72,8 @@ def initialize_commands(command_list):
 			fm.sort(reverse=not fm.settings.reverse))
 	command_list.hint(sort_hint, 'o', 'O')
 
-	bind('cd', do('open_console', ':', 'cd '))
-	bind('f', do('open_console', '>', 'find '))
+	bind('cd', do('open_console', cmode.COMMAND, 'cd '))
+	bind('f', do('open_console', cmode.COMMAND_QUICK, 'find '))
 
 	# key combinations which change the current directory
 	def cd(path):
@@ -104,12 +105,12 @@ def initialize_commands(command_list):
 	bind(ctrl('C'), do('interrupt'))
 	bind(KEY_RESIZE, do('resize'))
 	bind(KEY_MOUSE, do('handle_mouse'))
-	bind(':', do('open_console', ':'))
-	bind('>', do('open_console', '>'))
-	bind('/', do('open_console', '/'))
-	bind('?', do('open_console', '?'))
-	bind('!', do('open_console', '!'))
-	bind('r', do('open_console', '@'))
+	bind(':', do('open_console', cmode.COMMAND))
+	bind('>', do('open_console', cmode.COMMAND_QUICK))
+	bind('/', do('open_console', cmode.SEARCH))
+	bind('?', do('open_console', cmode.SEARCH))
+	bind('!', do('open_console', cmode.OPEN))
+	bind('r', do('open_console', cmode.OPEN_QUICK))
 
 
 	# definitions which require their own function:
diff --git a/ranger/gui/widgets/console.py b/ranger/gui/widgets/console.py
index 2a69ea85..75963829 100644
--- a/ranger/gui/widgets/console.py
+++ b/ranger/gui/widgets/console.py
@@ -1,7 +1,8 @@
 """The Console widget implements a vim-like console for entering
 commands, searching and executing files."""
 from . import Widget
-from ranger import commands
+from ranger import commands, log
+from ranger.gui.widgets.console_mode import is_valid_mode, mode_to_class
 import curses
 from collections import deque
 
@@ -50,12 +51,14 @@ class Console(Widget):
 			pass
 
 	def open(self, mode, string=''):
-		if mode not in self.mode_classes:
+		if not is_valid_mode(mode):
 			return False
 
+		cls = mode_to_class(mode)
+
 		self.last_cursor_mode = curses.curs_set(1)
 		self.mode = mode
-		self.__class__ = self.mode_classes[mode]
+		self.__class__ = cls
 		self.history = self.histories[DEFAULT_HISTORY]
 		self.init()
 		self.tab_deque = None
@@ -191,9 +194,12 @@ class Console(Widget):
 class CommandConsole(Console):
 	prompt = ':'
 
-	def execute(self):
-		cmd = self._get_cmd()
-		if cmd: cmd.execute()
+	def execute(self, cmd=None):
+		if cmd is None:
+			cmd = self._get_cmd()
+
+		if cmd:
+			cmd.execute()
 
 		Console.execute(self)
 	
@@ -241,11 +247,23 @@ class CommandConsole(Console):
 
 
 class QuickCommandConsole(CommandConsole):
+	"""
+	The QuickCommandConsole is essentially the same as the
+	CommandConsole, and includes one additional feature:
+	After each letter you type, it checks whether the command as it
+	stands there could be executed in a meaningful way, and if it does,
+	run it right away.
+
+	Example:
+	>cd ..
+	As you type the last dot, The console will recognize what you mean
+	and enter the parent directory saving you the time of pressing enter.
+	"""
 	prompt = '>'
 	def on_line_change(self):
 		cmd = self._get_cmd()
 		if cmd and cmd.quick_open():
-			self.execute()
+			self.execute(cmd)
 
 
 class SearchConsole(Console):
@@ -425,13 +443,3 @@ class QuickOpenConsole(Console):
 
 	def _is_mode(self, arg):
 		return all(x in '0123456789' for x in arg)
-
-
-Console.mode_classes = {
-		':': CommandConsole,
-		'>': QuickCommandConsole,
-		'!': OpenConsole,
-		'@': QuickOpenConsole,
-		'/': SearchConsole,
-		'?': SearchConsole,
-}
diff --git a/ranger/gui/widgets/console_mode.py b/ranger/gui/widgets/console_mode.py
new file mode 100644
index 00000000..333083c3
--- /dev/null
+++ b/ranger/gui/widgets/console_mode.py
@@ -0,0 +1,40 @@
+DEFAULT = 0
+COMMAND = 1
+COMMAND_QUICK = 2
+OPEN = 3
+OPEN_QUICK = 4
+SEARCH = 5
+
+def is_valid_mode(mode):
+	"""
+	Returns True or False depending on whether the mode is valid or not.
+	"""
+	return isinstance(mode, int) and mode >= 0 and mode <= 5
+
+def all_modes(mode):
+	"""
+	Returns a generator containing all valid modes.
+	"""
+	return range(6)
+
+def mode_to_class(mode):
+	"""
+	Associates modes with the actual classes
+	from ranger.gui.widgets.console.
+	"""
+	from .console import Console, CommandConsole, OpenConsole, \
+			QuickOpenConsole, QuickCommandConsole, SearchConsole
+
+	if mode == DEFAULT:
+		return Console
+	if mode == COMMAND:
+		return CommandConsole
+	if mode == OPEN:
+		return OpenConsole
+	if mode == OPEN_QUICK:
+		return QuickOpenConsole
+	if mode == COMMAND_QUICK:
+		return QuickCommandConsole
+	if mode == SEARCH:
+		return SearchConsole
+	raise ValueError