diff options
-rw-r--r-- | examples/README | 2 | ||||
-rw-r--r-- | examples/plugin_chmod_keybindings.py | 18 | ||||
-rw-r--r-- | examples/plugin_file_filter.py | 17 | ||||
-rw-r--r-- | examples/plugin_new_macro.py | 17 | ||||
-rw-r--r-- | examples/plugin_new_sorting_method.py | 7 | ||||
-rw-r--r-- | examples/plugin_skip_default_rc.py | 9 | ||||
-rw-r--r-- | ranger/config/commands.py | 8 | ||||
-rw-r--r-- | ranger/config/options.py | 216 | ||||
-rw-r--r-- | ranger/config/rc.conf | 119 | ||||
-rw-r--r-- | ranger/container/history.py | 2 | ||||
-rw-r--r-- | ranger/container/settingobject.py | 32 | ||||
-rw-r--r-- | ranger/core/actions.py | 29 | ||||
-rw-r--r-- | ranger/core/fm.py | 11 | ||||
-rw-r--r-- | ranger/core/main.py | 31 | ||||
-rw-r--r-- | ranger/core/shared.py | 16 | ||||
-rw-r--r-- | ranger/gui/colorscheme.py | 29 |
16 files changed, 286 insertions, 277 deletions
diff --git a/examples/README b/examples/README index 60f29ac6..8606a89d 100644 --- a/examples/README +++ b/examples/README @@ -1,2 +1,2 @@ -Thes files in this directory contain applications or extensions of ranger which +The files in this directory contain applications or extensions of ranger which are put here for your inspiration and as references. diff --git a/examples/plugin_chmod_keybindings.py b/examples/plugin_chmod_keybindings.py new file mode 100644 index 00000000..c04cc492 --- /dev/null +++ b/examples/plugin_chmod_keybindings.py @@ -0,0 +1,18 @@ +# This plugin serves as an example for adding key bindings through a plugin. +# It could replace the ten lines in the rc.conf that create the key bindings +# for the "chmod" command. + +import ranger.core.fm +old_init_hook = ranger.core.fm.init_hook + +def init_hook(fm): + old_init_hook(fm) + + # Generate key bindings for the chmod command + command = "map {0}{1}{2} shell -d chmod {1}{0}{2} %s" + for mode in list('ugoa') + '': + for perm in "rwxXst": + fm.execute_console(command.format('-', mode, perm)) + fm.execute_console(command.format('+', mode, perm)) + +ranger.core.fm.init_hook = init_hook diff --git a/examples/plugin_file_filter.py b/examples/plugin_file_filter.py new file mode 100644 index 00000000..99d026bb --- /dev/null +++ b/examples/plugin_file_filter.py @@ -0,0 +1,17 @@ +# This plugin hides the directories "boot", "sbin", "proc" and "sys" in the +# root directory. + +# Save the original filter function +import ranger.fsobject.directory +old_accept_file = ranger.fsobject.directory.accept_file + +# Define a new one +def custom_accept_file(fname, mypath, hidden_filter, name_filter): + if hidden_filter and mypath == '/' and fname in ('boot', 'sbin', 'proc', 'sys'): + return False + else: + return old_accept_file(fname, mypath, hidden_filter, name_filter) + +# Overwrite the old function +import ranger.fsobject.directory +ranger.fsobject.directory.accept_file = custom_accept_file diff --git a/examples/plugin_new_macro.py b/examples/plugin_new_macro.py new file mode 100644 index 00000000..ec0c487c --- /dev/null +++ b/examples/plugin_new_macro.py @@ -0,0 +1,17 @@ +# This plugin adds the new macro %date which is substituted with the current +# date in commands that allow macros. You can test it with the command +# ":shell echo %date; read" + +# Save the original macro function +import ranger.core.actions +old_get_macros = ranger.core.actions.Actions._get_macros + +# Define a new macro function +import time +def get_macros_with_date(self): + macros = old_get_macros(self) + macros['date'] = time.strftime('%m/%d/%Y') + return macros + +# Overwrite the old one +ranger.core.actions.Actions._get_macros = get_macros_with_date diff --git a/examples/plugin_new_sorting_method.py b/examples/plugin_new_sorting_method.py new file mode 100644 index 00000000..2500c1c1 --- /dev/null +++ b/examples/plugin_new_sorting_method.py @@ -0,0 +1,7 @@ +# This plugin adds the sorting algorithm called 'random'. To enable it, type +# ":set sort=random" or create a key binding with ":map oz set sort=random" + +from ranger.fsobject.directory import Directory +from random import random +Directory.sort_dict['random'] = lambda path: random() + diff --git a/examples/plugin_skip_default_rc.py b/examples/plugin_skip_default_rc.py new file mode 100644 index 00000000..6a657a99 --- /dev/null +++ b/examples/plugin_skip_default_rc.py @@ -0,0 +1,9 @@ +# This plugin inhibits the loading of the default rc.conf. This serves to +# speed up starting time by avoiding to load rc.conf twice if you have a full +# copy of it in ~/.config/ranger. +# +# Don't use this if you have a supplementary rc.conf or no rc.conf at all, or +# you will end up without key bindings and options. + +import ranger.core.main +ranger.core.main.load_default_config = False diff --git a/ranger/config/commands.py b/ranger/config/commands.py index 962b9fd1..4a2bb912 100644 --- a/ranger/config/commands.py +++ b/ranger/config/commands.py @@ -387,13 +387,7 @@ class set_(Command): def execute(self): name = self.arg(1) name, value, _ = self.parse_setting_line() - if name and value: - from re import compile as regexp - try: - value = eval(value) - except: - pass - self.fm.settings[name] = value + self.fm.set_option_from_string(name, value) def tab(self): name, value, name_done = self.parse_setting_line() diff --git a/ranger/config/options.py b/ranger/config/options.py deleted file mode 100644 index a401abc5..00000000 --- a/ranger/config/options.py +++ /dev/null @@ -1,216 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (C) 2009, 2010, 2011 Roman Zimbelmann <romanz@lavabit.com> -# This configuration file is licensed under the same terms as ranger. -# =================================================================== -# This is the main configuration file of ranger. It consists of python -# code, but fear not, you don't need any python knowledge for changing -# the settings. -# -# Lines beginning with # are comments. To enable a line, remove the #. -# -# You can customize ranger in the file ~/.config/ranger/options.py. -# It has the same syntax as this file. In fact, you can just copy this -# file there with `ranger --copy-config=options' and make your modifications. -# But make sure you update your configs when you update ranger. -# =================================================================== - -# Load the deault rc.conf file? If you've copied it to your configuration -# direcory, then you should deactivate this option. -load_default_rc = True - -# How many columns are there, and what are their relative widths? -column_ratios = (1, 3, 4) - -# Which files should be hidden? Toggle this by typing `zh' or -# changing the setting `show_hidden' -hidden_filter = r'^\.|\.(?:pyc|pyo|bak|swp)$|^lost\+found$|^__(py)?cache__$' -show_hidden = False - -# Which script is used to generate file previews? -# ranger ships with scope.sh, a script that calls external programs (see -# README for dependencies) to preview images, archives, etc. -preview_script = '~/.config/ranger/scope.sh' - -# Use that external preview script or display internal plain text previews? -use_preview_script = True - -# Use a unicode "..." character to mark cut-off filenames? -unicode_ellipsis = False - -# Show dotfiles in the bookmark preview box? -show_hidden_bookmarks = True - -# Which colorscheme to use? These colorschemes are available by default: -# default, default88, jungle, snow -# Snow is monochrome and default88 uses 88 colors. -colorscheme = 'default' - -# Preview files on the rightmost column? -# And collapse (shrink) the last column if there is nothing to preview? -preview_files = True -preview_directories = True -collapse_preview = True - -# Save the console history on exit? -save_console_history = True - -# Draw a progress bar in the status bar which displays the average state of all -# currently running tasks which support progress bars? -draw_progress_bar_in_status_bar = True - -# Draw borders around columns? -draw_borders = False -draw_bookmark_borders = True - -# Display the directory name in tabs? -dirname_in_tabs = False - -# Enable the mouse support? -mouse_enabled = True - -# Display the file size in the main column or status bar? -display_size_in_main_column = True -display_size_in_status_bar = False - -# Display files tags in all columns or only in main column? -display_tags_in_all_columns = True - -# Set a title for the window? -update_title = True - -# Shorten the title if it gets long? The number defines how many -# directories are displayed at once, False turns off this feature. -shorten_title = 3 - -# Abbreviate $HOME with ~ in the titlebar (first line) of ranger? -tilde_in_titlebar = True - -# How many directory-changes or console-commands should be kept in history? -max_history_size = 20 -max_console_history_size = 50 - -# Try to keep so much space between the top/bottom border when scrolling: -scroll_offset = 8 - -# Flush the input after each key hit? (Noticable when ranger lags) -flushinput = True - -# Padding on the right when there's no preview? -# This allows you to click into the space to run the file. -padding_right = True - -# Save bookmarks (used with mX and `X) instantly? -# This helps to synchronize bookmarks between multiple ranger -# instances but leads to *slight* performance loss. -# When false, bookmarks are saved when ranger is exited. -autosave_bookmarks = True - -# You can display the "real" cumulative size of directories by using the -# command :get_cumulative_size or typing "dc". The size is expensive to -# calculate and will not be updated automatically. You can choose -# to update it automatically though by turning on this option: -autoupdate_cumulative_size = False - -# Makes sense for screen readers: -show_cursor = False - -# One of: size, basename, mtime, type -sort = 'natural' -sort_reverse = False -sort_case_insensitive = True -sort_directories_first = True - -# Enable this if key combinations with the Alt Key don't work for you. -# (Especially on xterm) -xterm_alt_key = False - -# A function that is called when the user interface is being set up. -init_function = None - -# You can use it to initialize some custom functionality or bind singals -#def init_function(fm): -# fm.notify("Hello :)") -# def on_tab_change(signal): -# signal.origin.notify("Changing tab! Yay!") -# fm.signal_bind("tab.change", on_tab_change) - -# The color scheme overlay. Explained below. -colorscheme_overlay = None - -## Apply an overlay function to the colorscheme. It will be called with -## 4 arguments: the context and the 3 values (fg, bg, attr) returned by -## the original use() function of your colorscheme. The return value -## must be a 3-tuple of (fg, bg, attr). -## Note: Here, the colors/attributes aren't directly imported into -## the namespace but have to be accessed with color.xyz. - -#from ranger.gui import color -#def colorscheme_overlay(context, fg, bg, attr): -# if context.directory and attr & color.bold and \ -# not any((context.marked, context.selected)): -# attr ^= color.bold # I don't like bold directories! -# -# if context.main_column and context.selected: -# fg, bg = color.red, color.default # To highlight the main column! -# -# return fg, bg, attr - - -# =================================================================== -# Beware: from here on, you are on your own. This part requires python -# knowledge. -# -# Since python is a dynamic language, it gives you the power to replace any -# part of ranger without touching the code. This is commonly referred to as -# Monkey Patching and can be helpful if you, for some reason, don't want to -# modify rangers code directly. Just remember: the more you mess around, the -# more likely it is to break when you switch to another version. -# -# Here are some practical examples of monkey patching. -# -# Technical information: This file is imported as a python module. If a -# variable has the name of a setting, ranger will attempt to use it to change -# that setting. You can write "del <variable-name>" to avoid that. -# =================================================================== -# Add a new sorting algorithm: Random sort. -# Enable this with :set sort=random - -#from ranger.fsobject.directory import Directory -#from random import random -#Directory.sort_dict['random'] = lambda path: random() - -# =================================================================== -# A function that changes which files are displayed. This is more powerful -# than the hidden_filter setting since this function has more information. - -## Save the original filter function -#import ranger.fsobject.directory -#old_accept_file = ranger.fsobject.directory.accept_file -# -## Define a new one -#def accept_file_MOD(fname, mypath, hidden_filter, name_filter): -# if hidden_filter and mypath == '/' and fname in ('boot', 'sbin', 'proc', 'sys'): -# return False -# else: -# return old_accept_file(fname, mypath, hidden_filter, name_filter) -# -## Overwrite the old function -#import ranger.fsobject.directory -#ranger.fsobject.directory.accept_file = accept_file_MOD - -# =================================================================== -# A function that adds an additional macro. Test this with :shell -p echo %date - -## Save the original macro function -#import ranger.core.actions -#old_get_macros = ranger.core.actions.Actions._get_macros -# -## Define a new macro function -#import time -#def get_macros_MOD(self): -# macros = old_get_macros(self) -# macros['date'] = time.strftime('%m/%d/%Y') -# return macros -# -## Overwrite the old one -#ranger.core.actions.Actions._get_macros = get_macros_MOD diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 1b344465..2a6be5d8 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -8,9 +8,9 @@ # # load_default_rc = False # -# The purpose of this file is mainly to define keybindings. For -# changing settings or running more complex python code, use the -# configuation file "options.py" or define commands in "commands.py". +# The purpose of this file is mainly to define keybindings and settings. +# For running more complex python code, please create a plugin in "plugins/" or +# a command in "commands.py". # # Each line is a command that will be run before the user interface # is initialized. As a result, you can not use commands which rely @@ -18,6 +18,119 @@ # =================================================================== # =================================================================== +# == Options +# =================================================================== + +# How many columns are there, and what are their relative widths? +set column_ratios 1,3,4 + +# Which files should be hidden? (regular expression) +set hidden_filter ^\.|\.(?:pyc|pyo|bak|swp)$|^lost\+found$|^__(py)?cache__$ + +# Show hidden files? You can toggle this by typing 'zh' +set show_hidden false + +# Which script is used to generate file previews? +# ranger ships with scope.sh, a script that calls external programs (see +# README for dependencies) to preview images, archives, etc. +set preview_script ~/.config/ranger/scope.sh + +# Use the external preview script or display simple plain text previews? +set use_preview_script true + +# Use a unicode "..." character to mark cut-off filenames? +set unicode_ellipsis false + +# Show dotfiles in the bookmark preview box? +set show_hidden_bookmarks true + +# Which colorscheme to use? These colorschemes are available by default: +# default, default88, jungle, snow +# Snow is monochrome and default88 uses 88 colors. +set colorscheme default + +# Preview files on the rightmost column? +# And collapse (shrink) the last column if there is nothing to preview? +set preview_files true +set preview_directories true +set collapse_preview true + +# Save the console history on exit? +set save_console_history true + +# Draw a progress bar in the status bar which displays the average state of all +# currently running tasks which support progress bars? +set draw_progress_bar_in_status_bar True + +# Draw borders around columns? +set draw_borders false + +# Display the directory name in tabs? +set dirname_in_tabs false + +# Enable the mouse support? +set mouse_enabled true + +# Display the file size in the main column or status bar? +set display_size_in_main_column true +set display_size_in_status_bar true + +# Display files tags in all columns or only in main column? +set display_tags_in_all_columns true + +# Set a title for the window? +set update_title false + +# Shorten the title if it gets long? The number defines how many +# directories are displayed at once, False turns off this feature. +set shorten_title 3 + +# Abbreviate $HOME with ~ in the titlebar (first line) of ranger? +set tilde_in_titlebar false + +# How many directory-changes or console-commands should be kept in history? +set max_history_size 20 +set max_console_history_size 50 + +# Try to keep so much space between the top/bottom border when scrolling: +set scroll_offset 8 + +# Flush the input after each key hit? (Noticable when ranger lags) +set flushinput true + +# Padding on the right when there's no preview? +# This allows you to click into the space to run the file. +set padding_right true + +# Save bookmarks (used with mX and `X) instantly? +# This helps to synchronize bookmarks between multiple ranger +# instances but leads to *slight* performance loss. +# When false, bookmarks are saved when ranger is exited. +set autosave_bookmarks true + +# You can display the "real" cumulative size of directories by using the +# command :get_cumulative_size or typing "dc". The size is expensive to +# calculate and will not be updated automatically. You can choose +# to update it automatically though by turning on this option: +set autoupdate_cumulative_size false + +# Turning this on makes sense for screen readers: +set show_cursor false + +# One of: size, basename, mtime, type +set sort natural + +# Additional sorting options +set sort_reverse false +set sort_case_insensitive true +set sort_directories_first true + +# Enable this if key combinations with the Alt Key don't work for you. +# (Especially on xterm) +set xterm_alt_key true + + +# =================================================================== # == Command Aliases in the Console # =================================================================== diff --git a/ranger/container/history.py b/ranger/container/history.py index 8ba092bc..d0e077aa 100644 --- a/ranger/container/history.py +++ b/ranger/container/history.py @@ -33,7 +33,7 @@ class History(object): if self._history and self._history[-1] == item: del self._history[-1] # Remove first if list is too long - if len(self._history) > self.maxlen - 1: + if len(self._history) > max(self.maxlen - 1, 0): del self._history[0] # Append the item and fast forward self._history.append(item) diff --git a/ranger/container/settingobject.py b/ranger/container/settingobject.py index f70361b5..ed9ab1ea 100644 --- a/ranger/container/settingobject.py +++ b/ranger/container/settingobject.py @@ -4,12 +4,12 @@ from inspect import isfunction from ranger.ext.signals import SignalDispatcher from ranger.core.shared import FileManagerAware +import re ALLOWED_SETTINGS = { 'autosave_bookmarks': bool, 'autoupdate_cumulative_size': bool, 'collapse_preview': bool, - 'colorscheme_overlay': (type(None), type(lambda:0)), 'colorscheme': str, 'column_ratios': (tuple, list), 'dirname_in_tabs': bool, @@ -20,9 +20,7 @@ ALLOWED_SETTINGS = { 'draw_borders': bool, 'draw_progress_bar_in_status_bar': bool, 'flushinput': bool, - 'hidden_filter': lambda x: isinstance(x, str) or hasattr(x, 'match'), - 'init_function': (type(None), type(lambda:0)), - 'load_default_rc': (bool, type(None)), + 'hidden_filter': (str, type(re.compile(""))), #XXX 'max_console_history_size': (int, type(None)), 'max_history_size': (int, type(None)), 'mouse_enabled': bool, @@ -32,7 +30,7 @@ ALLOWED_SETTINGS = { 'padding_right': bool, 'save_console_history': bool, 'scroll_offset': int, - 'shorten_title': int, # Note: False is an instance of int + 'shorten_title': int, # XXX Note: False is an instance of int 'show_cursor': bool, 'show_hidden_bookmarks': bool, 'show_hidden': bool, @@ -47,6 +45,13 @@ ALLOWED_SETTINGS = { 'xterm_alt_key': bool, } +DEFAULT_VALUES = { + bool: False, + type(None): None, + str: "", + int: 0, + list: [], +} class SettingObject(SignalDispatcher, FileManagerAware): def __init__(self): @@ -63,10 +68,11 @@ class SettingObject(SignalDispatcher, FileManagerAware): else: assert name in ALLOWED_SETTINGS, "No such setting: {0}!".format(name) if name not in self._settings: - getattr(self, name) + previous = None + else: + previous=self._settings[name] assert self._check_type(name, value) - kws = dict(setting=name, value=value, - previous=self._settings[name], fm=self.fm) + kws = dict(setting=name, value=value, previous=previous, fm=self.fm) self.signal_emit('setopt', **kws) self.signal_emit('setopt.'+name, **kws) @@ -78,14 +84,8 @@ class SettingObject(SignalDispatcher, FileManagerAware): try: return self._settings[name] except: - for struct in self._setting_sources: - try: value = getattr(struct, name) - except: pass - else: break - else: - raise Exception("The option `{0}' was not defined" \ - " in the defaults!".format(name)) - assert self._check_type(name, value) + type_ = self.types_of(name)[0] + value = DEFAULT_VALUES[type_] self._raw_set(name, value) self.__setattr__(name, value) return self._settings[name] diff --git a/ranger/core/actions.py b/ranger/core/actions.py index cbe74132..6df73cdf 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -23,6 +23,7 @@ from ranger.core.shared import FileManagerAware, EnvironmentAware, \ from ranger.core.tab import Tab from ranger.fsobject import File from ranger.core.loader import CommandLoader, CopyLoader +from ranger.container.settingobject import ALLOWED_SETTINGS MACRO_FAIL = "<\x01\x01MACRO_HAS_NO_VALUE\x01\01>" @@ -66,6 +67,34 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): self.mode = mode self.ui.status.request_redraw() + def set_option_from_string(self, option_name, value): + if option_name not in ALLOWED_SETTINGS: + raise ValueError("The option named `%s' does not exist" % + option_name) + if not isinstance(value, str): + raise ValueError("The value for an option needs to be a string.") + self.settings[option_name] = self._parse_option_value(option_name, value) + + def _parse_option_value(self, name, value): + types = self.fm.settings.types_of(name) + if bool in types: + if value.lower() in ('false', 'off', '0'): + return False + elif value.lower() in ('true', 'on', '1'): + return True + if type(None) in types and value.lower() == 'none': + return None + if int in types: + try: + return int(value) + except ValueError: + pass + if str in types: + return value + if list in types: + return value.split(',') + raise ValueError("Invalid value `%s' for option `%s'!" % (name, value)) + def toggle_visual_mode(self, reverse=False): if self.mode == 'normal': self._visual_reverse = reverse diff --git a/ranger/core/fm.py b/ranger/core/fm.py index f554ab1b..b32e5730 100644 --- a/ranger/core/fm.py +++ b/ranger/core/fm.py @@ -28,6 +28,9 @@ from ranger.ext.signals import SignalDispatcher from ranger import __version__ from ranger.core.loader import Loader +def init_hook(): + pass + class FM(Actions, SignalDispatcher): input_blocked = False input_blocked_until = 0 @@ -123,8 +126,7 @@ class FM(Actions, SignalDispatcher): self.notify(text, bad=True) self.run = Runner(ui=self.ui, logfunc=mylogfunc, fm=self) - if self.settings.init_function: - self.settings.init_function(self) + init_hook() def destroy(self): debug = ranger.arg.debug @@ -185,14 +187,11 @@ class FM(Actions, SignalDispatcher): copy('config/commands.py', 'commands.py') if which == 'rc' or which == 'all': copy('config/rc.conf', 'rc.conf') - if which == 'options' or which == 'all': - copy('config/options.py', 'options.py') if which == 'scope' or which == 'all': copy('data/scope.sh', 'scope.sh') os.chmod(self.confpath('scope.sh'), os.stat(self.confpath('scope.sh')).st_mode | stat.S_IXUSR) - if which not in \ - ('all', 'rifle', 'scope', 'commands', 'rc', 'options'): + if which not in ('all', 'rifle', 'scope', 'commands', 'rc'): sys.stderr.write("Unknown config file `%s'\n" % which) def confpath(self, *paths): diff --git a/ranger/core/main.py b/ranger/core/main.py index c3a3d76b..df2a922e 100644 --- a/ranger/core/main.py +++ b/ranger/core/main.py @@ -6,12 +6,14 @@ The main function responsible to initialize the FM object and stuff. """ import os.path +import sys + +load_default_config = True def main(): """initialize objects and run the filemanager""" import locale import ranger - import sys from ranger.core.shared import FileManagerAware, SettingsAware from ranger.core.fm import FM @@ -181,7 +183,7 @@ def parse_arguments(): help="don't touch/require any config files. ") parser.add_option('--copy-config', type='string', metavar='which', help="copy the default configs to the local config directory. " - "Possible values: all, rc, rifle, commands, options, scope") + "Possible values: all, rc, rifle, commands, scope") parser.add_option('--fail-unless-cd', action='store_true', help="experimental: return the exit code 1 if ranger is" \ "used to run a file (with `ranger filename`)") @@ -225,6 +227,7 @@ def parse_arguments(): def load_settings(fm, clean): + global load_default_config from ranger.core.actions import Actions import ranger.core.shared import ranger.api.commands @@ -250,9 +253,8 @@ def load_settings(fm, clean): # Load rc.conf custom_conf = fm.confpath('rc.conf') default_conf = fm.relpath('config', 'rc.conf') - load_default_rc = fm.settings.load_default_rc - if load_default_rc: + if load_default_config: fm.source(default_conf) if os.access(custom_conf, os.R_OK): fm.source(custom_conf) @@ -281,6 +283,27 @@ def load_settings(fm, clean): fm.log.append(line) ranger.fm = None + # COMPAT: Load the outdated options.py + # options.py[oc] are deliberately ignored + if os.path.exists(fm.confpath("options.py")): + module = __import__('options') + from ranger.container.settingobject import ALLOWED_SETTINGS + for setting in ALLOWED_SETTINGS: + if hasattr(module, setting): + fm.settings[setting] = getattr(module, setting) + + sys.stderr.write( +"""****************************** +Warning: The configuration file 'options.py' is deprecated. +Please move all settings to the file 'rc.conf', converting lines like + "preview_files = False" +to + "set preview_files false" +If you had python code in the options.py that you'd like to keep, simply +copy & paste it to a .py file in ~/.config/ranger/plugins/. +Remove the options.py or discard stderr to get rid of this warning. +******************************\n""") + allow_access_to_confdir(ranger.arg.confdir, False) else: fm.source(fm.relpath('config', 'rc.conf')) diff --git a/ranger/core/shared.py b/ranger/core/shared.py index 26023e43..ec791f22 100644 --- a/ranger/core/shared.py +++ b/ranger/core/shared.py @@ -43,6 +43,9 @@ class SettingsAware(Awareness): settings.signal_bind('setopt.colorscheme', _colorscheme_name_to_class, priority=1) + settings.signal_bind('setopt.column_ratios', + _sanitize_setting_column_ratios, priority=1) + def after_setting_preview_script(signal): if isinstance(signal.value, str): signal.value = os.path.expanduser(signal.value) @@ -71,9 +74,12 @@ class SettingsAware(Awareness): settings._setting_sources.append(my_options) del sys.path[0] - from ranger.config import options as default_options - settings._setting_sources.append(default_options) - assert all(hasattr(default_options, setting) \ - for setting in ALLOWED_SETTINGS), \ - "Ensure that all options are defined in the defaults!" SettingsAware.settings = settings + +def _sanitize_setting_column_ratios(signal): + if isinstance(signal.value, tuple): + signal.value = list(signal.value) + if not isinstance(signal.value, list) or len(signal.value) < 2: + signal.value = [1,1] + else: + signal.value = [int(i) if str(i).isdigit() else 1 for i in signal.value] diff --git a/ranger/gui/colorscheme.py b/ranger/gui/colorscheme.py index b36048e2..34e59f55 100644 --- a/ranger/gui/colorscheme.py +++ b/ranger/gui/colorscheme.py @@ -33,23 +33,18 @@ import ranger from ranger.gui.color import get_color from ranger.gui.context import Context from ranger.core.main import allow_access_to_confdir -from ranger.core.shared import SettingsAware from ranger.ext.cached_function import cached_function from ranger.ext.iter_tools import flatten -# ColorScheme is not SettingsAware but it will gain access -# to the settings during the initialization. We can't import -# SettingsAware here because of circular imports. - -class ColorScheme(SettingsAware): +class ColorScheme(object): """ This is the class that colorschemes must inherit from. - it defines get() it defines the get() method, which returns the color tuple which fits to the given keys. """ + @cached_function def get(self, *keys): """ Returns the (fg, bg, attr) for the given keys. @@ -58,17 +53,11 @@ class ColorScheme(SettingsAware): colors for faster access. """ context = Context(keys) - - # add custom error messages for broken colorschemes color = self.use(context) - if self.settings.colorscheme_overlay: - result = self.settings.colorscheme_overlay(context, *color) - assert isinstance(result, (tuple, list)), \ - "Your colorscheme overlay doesn't return a tuple!" - assert all(isinstance(val, int) for val in result), \ - "Your colorscheme overlay doesn't return a tuple"\ - " containing 3 integers!" - color = result + if len(color) != 3 or not all(isinstance(value, int) \ + for value in color): + raise ValueError("Bad Value from colorscheme. Need " + "a tuple of (foreground_color, background_color, attribute).") return color @cached_function @@ -82,7 +71,8 @@ class ColorScheme(SettingsAware): return attr | color_pair(get_color(fg, bg)) def use(self, context): - """Use the colorscheme to determine the (fg, bg, attr) tuple. + """ + Use the colorscheme to determine the (fg, bg, attr) tuple. Override this method in your own colorscheme. """ @@ -95,6 +85,9 @@ def _colorscheme_name_to_class(signal): # is picked. if isinstance(signal.value, ColorScheme): return + if not signal.value: + signal.value = 'default' + scheme_name = signal.value usecustom = not ranger.arg.clean |