summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--examples/README2
-rw-r--r--examples/plugin_chmod_keybindings.py18
-rw-r--r--examples/plugin_file_filter.py17
-rw-r--r--examples/plugin_new_macro.py17
-rw-r--r--examples/plugin_new_sorting_method.py7
-rw-r--r--examples/plugin_skip_default_rc.py9
-rw-r--r--ranger/config/commands.py8
-rw-r--r--ranger/config/options.py216
-rw-r--r--ranger/config/rc.conf119
-rw-r--r--ranger/container/history.py2
-rw-r--r--ranger/container/settingobject.py32
-rw-r--r--ranger/core/actions.py29
-rw-r--r--ranger/core/fm.py11
-rw-r--r--ranger/core/main.py31
-rw-r--r--ranger/core/shared.py16
-rw-r--r--ranger/gui/colorscheme.py29
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