diff options
-rw-r--r-- | ranger/__main__.py | 69 | ||||
-rw-r--r-- | ranger/core/environment.py | 4 | ||||
-rw-r--r-- | ranger/core/fm.py | 11 | ||||
-rw-r--r-- | ranger/defaults/options.py | 7 | ||||
-rw-r--r-- | ranger/fsobject/directory.py | 8 | ||||
-rw-r--r-- | ranger/fsobject/fsobject.py | 47 | ||||
-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 | 7 | ||||
-rw-r--r-- | ranger/help/starting.py | 12 | ||||
-rw-r--r-- | ranger/shared/settings.py | 21 |
11 files changed, 109 insertions, 82 deletions
diff --git a/ranger/__main__.py b/ranger/__main__.py index 2aae6343..ae3f3221 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,47 @@ 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.append(arg.confdir) - return arg + + sys.path[0:0] = [ranger.arg.confdir] + + try: + import commands + except ImportError: + from ranger.defaults import commands + try: + import apps + except ImportError: + from ranger.defaults import apps + + from ranger import shared, api + from ranger.api import keys + keymanager = shared.EnvironmentAware.env.keymanager + keys.keymanager = keymanager + from ranger.defaults import keys + try: + import keys + except ImportError: + pass + 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 +100,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 +133,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 @@ -116,18 +146,21 @@ def main(): SettingsAware._setup_keys() 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/environment.py b/ranger/core/environment.py index b712683a..49bc8a5c 100644 --- a/ranger/core/environment.py +++ b/ranger/core/environment.py @@ -195,6 +195,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/core/fm.py b/ranger/core/fm.py index 495b9f13..ab418c89 100644 --- a/ranger/core/fm.py +++ b/ranger/core/fm.py @@ -50,12 +50,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())) @@ -93,6 +87,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/defaults/options.py b/ranger/defaults/options.py index 0593bae3..2de8a230 100644 --- a/ranger/defaults/options.py +++ b/ranger/defaults/options.py @@ -39,16 +39,18 @@ 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. 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? @@ -80,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/fsobject/directory.py b/ranger/fsobject/directory.py index c9ec5bf5..3cec1646 100644 --- a/ranger/fsobject/directory.py +++ b/ranger/fsobject/directory.py @@ -200,9 +200,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: @@ -220,8 +224,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: diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index 61c74e63..d7dbac4f 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): diff --git a/ranger/gui/widgets/browserview.py b/ranger/gui/widgets/browserview.py index 466e23eb..33418a2f 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/gui/widgets/console.py b/ranger/gui/widgets/console.py index c81c66b5..36090bb5 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 @@ -70,7 +69,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') @@ -347,7 +346,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: @@ -357,7 +356,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/help/starting.py b/ranger/help/starting.py index 29921ffc..8fd8b0da 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,12 +93,15 @@ 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 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. diff --git a/ranger/shared/settings.py b/ranger/shared/settings.py index 01d4caf6..df97238f 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, @@ -35,8 +36,8 @@ 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)), + 'max_console_history_size': (int, type(None)), 'scroll_offset': int, 'preview_files': bool, 'preview_directories': bool, @@ -169,22 +170,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) - SettingsAware.settings = settings - - @staticmethod - def _setup_keys(): # ugly! but works. - import ranger.api.keys - import ranger.shared - env = ranger.shared.EnvironmentAware.env - ranger.api.keys.keymanager = env.keymanager - from ranger.defaults import keys - try: - import keys - except ImportError: - pass |