summary refs log tree commit diff stats
path: root/ranger/commands.py
diff options
context:
space:
mode:
Diffstat (limited to 'ranger/commands.py')
-rw-r--r--ranger/commands.py99
1 files changed, 78 insertions, 21 deletions
diff --git a/ranger/commands.py b/ranger/commands.py
index e61e9fd8..a4ef2b22 100644
--- a/ranger/commands.py
+++ b/ranger/commands.py
@@ -1,10 +1,10 @@
 import os
-
 from ranger.shared import FileManagerAware
 
 # -------------------------------- helper classes
 
 class parse(object):
+	"""Parse commands and extract information"""
 	def __init__(self, line):
 		self.line = line
 		self.chunks = line.split()
@@ -14,13 +14,24 @@ class parse(object):
 		except ValueError:
 			self.firstpart = ''
 
+	def chunk(self, n, otherwise=''):
+		if len(self.chunks) >= n:
+			return self.chunks[n]
+		else:
+			return otherwise
+
+
 	def __add__(self, newpart):
 		return self.firstpart + newpart
 
 class Command(FileManagerAware):
+	"""Abstract command class"""
 	name = None
-	def __init__(self, line):
+	mode = ':'
+	line = ''
+	def __init__(self, line, mode):
 		self.line = line
+		self.mode = mode
 
 	def execute(self):
 		pass
@@ -28,12 +39,16 @@ class Command(FileManagerAware):
 	def tab(self):
 		pass
 
-	def _no_change(self):
-		return (self.line for i in range(100))
 
 # -------------------------------- definitions
 
 class cd(Command):
+	"""The cd command changes the directory. The command 'cd -' is
+equivalent to typing ``. In the quick console, the directory
+will be entered without the need to press enter, as soon as there
+is one unambiguous match.
+"""
+
 	def execute(self):
 		line = parse(self.line)
 		try:
@@ -84,6 +99,65 @@ class cd(Command):
 				return line + join(rel_dirname, dirnames[0]) + '/'
 
 			return (line + join(rel_dirname, dirname) for dirname in dirnames)
+	
+	def quick_open(self):
+		from os.path import isdir, join, normpath
+		line = parse(self.line)
+		pwd = self.fm.env.pwd.path
+
+		try:
+			rel_dest = line.chunks[1]
+		except IndexError:
+			return False
+
+		abs_dest = normpath(join(pwd, rel_dest))
+		return rel_dest != '.' and isdir(abs_dest)
+
+class find(Command):
+	"""The find command will attempt to find a partial, case insensitive
+match in the filenames of the current directory. In the quick command
+console, once there is one unambiguous match, the file will be run
+automatically.
+"""
+	count = 0
+	def execute(self):
+		if self.mode != '>':
+			self._search()
+
+		import re
+		search = parse(self.line).chunk(1)
+		search = re.escape(search)
+		self.fm.env.last_search = re.compile(search, re.IGNORECASE)
+
+	def quick_open(self):
+		self._search()
+		if self.count == 1:
+			self.fm.move_right()
+			self.fm.block_input(0.5)
+			return True
+
+	def _search(self):
+		self.count = 0
+		line = parse(self.line)
+		pwd = self.fm.env.pwd
+		try:
+			arg = line.chunks[1]
+		except IndexError:
+			return False
+		
+		length = len(pwd.files)
+		for i in range(length):
+			actual_index = (pwd.pointed_index + i) % length
+			filename = pwd.files[actual_index].basename_lower
+			if arg in filename:
+				self.count += 1
+				if self.count == 1:
+					pwd.move_pointer(absolute=actual_index)
+					self.fm.env.cf = pwd.pointed_file
+			if self.count > 1:
+				return False
+
+		return self.count == 1
 
 # -------------------------------- rest
 
@@ -94,20 +168,3 @@ for varname, var in vars().copy().items():
 			by_name[var.name or varname] = var
 	except TypeError:
 		pass
-
-def execute(name, line):
-	try:
-		command = by_name[name](line)
-	except KeyError:
-		pass
-	else:
-		command.execute()
-
-def tab(name, line):
-	try:
-		command = by_name[name](line)
-	except KeyError:
-		pass
-	else:
-		return command.tab()
-