diff options
author | hut <hut@lavabit.com> | 2010-04-12 12:25:23 +0200 |
---|---|---|
committer | hut <hut@lavabit.com> | 2010-04-12 12:25:23 +0200 |
commit | 3cc9e8aa5592d370a0d355584a3716765531a439 (patch) | |
tree | cf772515d0c97b058f5613a5aee69ce4f3111cef | |
parent | 00b627921c0a493e064501f444fa69e147bbb59d (diff) | |
parent | 1019737b2570cebd09a2cdff29642085aa6d062e (diff) | |
download | ranger-3cc9e8aa5592d370a0d355584a3716765531a439.tar.gz |
Merge branch 'master' into newkey
Conflicts: ranger/defaults/keys.py ranger/gui/widgets/console.py
-rw-r--r-- | ranger/api/apps.py | 7 | ||||
-rw-r--r-- | ranger/colorschemes/default.py | 3 | ||||
-rw-r--r-- | ranger/core/actions.py | 7 | ||||
-rw-r--r-- | ranger/core/fm.py | 6 | ||||
-rw-r--r-- | ranger/defaults/apps.py | 3 | ||||
-rw-r--r-- | ranger/defaults/keys.py | 1 | ||||
-rw-r--r-- | ranger/ext/get_all_modules.py | 23 | ||||
-rw-r--r-- | ranger/ext/get_executables.py | 33 | ||||
-rw-r--r-- | ranger/ext/waitpid_no_intr.py | 9 | ||||
-rw-r--r-- | ranger/fsobject/directory.py | 5 | ||||
-rw-r--r-- | ranger/gui/context.py | 2 | ||||
-rw-r--r-- | ranger/gui/widgets/browsercolumn.py | 3 | ||||
-rw-r--r-- | ranger/gui/widgets/browserview.py | 2 | ||||
-rw-r--r-- | ranger/gui/widgets/console.py | 9 | ||||
-rw-r--r-- | ranger/gui/widgets/statusbar.py | 11 |
15 files changed, 68 insertions, 56 deletions
diff --git a/ranger/api/apps.py b/ranger/api/apps.py index a17a6601..309c0db6 100644 --- a/ranger/api/apps.py +++ b/ranger/api/apps.py @@ -20,6 +20,7 @@ This module provides helper functions/classes for ranger.apps. import os, sys, re from subprocess import Popen, PIPE from ranger.ext.iter_tools import flatten +from ranger.ext.get_executables import get_executables from ranger.shared import FileManagerAware @@ -68,7 +69,7 @@ class Applications(FileManagerAware): if hasattr(dep, 'dependencies') \ and not self._meets_dependencies(dep): return False - if dep not in self.fm.executables: + if dep not in get_executables(): return False return True @@ -78,7 +79,7 @@ class Applications(FileManagerAware): try: application_handler = getattr(self, 'app_' + app) except AttributeError: - if app in self.fm.executables: + if app in get_executables(): return tup(app, *context) continue if self._meets_dependencies(application_handler): @@ -101,7 +102,7 @@ class Applications(FileManagerAware): try: handler = getattr(self, 'app_' + app) except AttributeError: - if app in self.fm.executables: + if app in get_executables(): return tup(app, *context) # generic app handler = self.app_default return handler(context) diff --git a/ranger/colorschemes/default.py b/ranger/colorschemes/default.py index 24f8ab91..ca8456e7 100644 --- a/ranger/colorschemes/default.py +++ b/ranger/colorschemes/default.py @@ -59,6 +59,9 @@ class Default(ColorScheme): fg = white else: fg = red + if not context.selected and (context.cut or context.copied): + fg = black + attr |= bold if context.main_column: if context.selected: attr |= bold diff --git a/ranger/core/actions.py b/ranger/core/actions.py index b0ec289f..a07b4ae0 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -538,16 +538,23 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): # -- File System Operations # -------------------------- + def uncut(self): + self.env.copy = set() + self.env.cut = False + self.ui.browser.main_column.request_redraw() + def copy(self): """Copy the selected items""" selected = self.env.get_selection() self.env.copy = set(f for f in selected if f in self.env.cwd.files) self.env.cut = False + self.ui.browser.main_column.request_redraw() def cut(self): self.copy() self.env.cut = True + self.ui.browser.main_column.request_redraw() def paste_symlink(self): from os import symlink, getcwd diff --git a/ranger/core/fm.py b/ranger/core/fm.py index ae815fbf..459620c6 100644 --- a/ranger/core/fm.py +++ b/ranger/core/fm.py @@ -50,7 +50,6 @@ class FM(Actions, SignalDispatcher): self.tabs = {} self.current_tab = 1 self.loader = Loader() - self._executables = None self.apps = self.settings.apps.CustomApplications() def mylogfunc(text): @@ -67,9 +66,8 @@ class FM(Actions, SignalDispatcher): @property def executables(self): - if self._executables is None: - self._executables = sorted(get_executables()) - return self._executables + """For compatibility. Calls get_executables()""" + return get_executables() def initialize(self): """If ui/bookmarks are None, they will be initialized here.""" diff --git a/ranger/defaults/apps.py b/ranger/defaults/apps.py index b3500c0d..45f2ace3 100644 --- a/ranger/defaults/apps.py +++ b/ranger/defaults/apps.py @@ -46,6 +46,7 @@ This example modifies the behaviour of "feh" and adds a custom media player: """ from ranger.api.apps import * +from ranger.ext.get_executables import get_executables INTERPRETED_LANGUAGES = re.compile(r''' ^(text|application)\/x-( @@ -103,7 +104,7 @@ class CustomApplications(Applications): else: parts = default_editor.split() exe_name = os.path.basename(parts[0]) - if exe_name in self.fm.executables: + if exe_name in get_executables(): return tuple(parts) + tuple(c) return self.either(c, 'vim', 'emacs', 'nano') diff --git a/ranger/defaults/keys.py b/ranger/defaults/keys.py index 81ebfea0..c181857e 100644 --- a/ranger/defaults/keys.py +++ b/ranger/defaults/keys.py @@ -133,6 +133,7 @@ map('V', fm.mark(all=True, val=False)) # ------------------------------------------ file system operations map('yy', 'y<dir>', fm.copy()) map('dd', 'd<dir>', fm.cut()) +map('ud', fm.uncut()) map('pp', fm.paste()) map('po', fm.paste(overwrite=True)) map('pl', fm.paste_symlink()) diff --git a/ranger/ext/get_all_modules.py b/ranger/ext/get_all_modules.py deleted file mode 100644 index 62c81437..00000000 --- a/ranger/ext/get_all_modules.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (C) 2009, 2010 Roman Zimbelmann <romanz@lavabit.com> -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -def get_all_modules(dirname): - """returns a list of strings containing the names of modules in a directory""" - import os - result = [] - for filename in os.listdir(dirname): - if filename.endswith('.py') and not filename.startswith('_'): - result.append(filename[0:filename.index('.')]) - return result diff --git a/ranger/ext/get_executables.py b/ranger/ext/get_executables.py index 9eeb3345..22c08eb9 100644 --- a/ranger/ext/get_executables.py +++ b/ranger/ext/get_executables.py @@ -13,12 +13,28 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -import stat -import os -from os.path import isfile, join, exists +from stat import S_IXOTH, S_IFREG from ranger.ext.iter_tools import unique +from os import listdir, environ, stat +from os.path import join -def get_executables(*paths): + +_cached_executables = None + + +def get_executables(): + """ + Return all executable files in each of the given directories. + + Looks in $PATH by default. + """ + global _cached_executables + if _cached_executables is None: + _cached_executables = sorted(get_executables_uncached()) + return _cached_executables + + +def get_executables_uncached(*paths): """ Return all executable files in each of the given directories. @@ -26,7 +42,7 @@ def get_executables(*paths): """ if not paths: try: - pathstring = os.environ['PATH'] + pathstring = environ['PATH'] except KeyError: return () paths = unique(pathstring.split(':')) @@ -34,15 +50,16 @@ def get_executables(*paths): executables = set() for path in paths: try: - content = os.listdir(path) + content = listdir(path) except: continue for item in content: abspath = join(path, item) try: - filestat = os.stat(abspath) + filestat = stat(abspath) except: continue - if filestat.st_mode & (stat.S_IXOTH | stat.S_IFREG): + if filestat.st_mode & (S_IXOTH | S_IFREG): executables.add(item) return executables + diff --git a/ranger/ext/waitpid_no_intr.py b/ranger/ext/waitpid_no_intr.py index c14fa5b9..12fbcbce 100644 --- a/ranger/ext/waitpid_no_intr.py +++ b/ranger/ext/waitpid_no_intr.py @@ -13,17 +13,18 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +from errno import EINTR +from os import waitpid + def waitpid_no_intr(pid): """catch interrupts which occur while using os.waitpid""" - import os, errno - while True: try: - return os.waitpid(pid, 0) + return waitpid(pid, 0) except KeyboardInterrupt: continue except OSError as e: - if e.errno == errno.EINTR: + if e.errno == EINTR: continue else: raise diff --git a/ranger/fsobject/directory.py b/ranger/fsobject/directory.py index bf626004..3574f329 100644 --- a/ranger/fsobject/directory.py +++ b/ranger/fsobject/directory.py @@ -237,6 +237,7 @@ class Directory(FileSystemObject, Accumulator, SettingsAware): Loads the contents of the directory. Use this sparingly since it takes rather long. """ + self.content_outdated = False if not self.loading: self.load_once() @@ -370,8 +371,7 @@ class Directory(FileSystemObject, Accumulator, SettingsAware): if self.load_content_once(*a, **k): return True - if self.content_outdated: - self.content_outdated = False + if self.files is None or self.content_outdated: self.load_content(*a, **k) return True @@ -403,6 +403,7 @@ class Directory(FileSystemObject, Accumulator, SettingsAware): """The number of containing files""" if not self.accessible or not self.content_loaded: raise ranger.fsobject.NotLoadedYet() + assert self.files is not None return len(self.files) def __eq__(self, other): diff --git a/ranger/gui/context.py b/ranger/gui/context.py index 4ea50714..d4c1c94d 100644 --- a/ranger/gui/context.py +++ b/ranger/gui/context.py @@ -23,7 +23,7 @@ CONTEXT_KEYS = ['reset', 'error', 'good', 'bad', 'space', 'permissions', 'owner', 'group', 'mtime', 'nlink', 'scroll', 'all', 'bot', 'top', 'percentage', - 'marked', 'tagged', 'tag_marker', + 'marked', 'tagged', 'tag_marker', 'cut', 'copied', 'help_markup', 'seperator', 'key', 'special', 'border', 'title', 'text', 'highlight', 'bars', 'quotes', 'tab', diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index 4e93ed3e..8cf8990c 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -281,6 +281,9 @@ class BrowserColumn(Pager): if stat.S_ISSOCK(mode): this_color.append('socket') + if self.env.copy and drawn in self.env.copy: + this_color.append('cut' if self.env.cut else 'copied') + if drawn.islink: this_color.append('link') this_color.append(drawn.exists and 'good' or 'bad') diff --git a/ranger/gui/widgets/browserview.py b/ranger/gui/widgets/browserview.py index 1995b714..466e23eb 100644 --- a/ranger/gui/widgets/browserview.py +++ b/ranger/gui/widgets/browserview.py @@ -264,7 +264,7 @@ class BrowserView(Widget, DisplayableContainer): def poke(self): DisplayableContainer.poke(self) if self.settings.collapse_preview and self.preview: - has_preview = self.columns[-2].has_preview() + has_preview = self.columns[-1].has_preview() if self.preview_available != has_preview: self.preview_available = has_preview self.resize(self.y, self.x, self.hei, self.wid) diff --git a/ranger/gui/widgets/console.py b/ranger/gui/widgets/console.py index 0e949d3b..a27e1956 100644 --- a/ranger/gui/widgets/console.py +++ b/ranger/gui/widgets/console.py @@ -27,8 +27,9 @@ from ranger.defaults import commands from ranger.gui.widgets.console_mode import is_valid_mode, mode_to_class from ranger import log, relpath_conf from ranger.ext.shell_escape import shell_quote -from ranger.ext.direction import Direction from ranger.container.keymap import CommandArgs +from ranger.ext.get_executables import get_executables +from ranger.ext.direction import Direction import ranger DEFAULT_HISTORY = 0 @@ -443,8 +444,8 @@ class OpenConsole(ConsoleWithTab): try: position_of_last_space = line.rindex(" ") except ValueError: - return (start + program + ' ' for program in self.fm.executables \ - if program.startswith(line)) + return (start + program + ' ' for program \ + in get_executables() if program.startswith(line)) if position_of_last_space == len(line) - 1: return self.line + '%s ' else: @@ -613,7 +614,7 @@ class QuickOpenConsole(ConsoleWithTab): def _is_app(self, arg): return self.fm.apps.has(arg) or \ - (not self._is_flags(arg) and arg in self.fm.executables) + (not self._is_flags(arg) and arg in get_executables()) def _is_flags(self, arg): from ranger.core.runner import ALLOWED_FLAGS diff --git a/ranger/gui/widgets/statusbar.py b/ranger/gui/widgets/statusbar.py index 75fbbe89..78666a3d 100644 --- a/ranger/gui/widgets/statusbar.py +++ b/ranger/gui/widgets/statusbar.py @@ -146,10 +146,9 @@ class StatusBar(Widget): else: target = self.env.at_level(0).pointed_obj - if target is None: - return - - if target.accessible is False: + if target is None \ + or not target.accessible \ + or (target.is_directory and target.files is None): return perms = target.get_permission_string() @@ -208,7 +207,9 @@ class StatusBar(Widget): if target is None: return - if not target.content_loaded or not target.accessible: + if target is None \ + or not target.accessible \ + or (target.is_directory and target.files is None): return pos = target.scroll_begin |