summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/commands.py44
-rw-r--r--ranger/ext/command_parser.py51
2 files changed, 61 insertions, 34 deletions
diff --git a/ranger/commands.py b/ranger/commands.py
index 26c96e1b..a3cc131e 100644
--- a/ranger/commands.py
+++ b/ranger/commands.py
@@ -1,47 +1,23 @@
 import os
 from ranger.shared import FileManagerAware
 from ranger.gui.widgets import console_mode as cmode
-
-# -------------------------------- helper classes
-
-class parse(object):
-	"""Parse commands and extract information"""
-	def __init__(self, line):
-		self.line = line
-		self.chunks = line.split()
-
-		try:
-			self.firstpart = line[:line.rindex(' ') + 1]
-		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
+from ranger.ext.command_parser import LazyParser as parse
 
 class Command(FileManagerAware):
 	"""Abstract command class"""
 	name = None
-	line = ''
 	def __init__(self, line, mode):
 		self.line = line
 		self.mode = mode
 
 	def execute(self):
-		pass
+		"""Override this"""
 
 	def tab(self):
-		pass
+		"""Override this"""
 
 	def quick_open(self):
-		pass
-
+		"""Override this"""
 
 # -------------------------------- definitions
 
@@ -56,7 +32,7 @@ class cd(Command):
 	def execute(self):
 		line = parse(self.line)
 		try:
-			destination = line.chunks[1]
+			destination = line.rest(1)
 		except IndexError:
 			destination = '~'
 
@@ -72,7 +48,7 @@ class cd(Command):
 		pwd = self.fm.env.pwd.path
 
 		try:
-			rel_dest = line.chunks[1]
+			rel_dest = line.rest(1)
 		except IndexError:
 			rel_dest = ''
 
@@ -110,7 +86,7 @@ class cd(Command):
 		pwd = self.fm.env.pwd.path
 
 		try:
-			rel_dest = line.chunks[1]
+			rel_dest = line.rest(1)
 		except IndexError:
 			return False
 
@@ -130,7 +106,7 @@ class find(Command):
 			self._search()
 
 		import re
-		search = parse(self.line).chunk(1)
+		search = parse(self.line).rest(1)
 		search = re.escape(search)
 		self.fm.env.last_search = re.compile(search, re.IGNORECASE)
 
@@ -146,7 +122,7 @@ class find(Command):
 		line = parse(self.line)
 		pwd = self.fm.env.pwd
 		try:
-			arg = line.chunks[1]
+			arg = line.rest(1)
 		except IndexError:
 			return False
 		
@@ -180,7 +156,7 @@ class mkdir(Command):
 	def execute(self):
 		line = parse(self.line)
 		try:
-			self.fm.mkdir(line.chunks[1])
+			self.fm.mkdir(line.rest(1))
 		except IndexError:
 			pass
 
diff --git a/ranger/ext/command_parser.py b/ranger/ext/command_parser.py
new file mode 100644
index 00000000..432f0364
--- /dev/null
+++ b/ranger/ext/command_parser.py
@@ -0,0 +1,51 @@
+class LazyParser(object):
+	"""Parse commands and extract information"""
+	def __init__(self, line):
+		self.line = line
+		self._chunks = None
+		self._rests = None
+		self._rests_loaded = 0
+		self._rests_gen_instance = None
+
+		try:
+			self.firstpart = line[:line.rindex(' ') + 1]
+		except ValueError:
+			self.firstpart = ''
+
+	def chunk(self, n, otherwise=''):
+		"""Chunks are pieces of the command seperated by spaces"""
+		if self._chunks is None:
+			self._chunks = line.split()
+
+		if len(self._chunks) > n:
+			return self._chunks[n]
+		else:
+			return otherwise
+
+	def rest(self, n, otherwise=''):
+		"""Rests are the strings which come after each word."""
+		if self._rests is None:
+			self._rests = list(self._rest_generator())
+			# TODO: Don't calculate all the rest elements if not needed
+
+		if len(self._rests) > n:
+			return self._rests[n]
+		else:
+			return otherwise
+
+	def _rest_generator(self):
+		lastrest = self.line
+		n = 0
+		while n < len(lastrest):
+			if lastrest[n] == ' ':
+				n += 1
+			else:
+				yield lastrest[n:]
+				n = lastrest.find(' ', n) + 1
+				if n <= 0:
+					break
+				lastrest = lastrest[n:]
+				n = 0
+
+	def __add__(self, newpart):
+		return self.firstpart + newpart
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375