summary refs log tree commit diff stats
path: root/ranger/applications.py
diff options
context:
space:
mode:
Diffstat (limited to 'ranger/applications.py')
-rw-r--r--ranger/applications.py174
1 files changed, 106 insertions, 68 deletions
diff --git a/ranger/applications.py b/ranger/applications.py
index beefba9f..499e8b2c 100644
--- a/ranger/applications.py
+++ b/ranger/applications.py
@@ -9,6 +9,9 @@ An uppercase key ensures that a certain flag will not be used.
 
 import os, sys
 from ranger.ext.waitpid_no_intr import waitpid_no_intr
+from subprocess import Popen, PIPE
+
+devnull = open(os.devnull, 'a')
 
 ALLOWED_FLAGS = 'sdpSDP'
 
@@ -26,79 +29,114 @@ class Applications(object):
 
 	def all(self):
 		"""Returns a list with all application functions"""
-		return [x[4:] for x in self.__class__.__dict__ if x.startswith('app_')]
+		methods = self.__class__.__dict__
+		return [meth[4:] for meth in methods if meth.startswith('app_')]
 
-null = open(os.devnull, 'a')
+class AppContext(object):
+	def __init__(self, app='default', files=None, mode=0, flags='', fm=None,
+			stdout=None, stderr=None, stdin=None, shell=None,
+			wait=True, action=None):
 
-def run(*args, **kw):
-	"""Run files with the specified parameters"""
-	from subprocess import Popen
-	from subprocess import PIPE
+		if files is None:
+			self.files = []
+		else:
+			self.files = list(files)
 
-	flags, fm = kw['flags'], kw['fm']
-	for flag in flags:
-		if ord(flag) <= 90:
-			bad = flag + flag.lower()
-			flags = ''.join(c for c in flags if c not in bad)
+		try:
+			self.file = self.files[0]
+		except IndexError:
+			self.file = None
+
+		self.app = app
+		self.action = action
+		self.mode = mode
+		self.flags = flags
+		self.fm = fm
+		self.stdout = stdout
+		self.stderr = stderr
+		self.stdin = stdin
+		self.wait = wait
+
+		if shell is None:
+			self.shell = isinstance(action, str)
+		else:
+			self.shell = shell
+	
+	def __getitem__(self, key):
+		return self.files[key]
+	
+	def __iter__(self):
+		if self.files:
+			for f in self.files:
+				yield f.path
+	
+	def squash_flags(self):
+		for flag in self.flags:
+			if ord(flag) <= 90:
+				bad = flag + flag.lower()
+				self.flags = ''.join(c for c in self.flags if c not in bad)
+
+	def get_action(self, apps=None):
+		if apps is None and self.fm:
+			apps = self.fm.apps
+
+		if apps is None:
+			raise RuntimeError("AppContext has no source for applications!")
+
+		app = apps.get(self.app)
+		self.action = app(self)
+		self.shell = isinstance(self.action, str)
+	
+	def run(self):
+		self.squash_flags()
+		if self.action is None:
+			self.get_action()
 
-	args = map(str, args)
-	popen_kw = {}
-	popen_kw['stdout'] = sys.stderr
-	popen_kw['stderr'] = sys.stderr
+		# ---------------------------- determine keywords for Popen()
 
-	for word in ('shell', 'stdout', 'stdin', 'stderr'):
-		if word in kw:
-			popen_kw[word] = kw[word]
+		kw = {}
+		kw['stdout'] = sys.stderr
+		kw['stderr'] = sys.stderr
+		kw['args'] = self.action
 
-	if kw['stdin'] is not None:
-		popen_kw['stdin'] = kw['stdin']
+		for word in ('shell', 'stdout', 'stdin', 'stderr'):
+			if getattr(self, word) is not None:
+				kw[word] = getattr(self, word)
+
+		if 's' in self.flags or 'd' in self.flags:
+			kw['stdout'] = kw['stderr'] = kw['stdin'] = devnull
+
+		# --------------------------- run them
+		if 'p' in self.flags:
+			kw['stdout'] = PIPE
+			kw['stderr'] = PIPE
+			process1 = Popen(**kw)
+			process2 = run(app='pager', stdin=process1.stdout, fm=self.fm)
+			return process2
+
+		elif 'd' in self.flags:
+			process = Popen(**kw)
+			return process
 
-	if 's' in flags or 'd' in flags:
-		popen_kw['stdout'] = popen_kw['stderr'] = popen_kw['stdin'] = null
-	
-	if 'p' in flags:
-		popen_kw['stdout'] = PIPE
-		process1 = Popen(args, **popen_kw)
-		kw['stdin'] = process1.stdout
-		kw['files'] = ()
-		kw['flags'] = ''.join(f for f in kw['flags'] if f in 'd')
-		process2 = kw['apps'].app_pager(**kw)
-		return process2
-
-	if 'd' in flags:
-		process = Popen(args, **popen_kw)
-		return process
-
-	else:
-		if fm.ui:
-			fm.ui.suspend()
-		try:
-			p = Popen(args, **popen_kw)
-			waitpid_no_intr(p.pid)
-		finally:
-			if fm.ui:
-				fm.ui.initialize()
-		return p
-
-def spawn(command, fm=None, suspend=True, wait=True):
-	from subprocess import Popen, STDOUT
-	from ranger.ext.waitpid_no_intr import waitpid_no_intr
-
-	if suspend and fm and fm.ui:
-		fm.ui.suspend()
-
-	try:
-		if wait:
-			kw = {}
 		else:
-			kw = {'stdout':null, 'stderr':null, 'stdin':null}
-
-		if fm and fm.stderr_to_out:
-			if 'stderr' not in kw:
-				kw['stderr'] = STDOUT
-		process = Popen(command, shell=True, **kw)
-		if wait:
-			waitpid_no_intr(process.pid)
-	finally:
-		if suspend and fm and fm.ui:
-			fm.ui.initialize()
+			self._activate_ui(False)
+			try:
+				p = Popen(**kw)
+				if self.wait:
+					waitpid_no_intr(p.pid)
+			finally:
+				self._activate_ui(True)
+
+	def _activate_ui(self, boolean):
+		if self.fm and self.fm.ui:
+			if boolean:
+				self.fm.ui.initialize()
+			else:
+				self.fm.ui.suspend()
+
+def run(action=None, **kw):
+	app = AppContext(action=action, **kw)
+	return app.run()
+
+def tup(*args):
+	return tuple(args)