From c82e1c27a1033b3d7cbe3dddcfeed126e2632c5f Mon Sep 17 00:00:00 2001 From: hut Date: Fri, 16 Apr 2010 22:00:53 +0200 Subject: fsobject: lazy calculation of infostring --- ranger/core/environment.py | 4 ++++ ranger/fsobject/directory.py | 8 ++++++-- ranger/fsobject/fsobject.py | 47 ++++++++++++++++++++++---------------------- 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/ranger/core/environment.py b/ranger/core/environment.py index e5deda07..49d92502 100644 --- a/ranger/core/environment.py +++ b/ranger/core/environment.py @@ -190,6 +190,10 @@ class Environment(SettingsAware, SignalDispatcher): self.cwd = new_cwd self.cwd.load_content_if_outdated() + if self.cwd.files: + for dir in self.cwd.files: + if dir.is_directory and dir.infostring == 'unknown': + dir.determine_infostring() # build the pathway, a tuple of directory objects which lie # on the path to the current directory. diff --git a/ranger/fsobject/directory.py b/ranger/fsobject/directory.py index 29f0042c..1c8355cd 100644 --- a/ranger/fsobject/directory.py +++ b/ranger/fsobject/directory.py @@ -199,9 +199,13 @@ class Directory(FileSystemObject, Accumulator, SettingsAware): self.scroll_offset = 0 self.filenames = filenames - self.infostring = ' %d' % len(self.filenames) # update the infostring self.files = files + if self == self.fm.env.cwd: + for dir in self.files: + if dir.is_directory and dir.infostring == 'unknown': + dir.determine_infostring() + self._clear_marked_items() for item in self.files: if item.path in marked_paths: @@ -219,8 +223,8 @@ class Directory(FileSystemObject, Accumulator, SettingsAware): else: self.filenames = None self.files = None - self.infostring = BAD_INFO + self.determine_infostring() self.cycle_list = None self.content_loaded = True self.last_update_time = time() diff --git a/ranger/fsobject/fsobject.py b/ranger/fsobject/fsobject.py index 94729b9a..4ebec3bc 100644 --- a/ranger/fsobject/fsobject.py +++ b/ranger/fsobject/fsobject.py @@ -156,6 +156,29 @@ class FileSystemObject(MimeTypeAware, FileManagerAware): """Called by directory.mark_item() and similar functions""" self.marked = bool(boolean) + def determine_infostring(self): + if self.is_device: + self.infostring = 'dev' + elif self.is_fifo: + self.infostring = 'fifo' + elif self.is_socket: + self.infostring = 'sock' + elif self.is_link: + self.infostring = '->' + elif self.is_directory: + try: + self.size = len(os.listdir(self.path)) + self.infostring = " %d" % self.size + self.accessible = True + self.runnable = True + except OSError: + self.size = 0 + self.infostring = BAD_INFO + self.accessible = False + elif self.is_file: + self.size = self.stat.st_size + self.infostring = ' ' + human_readable(self.size) + def load(self): """ reads useful information about the filesystem-object from the @@ -188,40 +211,18 @@ class FileSystemObject(MimeTypeAware, FileManagerAware): if self.accessible and os.access(self.path, os.F_OK): self.exists = True self.accessible = True - if os.path.isdir(self.path): self.type = T_DIRECTORY - try: - self.size = len(os.listdir(self.path)) - self.infostring = ' %d' % self.size - self.runnable = True - except OSError: - self.infostring = BAD_INFO - self.runnable = False - self.accessible = False elif os.path.isfile(self.path): self.type = T_FILE - self.size = self.stat.st_size - self.infostring = ' ' + human_readable(self.stat.st_size) else: self.type = T_UNKNOWN - if self.is_device: - self.infostring = 'dev' - elif self.is_fifo: - self.infostring = 'fifo' - elif self.is_socket: - self.infostring = 'sock' - else: - self.infostring = BAD_INFO else: - if self.is_link: - self.infostring = '->' - else: - self.infostring = None self.type = T_NONEXISTANT self.exists = False self.runnable = False + self.determine_infostring() def get_permission_string(self): if self.permissions is not None: -- cgit 1.4.1-2-gfad0 From 5588ccbab5cb30fb65a2f8e4aa4499d1567cf6ee Mon Sep 17 00:00:00 2001 From: hut Date: Sat, 17 Apr 2010 14:05:15 +0200 Subject: help.starting: updated --- ranger/help/starting.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ranger/help/starting.py b/ranger/help/starting.py index 29921ffc..88f90184 100644 --- a/ranger/help/starting.py +++ b/ranger/help/starting.py @@ -66,7 +66,8 @@ in the class CustomApplications which starts with "app_" can be used as a program in the "open with" prompt. You're encouraged to add your own program definitions to the list. Refer to -documentation in ranger/applications.py for more information on this subject. +the existing examples in the apps.py, it should be easy to adapt it for your +purposes. ============================================================================== @@ -75,8 +76,8 @@ documentation in ranger/applications.py for more information on this subject. Sometimes there are multiple variants to open a file. For example, ranger gives you 2 ways of opening a video (by default): - 0 fullscreen - 1 windowed + 0 windowed + 1 fullscreen By specifying a mode, you can select one of those. The "l" key will start a file in mode 0. "4l" will start the file in mode 4 etc. @@ -92,7 +93,7 @@ For a list of all programs and modes, see ranger/defaults/apps.py Flags give you a way to modify the behaviour of the spawned process. s Silent mode. Output will be discarded. - d Detach the process. + d Detach the process. (Run in background) p Redirect output to the pager For example, "open with: p" will pipe the output of that process into -- cgit 1.4.1-2-gfad0 From 0abb72df8f740d4e9504f91f5d3657ed8712ce3f Mon Sep 17 00:00:00 2001 From: hut Date: Sat, 17 Apr 2010 19:13:21 +0200 Subject: Added option "show_hidden_bookmarks" --- ranger/defaults/options.py | 3 +++ ranger/gui/widgets/browserview.py | 2 +- ranger/shared/settings.py | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ranger/defaults/options.py b/ranger/defaults/options.py index a9dd8bde..43129652 100644 --- a/ranger/defaults/options.py +++ b/ranger/defaults/options.py @@ -39,6 +39,9 @@ hidden_filter = regexp( r'lost\+found|^\.|~$|\.(:?pyc|pyo|bak|swp)$') show_hidden = False +# Show dotfiles in the bookmark preview box? +show_hidden_bookmarks = True + # Which colorscheme to use? These colorschemes are available by default: # default, default88, texas, jungle, snow # Snow is monochrome, texas and default88 use 88 colors. diff --git a/ranger/gui/widgets/browserview.py b/ranger/gui/widgets/browserview.py index 7f2ea5fb..f586596e 100644 --- a/ranger/gui/widgets/browserview.py +++ b/ranger/gui/widgets/browserview.py @@ -121,7 +121,7 @@ class BrowserView(Widget, DisplayableContainer): self.need_clear = True sorted_bookmarks = sorted(item for item in self.fm.bookmarks \ - if '/.' not in item[1].path) + if self.settings.show_hidden_bookmarks or '/.' not in item[1].path) def generator(): return zip(range(self.hei-1), sorted_bookmarks) diff --git a/ranger/shared/settings.py b/ranger/shared/settings.py index 692d06d2..42e3502a 100644 --- a/ranger/shared/settings.py +++ b/ranger/shared/settings.py @@ -19,6 +19,7 @@ from ranger.ext.openstruct import OpenStruct ALLOWED_SETTINGS = { 'show_hidden': bool, + 'show_hidden_bookmarks': bool, 'show_cursor': bool, 'autosave_bookmarks': bool, 'save_console_history': bool, -- cgit 1.4.1-2-gfad0 From eafe24e15e84d64e893ca756272466e29e3f2a49 Mon Sep 17 00:00:00 2001 From: hut Date: Sat, 17 Apr 2010 19:34:35 +0200 Subject: removed option "max_filesize_for_preview" I see no point in keeping it. Even very large files will only have the first few lines loaded and binary files aren't previewed anyway. --- ranger/defaults/options.py | 3 +-- ranger/gui/widgets/browsercolumn.py | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/ranger/defaults/options.py b/ranger/defaults/options.py index 43129652..7c1be4a3 100644 --- a/ranger/defaults/options.py +++ b/ranger/defaults/options.py @@ -48,10 +48,9 @@ show_hidden_bookmarks = True colorscheme = 'default' # Preview files on the rightmost column? -# And collapse the last column if there is nothing to preview? +# And collapse (shrink) the last column if there is nothing to preview? preview_files = True preview_directories = True -max_filesize_for_preview = 300 * 1024 # 300kb collapse_preview = True # Save the console history on exit? diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index c0b60a2e..73f1e61e 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -179,9 +179,6 @@ class BrowserColumn(Pager): and not target.stat.st_mode & stat.S_IFIFO): return False - maxsize = self.settings.max_filesize_for_preview - if maxsize is not None and target.size > maxsize: - return False if PREVIEW_WHITELIST.search(target.basename): return True if PREVIEW_BLACKLIST.search(target.basename): -- cgit 1.4.1-2-gfad0 From d0e58e1df8f5c92fb86decde8a15987e63e7b04a Mon Sep 17 00:00:00 2001 From: hut Date: Sat, 17 Apr 2010 19:38:08 +0200 Subject: help.starting: explain uppercase flags --- ranger/help/starting.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ranger/help/starting.py b/ranger/help/starting.py index 88f90184..8fd8b0da 100644 --- a/ranger/help/starting.py +++ b/ranger/help/starting.py @@ -99,6 +99,9 @@ Flags give you a way to modify the behaviour of the spawned process. For example, "open with: p" will pipe the output of that process into the pager. +An uppercase flag has the opposite effect. If a program will be detached by +default, use "open with: D" to not detach it. + Note: Some combinations don't make sense, eg: "vim d" would open the file in vim and detach it. Since vim is a console application, you loose grip of that process when you detach it. It's up to you to do such sanity checks. -- cgit 1.4.1-2-gfad0 From 91ed2301e97401c8097f6ffc2d2eeb41f0bf713b Mon Sep 17 00:00:00 2001 From: hut Date: Sat, 17 Apr 2010 19:49:26 +0200 Subject: shared.settings: bugfix, forgot to remove max_filesize_for_preview --- ranger/shared/settings.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ranger/shared/settings.py b/ranger/shared/settings.py index 42e3502a..ddc799d2 100644 --- a/ranger/shared/settings.py +++ b/ranger/shared/settings.py @@ -36,7 +36,6 @@ ALLOWED_SETTINGS = { 'update_title': bool, 'shorten_title': int, # Note: False is an instance of int 'tilde_in_titlebar': bool, - 'max_filesize_for_preview': (int, type(None)), 'max_history_size': (int, type(None)), 'scroll_offset': int, 'preview_files': bool, -- cgit 1.4.1-2-gfad0 From 2432c8622c1ff66f62753d1cd9d95508efb276a0 Mon Sep 17 00:00:00 2001 From: hut Date: Sat, 17 Apr 2010 20:21:17 +0200 Subject: ranger.main: prioritize confdir in imports --- ranger/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ranger/__main__.py b/ranger/__main__.py index 827452ff..6b5a21b3 100644 --- a/ranger/__main__.py +++ b/ranger/__main__.py @@ -56,7 +56,7 @@ def parse_arguments(): print("To run ranger without the need for configuration files") print("use the --clean option.") raise SystemExit() - sys.path.append(arg.confdir) + sys.path[0:0] = [arg.confdir] return arg def main(): -- cgit 1.4.1-2-gfad0 From 7213292e490a4f6c73a915d2ea6b834c005dd424 Mon Sep 17 00:00:00 2001 From: hut Date: Sat, 17 Apr 2010 20:25:06 +0200 Subject: Added option "max_console_history_size" --- ranger/defaults/options.py | 1 + ranger/gui/widgets/console.py | 2 +- ranger/shared/settings.py | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ranger/defaults/options.py b/ranger/defaults/options.py index 7c1be4a3..cddd70eb 100644 --- a/ranger/defaults/options.py +++ b/ranger/defaults/options.py @@ -82,6 +82,7 @@ tilde_in_titlebar = True # How many directory-changes or console-commands should be kept in history? max_history_size = 20 +max_console_history_size = 20 # Try to keep so much space between the top/bottom border when scrolling: scroll_offset = 2 diff --git a/ranger/gui/widgets/console.py b/ranger/gui/widgets/console.py index 8480ea42..5f45c26f 100644 --- a/ranger/gui/widgets/console.py +++ b/ranger/gui/widgets/console.py @@ -71,7 +71,7 @@ class Console(Widget): self.historypaths = [relpath_conf(x) for x in \ ('history', 'history_search', 'history_qopen', 'history_open')] for i, path in enumerate(self.historypaths): - hist = History(self.settings.max_history_size) + hist = History(self.settings.max_console_history_size) self.histories.append(hist) if ranger.arg.clean: continue try: f = open(path, 'r') diff --git a/ranger/shared/settings.py b/ranger/shared/settings.py index ddc799d2..44b0e55e 100644 --- a/ranger/shared/settings.py +++ b/ranger/shared/settings.py @@ -37,6 +37,7 @@ ALLOWED_SETTINGS = { 'shorten_title': int, # Note: False is an instance of int 'tilde_in_titlebar': bool, 'max_history_size': (int, type(None)), + 'max_console_history_size': (int, type(None)), 'scroll_offset': int, 'preview_files': bool, 'preview_directories': bool, -- cgit 1.4.1-2-gfad0 From c2238598bfb590367f6c52c4fcbf43d02148a523 Mon Sep 17 00:00:00 2001 From: hut Date: Sun, 18 Apr 2010 00:23:04 +0200 Subject: main: added load_settings(). Store apps/keys in fm now. Also, commands are now loaded from ~/.ranger/commands.py if available --- ranger/__main__.py | 63 ++++++++++++++++++++++++++++++------------ ranger/core/fm.py | 11 ++++---- ranger/gui/ui.py | 2 +- ranger/gui/widgets/console.py | 7 ++--- ranger/gui/widgets/pager.py | 4 +-- ranger/gui/widgets/taskview.py | 2 +- ranger/shared/settings.py | 11 -------- 7 files changed, 57 insertions(+), 43 deletions(-) diff --git a/ranger/__main__.py b/ranger/__main__.py index 6b5a21b3..11d2d288 100644 --- a/ranger/__main__.py +++ b/ranger/__main__.py @@ -18,7 +18,7 @@ import os import sys - +import ranger def parse_arguments(): """Parse the program arguments""" @@ -46,18 +46,41 @@ def parse_arguments(): arg = OpenStruct(options.__dict__, targets=positional) arg.confdir = os.path.expanduser(arg.confdir) - if not arg.clean: + return arg + +def load_settings(fm): + if not ranger.arg.clean: try: - os.makedirs(arg.confdir) + os.makedirs(ranger.arg.confdir) except OSError as err: if err.errno != 17: # 17 means it already exists print("This configuration directory could not be created:") - print(arg.confdir) - print("To run ranger without the need for configuration files") - print("use the --clean option.") + print(ranger.arg.confdir) + print("To run ranger without the need for configuration") + print("files, use the --clean option.") raise SystemExit() - sys.path[0:0] = [arg.confdir] - return arg + + sys.path[0:0] = [ranger.arg.confdir] + + try: + import commands + except ImportError: + from ranger.defaults import commands + try: + import keys + except ImportError: + from ranger.defaults import keys + try: + import apps + except ImportError: + from ranger.defaults import apps + del sys.path[0] + else: + from ranger.defaults import commands, keys, apps + fm.commands = commands + fm.keys = keys + fm.apps = apps.CustomApplications() + def main(): """initialize objects and run the filemanager""" @@ -71,7 +94,6 @@ def main(): from signal import signal, SIGINT from locale import getdefaultlocale, setlocale, LC_ALL - import ranger from ranger.ext import curses_interrupt_handler from ranger.core.fm import FM from ranger.core.environment import Environment @@ -105,7 +127,9 @@ def main(): sys.exit(1) elif os.path.isfile(target): thefile = File(target) - FM().execute_file(thefile, mode=arg.mode, flags=arg.flags) + fm = FM() + load_settings(fm) + fm.execute_file(thefile, mode=arg.mode, flags=arg.flags) sys.exit(0) else: path = target @@ -115,18 +139,21 @@ def main(): EnvironmentAware._assign(Environment(path)) try: - my_ui = UI() - my_fm = FM(ui=my_ui) - FileManagerAware._assign(my_fm) + fm = FM() + load_settings(fm) + FileManagerAware._assign(fm) + fm.ui = UI() # Run the file manager - my_fm.initialize() - my_ui.initialize() - my_fm.loop() + fm.initialize() + fm.ui.initialize() + fm.loop() finally: # Finish, clean up - if 'my_ui' in vars(): - my_ui.destroy() + try: + fm.ui.destroy() + except (AttributeError, NameError): + pass if __name__ == '__main__': top_dir = os.path.dirname(sys.path[0]) diff --git a/ranger/core/fm.py b/ranger/core/fm.py index 224ef06f..2cb3eea7 100644 --- a/ranger/core/fm.py +++ b/ranger/core/fm.py @@ -51,12 +51,6 @@ class FM(Actions, SignalDispatcher): self.tabs = {} self.current_tab = 1 self.loader = Loader() - self.apps = self.settings.apps.CustomApplications() - - def mylogfunc(text): - self.notify(text, bad=True) - self.run = Runner(ui=self.ui, apps=self.apps, - logfunc=mylogfunc) self.log.append('Ranger {0} started! Process ID is {1}.' \ .format(__version__, os.getpid())) @@ -94,6 +88,11 @@ class FM(Actions, SignalDispatcher): self.ui = DefaultUI() self.ui.initialize() + def mylogfunc(text): + self.notify(text, bad=True) + self.run = Runner(ui=self.ui, apps=self.apps, + logfunc=mylogfunc) + self.env.signal_bind('cd', self._update_current_tab) def block_input(self, sec=0): diff --git a/ranger/gui/ui.py b/ranger/gui/ui.py index cdaf6cde..2e2f5ada 100644 --- a/ranger/gui/ui.py +++ b/ranger/gui/ui.py @@ -59,7 +59,7 @@ class UI(DisplayableContainer): if commandlist is None: self.commandlist = CommandList() - self.settings.keys.initialize_commands(self.commandlist) + self.fm.keys.initialize_commands(self.commandlist) else: self.commandlist = commandlist self.win = curses.initscr() diff --git a/ranger/gui/widgets/console.py b/ranger/gui/widgets/console.py index 5f45c26f..22539e75 100644 --- a/ranger/gui/widgets/console.py +++ b/ranger/gui/widgets/console.py @@ -24,7 +24,6 @@ import re from collections import deque from . import Widget -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.core.runner import ALLOWED_FLAGS @@ -63,7 +62,7 @@ class Console(Widget): def __init__(self, win): Widget.__init__(self, win) self.commandlist = CommandList() - self.settings.keys.initialize_console_commands(self.commandlist) + self.fm.keys.initialize_console_commands(self.commandlist) self.clear() self.histories = [] # load histories from files @@ -341,7 +340,7 @@ class CommandConsole(ConsoleWithTab): return command_class(self.line, self.mode) def _get_cmd_class(self): - return commands.get_command(self.line.split()[0]) + return self.fm.commands.get_command(self.line.split()[0]) def _get_tab(self): if ' ' in self.line: @@ -351,7 +350,7 @@ class CommandConsole(ConsoleWithTab): else: return None - return commands.command_generator(self.line) + return self.fm.commands.command_generator(self.line) class QuickCommandConsole(CommandConsole): diff --git a/ranger/gui/widgets/pager.py b/ranger/gui/widgets/pager.py index 2fc8ecda..c0646cdf 100644 --- a/ranger/gui/widgets/pager.py +++ b/ranger/gui/widgets/pager.py @@ -44,9 +44,9 @@ class Pager(Widget): self.commandlist = CommandList() if embedded: - keyfnc = self.settings.keys.initialize_embedded_pager_commands + keyfnc = self.fm.keys.initialize_embedded_pager_commands else: - keyfnc = self.settings.keys.initialize_pager_commands + keyfnc = self.fm.keys.initialize_pager_commands keyfnc(self.commandlist) diff --git a/ranger/gui/widgets/taskview.py b/ranger/gui/widgets/taskview.py index 6e86465c..ec68cb1a 100644 --- a/ranger/gui/widgets/taskview.py +++ b/ranger/gui/widgets/taskview.py @@ -32,7 +32,7 @@ class TaskView(Widget, Accumulator): Accumulator.__init__(self) self.scroll_begin = 0 self.commandlist = CommandList() - self.settings.keys.initialize_taskview_commands(self.commandlist) + self.fm.keys.initialize_taskview_commands(self.commandlist) def draw(self): base_clr = deque() diff --git a/ranger/shared/settings.py b/ranger/shared/settings.py index 44b0e55e..57e00142 100644 --- a/ranger/shared/settings.py +++ b/ranger/shared/settings.py @@ -169,15 +169,4 @@ class SettingsAware(object): for setting in ALLOWED_SETTINGS), \ "Ensure that all options are defined in the defaults!" - try: - import apps - except ImportError: - from ranger.defaults import apps - settings._raw_set('apps', apps) - try: - import keys - except ImportError: - from ranger.defaults import keys - settings._raw_set('keys', keys) - SettingsAware.settings = settings -- cgit 1.4.1-2-gfad0