diff options
author | hut <hut@lavabit.com> | 2010-01-23 01:47:15 +0100 |
---|---|---|
committer | hut <hut@lavabit.com> | 2010-01-23 01:47:15 +0100 |
commit | d46a05a856c417140e3fc2a9481fc67d6c8a66ba (patch) | |
tree | 39a02dac0cc5140c26264f07bec777c7b9cc9ad0 | |
parent | 2dc35a085a285a274a960c8a029d4e7bc8026aee (diff) | |
download | ranger-d46a05a856c417140e3fc2a9481fc67d6c8a66ba.tar.gz |
apps: more intelligent application choosing
ranger can now check whether an application is installed on the system and choose the best available application out of a list. ("either" method)
-rw-r--r-- | ranger/applications.py | 37 | ||||
-rw-r--r-- | ranger/defaults/apps.py | 33 | ||||
-rw-r--r-- | ranger/fm.py | 9 |
3 files changed, 73 insertions, 6 deletions
diff --git a/ranger/applications.py b/ranger/applications.py index 5f267a42..e5a5fc4e 100644 --- a/ranger/applications.py +++ b/ranger/applications.py @@ -19,12 +19,14 @@ This module faciliates starting of new processes. import os, sys from ranger.ext.waitpid_no_intr import waitpid_no_intr from subprocess import Popen, PIPE +from ranger.ext.iter_tools import flatten +from ranger.shared import FileManagerAware devnull = open(os.devnull, 'a') ALLOWED_FLAGS = 'sdpSDP' -class Applications(object): +class Applications(FileManagerAware): """ This class contains definitions on how to run programs and should be extended in ranger.defaults.apps @@ -59,6 +61,30 @@ class Applications(object): return ('vim', ) + tuple(context) """ + def _meets_dependencies(self, fnc): + try: + deps = fnc.dependencies + except AttributeError: + return True + + for dep in deps: + if hasattr(dep, 'dependencies') \ + and not self._meets_dependencies(dep): + return False + if dep not in self.fm.executables: + return False + + return True + + def either(self, context, *args): + for app in args: + try: + application_handler = getattr(self, 'app_' + app) + except AttributeError: + continue + if self._meets_dependencies(application_handler): + return application_handler(context) + def app_self(self, context): """Run the file itself""" return "./" + context.file.basename @@ -268,4 +294,11 @@ def tup(*args): is equivalent to: tup('a', *some_iterator) """ - return tuple(args) + return args + +def depends_on(*args): + args = tuple(flatten(args)) + def decorator(fnc): + fnc.dependencies = args + return fnc + return decorator diff --git a/ranger/defaults/apps.py b/ranger/defaults/apps.py index 5117a027..5c4174ab 100644 --- a/ranger/defaults/apps.py +++ b/ranger/defaults/apps.py @@ -12,6 +12,7 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +import os from re import compile, VERBOSE from ranger.applications import * @@ -27,7 +28,7 @@ class CustomApplications(Applications): if f.extension is not None: if f.extension in ('pdf'): - return self.app_apvlv(c) + return self.either(c, 'evince', 'apvlv') if f.extension in ('swc', 'smc'): return self.app_zsnes(c) @@ -41,7 +42,7 @@ class CustomApplications(Applications): if f.video or f.audio: if f.video: c.flags += 'd' - return self.app_mplayer(c) + return self.either(c, 'mplayer', 'totem') if f.image: return self.app_feh(c) @@ -53,22 +54,35 @@ class CustomApplications(Applications): def app_pager(self, c): return tup('less', *c) + @depends_on('vim') def app_vim(self, c): return tup('vim', *c) - app_editor = app_vim + def app_editor(self, c): + default_editor = os.environ['EDITOR'] + parts = default_editor.split() + exe_name = os.path.basename(parts[0]) + log(exe_name) + if exe_name in self.fm.executables: + return tuple(parts) + tuple(c) + + else: + return self.either(c, 'vim', 'emacs', 'nano') + + @depends_on(app_editor, Applications.app_self) def app_edit_or_run(self, c): if c.mode is 1: return self.app_self(c) return self.app_editor(c) + @depends_on('mplayer') def app_mplayer(self, c): if c.mode is 1: return tup('mplayer', *c) elif c.mode is 2: - args = "mplayer -fs -sid 0 -vfm ffmpeg -lavdopts" \ + args = "mplayer -fs -sid 0 -vfm ffmpeg -lavdopts " \ "lowres=1:fast:skiploopfilter=all:threads=8".split() args.extend(c) return tup(*args) @@ -79,6 +93,7 @@ class CustomApplications(Applications): else: return tup('mplayer', '-fs', *c) + @depends_on('feh') def app_feh(self, c): arg = {1: '--bg-scale', 2: '--bg-tile', 3: '--bg-center'} @@ -90,16 +105,19 @@ class CustomApplications(Applications): return tup('gimp', *c) return tup('feh', *c) + @depends_on('aunpack') def app_aunpack(self, c): if c.mode is 0: c.flags += 'p' return tup('aunpack', '-l', c.file.path) return tup('aunpack', c.file.path) + @depends_on('apvlv') def app_apvlv(self, c): c.flags += 'd' return tup('apvlv', *c) + @depends_on('make') def app_make(self, c): if c.mode is 0: return tup("make") @@ -108,12 +126,15 @@ class CustomApplications(Applications): if c.mode is 2: return tup("make", "clear") + @depends_on('firefox') def app_firefox(self, c): return tup("firefox") + @depends_on('javac') def app_javac(self, c): return tup("javac", *c) + @depends_on('java') def app_java(self, c): def strip_extensions(file): if '.' in file.basename: @@ -122,15 +143,19 @@ class CustomApplications(Applications): files_without_extensions = map(strip_extensions, c.files) return tup("java", files_without_extensions) + @depends_on('zsnes') def app_zsnes(self, c): return tup("zsnes", c.file) + @depends_on('evince') def app_evince(self, c): return tup("evince", *c) + @depends_on('wine') def app_wine(self, c): return tup("wine", c.file) + @depends_on('totem') def app_totem(self, c): if c.mode is 0: return tup("totem", "--fullscreen", *c) diff --git a/ranger/fm.py b/ranger/fm.py index 3471dcd4..7993a207 100644 --- a/ranger/fm.py +++ b/ranger/fm.py @@ -18,6 +18,7 @@ from collections import deque from ranger.actions import Actions from ranger.container import Bookmarks from ranger.ext.relpath import relpath_conf +from ranger.ext.get_executables import get_executables from ranger import __version__ from ranger.fsobject import Loader @@ -36,11 +37,19 @@ class FM(Actions): self.bookmarks = bookmarks self.tags = tags self.loader = Loader() + self._executables = None self.apps = self.settings.apps.CustomApplications() from ranger.shared import FileManagerAware FileManagerAware.fm = self + def get_executables(self): + if self._executables is None: + self._executables = get_executables() + return self._executables + + executables = property(get_executables) + def initialize(self): """If ui/bookmarks are None, they will be initialized here.""" from ranger.fsobject.directory import Directory |