summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--INSTALL10
-rw-r--r--Makefile18
-rw-r--r--README19
-rw-r--r--TODO20
-rw-r--r--doc/cd-after-exit.txt161
-rwxr-xr-xdoc/pick.sh25
-rw-r--r--doc/pydoc/ranger.colorschemes.default.html9
-rw-r--r--doc/pydoc/ranger.colorschemes.jungle.html7
-rw-r--r--doc/pydoc/ranger.colorschemes.snow.html9
-rw-r--r--doc/pydoc/ranger.defaults.options.html11
-rw-r--r--doc/pydoc/ranger.ext.html3
-rw-r--r--doc/pydoc/ranger.fsobject.directory.html17
-rw-r--r--doc/pydoc/ranger.fsobject.file.html20
-rw-r--r--doc/pydoc/ranger.fsobject.fsobject.html10
-rw-r--r--doc/pydoc/ranger.fsobject.loader.html2
-rw-r--r--doc/pydoc/ranger.gui.colorscheme.html27
-rw-r--r--doc/pydoc/ranger.gui.defaultui.html2
-rw-r--r--doc/pydoc/ranger.gui.ui.html2
-rw-r--r--doc/pydoc/ranger.gui.widgets.browsercolumn.html3
-rw-r--r--doc/pydoc/ranger.gui.widgets.console.html52
-rw-r--r--doc/pydoc/ranger.gui.widgets.titlebar.html5
-rw-r--r--doc/pydoc/ranger.html2
-rw-r--r--doc/pydoc/ranger.shared.settings.html65
-rw-r--r--doc/pydoc/test.html7
-rw-r--r--doc/ranger.1213
-rw-r--r--doc/uml.txt5
-rw-r--r--doc/uml/1280021090
-rw-r--r--doc/uml/128002.diagram217
-rw-r--r--doc/uml/134530145
-rw-r--r--doc/uml/134530.diagram190
-rw-r--r--doc/uml/141058.diagram218
-rw-r--r--doc/uml/2.session26
-rw-r--r--doc/uml/cpp_includes13
-rw-r--r--doc/uml/generation_settings310
-rw-r--r--doc/uml/idl_includes1
-rw-r--r--doc/uml/java_imports1
-rw-r--r--doc/uml/python_imports1
-rw-r--r--doc/uml/stereotypes59
-rw-r--r--doc/uml/tools18
-rw-r--r--doc/uml/uml.prj43
-rwxr-xr-xranger.py12
-rw-r--r--ranger/__init__.py5
-rw-r--r--ranger/__main__.py38
-rw-r--r--ranger/api/options.py1
-rw-r--r--ranger/colorschemes/default.py13
-rw-r--r--ranger/core/actions.py619
-rw-r--r--ranger/core/environment.py46
-rw-r--r--ranger/core/fm.py34
-rw-r--r--ranger/defaults/apps.py26
-rw-r--r--ranger/defaults/commands.py30
-rw-r--r--ranger/defaults/keys.py141
-rw-r--r--ranger/defaults/options.py38
-rw-r--r--ranger/ext/direction.py202
-rw-r--r--ranger/ext/move.py23
-rw-r--r--ranger/ext/signal_dispatcher.py103
-rw-r--r--ranger/fsobject/directory.py70
-rw-r--r--ranger/fsobject/file.py22
-rw-r--r--ranger/fsobject/fsobject.py8
-rw-r--r--ranger/fsobject/loader.py2
-rw-r--r--ranger/gui/colorscheme.py71
-rw-r--r--ranger/gui/context.py4
-rw-r--r--ranger/gui/defaultui.py7
-rw-r--r--ranger/gui/displayable.py8
-rw-r--r--ranger/gui/mouse_event.py9
-rw-r--r--ranger/gui/ui.py12
-rw-r--r--ranger/gui/widgets/browsercolumn.py90
-rw-r--r--ranger/gui/widgets/browserview.py100
-rw-r--r--ranger/gui/widgets/console.py77
-rw-r--r--ranger/gui/widgets/pager.py82
-rw-r--r--ranger/gui/widgets/statusbar.py13
-rw-r--r--ranger/gui/widgets/titlebar.py57
-rw-r--r--ranger/help/movement.py23
-rw-r--r--ranger/shared/settings.py176
-rw-r--r--test/tc_direction.py80
-rw-r--r--test/tc_signal.py134
75 files changed, 1990 insertions, 3442 deletions
diff --git a/INSTALL b/INSTALL
index d14d3891..5fc5ca6b 100644
--- a/INSTALL
+++ b/INSTALL
@@ -35,16 +35,6 @@ though you might want to read the Makefile first)
    python -c 'import sys; print("\n".join(sys.path))'
 
 
-3. Optionally, you can activate an extra feature: When you exit ranger,
-   the directory of the current shell can be changed to the last visited
-   directory in ranger.  To do so, add this alias to your shell rc file:
-
-   alias rng="source ranger ranger"
-
-   (Unfortunately this feature is shell dependent.  It has been
-   successfully tested with BASH and ZSH only.)
-
-
 Uninstalling
 ============
 
diff --git a/Makefile b/Makefile
index ac7b0502..05c565e6 100644
--- a/Makefile
+++ b/Makefile
@@ -71,10 +71,10 @@ cleandoc:
 	test -d $(DOCDIR) && rm -f -- $(DOCDIR)/*.html
 
 clean:
-	find . -regex [^\s]\*.py[co]$ | xargs rm -f --
+	find . -regex .\*.py[co]\$$ -exec rm -f -- {} \;
 
 test:
-	./all_tests.py
+	./all_tests.py 1
 
 edit:
 	@$(EDITOR) ranger.py Makefile README COPYING HACKING INSTALL $(shell find ranger test -regex .\*py$ )
@@ -89,16 +89,4 @@ commit: test
 	@git citool
 
 snapshot:
-	git archive HEAD | gzip > $(NAME)-$(VERSION)-$(shell git rev-list HEAD | head -n 1 | cut -b 1-8).tar.gz
-
-minimal_snapshot:
-	@echo 'This is not quite working well. I will abort now' && false
-	git checkout -b no_help
-	git rm -rf doc
-	git rm -rf test
-	git rm all_tests.py
-	git rm TODO
-	git commit -a -m'removed documentation'
-	git archive HEAD | gzip > $(NAME)-$(VERSION)-$(shell git rev-list HEAD | head -n 1 | cut -b 1-8).tar.gz
-	git reset --hard no_help^
-	git branch -D no_help
+	git archive HEAD | gzip > $(NAME)-$(VERSION)-$(shell git rev-parse HEAD | cut -b 1-8).tar.gz
diff --git a/README b/README
index b97b5ed7..07837688 100644
--- a/README
+++ b/README
@@ -26,6 +26,7 @@ About
 
 * Author:          Roman Zimbelmann
 * Email:           romanz@lavabit.com
+* Website:         http://savannah.nongnu.org/projects/ranger
 * Git repo:        http://git.savannah.gnu.org/cgit/ranger.git
 * Version:         1.0.4
 
@@ -90,9 +91,8 @@ Now use the arrow keys to navigate, press enter to open a file.
 
 A list of commands with short descriptions can be viewed by
 pressing "?" inside the program and following the instructions.
-The file code/keys.rb contains all key combinations, so that's another
-place you may want to check out.
-More extensive documentation will be written when enough users ask me to :)
+The file ranger/defaults/keys.py contains all key combinations, so that's
+another place you may want to check out.
 
 
 Opening Files with Ranger
@@ -122,3 +122,16 @@ information, check out the source code.
 
 Also, see the file HACKING for more detailed instructions on
 modifying the program.
+
+
+Tips
+----
+
+Change the directory of your parent shell when you exit ranger:
+
+ranger() {
+    $(which ranger) $@ &&
+    cd "$(grep \^\' ~/.ranger/bookmarks | cut -b3-)"
+}
+
+This can be put into your ~/.bashrc or something similar.
diff --git a/TODO b/TODO
index 17991c40..a0c7f03a 100644
--- a/TODO
+++ b/TODO
@@ -47,8 +47,8 @@ General
    (X) #63  10/02/15  limit filesize in previews
    ( ) #64  10/02/25  scroll in previews
    (X) #66  10/02/28  explain how colorschemes work
-   ( ) #70  10/03/14  mouse handler for titlebar
-   ( ) #71  10/03/21  previews: black/whitelist + read file
+   (X) #70  10/03/14  mouse handler for titlebar
+   (X) #71  10/03/21  previews: black/whitelist + read file
 
 
 Bugs
@@ -60,8 +60,8 @@ Bugs
    (X) #25  10/01/06  directories sometimes dont reload correctly
    (X) #26  10/01/06  :delete on symlinks of directories fails
    (X) #31  10/01/06  ^C breaks cd-after-exit by stopping sourced shell script
-   ( ) #40  10/01/17  freeze with unavailable sshfs
-          Looks like I need threads for that...
+   (X) #40  10/01/17  freeze with unavailable sshfs
+          Not rangers fault (?)
    (X) #41  10/01/17  capital file extensions are not recognized
    (X) #46  10/01/19  old username displayed after using su
    (X) #49  10/01/19  fix unit tests :'(
@@ -70,10 +70,11 @@ Bugs
    ( ) #60  10/02/05  utf support improvable
    (X) #62  10/02/15  curs_set can raise an exception
    (X) #65  10/02/16  "source ranger ranger some/file.txt" shouldn't cd after exit
-   ( ) #67  10/03/08  terminal title in tty
+   (X) #67  10/03/08  terminal title in tty
    (X) #69  10/03/11  tab-completion breaks with Apps subclass
-   ( ) #73  10/03/21  when clicking on the first column, it goes 1x down
-   ( ) #74  10/03/21  console doesn't scroll
+   (X) #73  10/03/21  when clicking on the first column, it goes 1x down
+   (X) #74  10/03/21  console doesn't scroll
+   ( ) #78  10/03/31  broken preview when deleting all files in a directory
 
 
 Ideas
@@ -83,8 +84,11 @@ Ideas
    (X) #27  10/01/06  hide bookmarks in list which contain hidden dir
    (X) #28  10/01/06  use regexp instead of string for searching
    ( ) #33  10/01/08  accelerate mousewheel speed
-   ( ) #45  10/01/18  hooks for events like setting changes
+   (X) #45  10/01/18  hooks for events like setting changes
    ( ) #53  10/01/23  merge fm and environment
    ( ) #68  10/03/10  threads, to seperate ui and loading
    ( ) #72  10/03/21  ranger daemon which does the slow io tasks
+   ( ) #75  10/03/28  navigate in history
+   (X) #76  10/03/28  save history between sessions
+   (X) #77  10/03/28  colorscheme overlay in options.py
 
diff --git a/doc/cd-after-exit.txt b/doc/cd-after-exit.txt
deleted file mode 100644
index ee300518..00000000
--- a/doc/cd-after-exit.txt
+++ /dev/null
@@ -1,161 +0,0 @@
-The "cd-after-exit" Feature
-===========================
-
-Abstract
---------
-
-This document explains the troublesome implementation of the "cd-after-exit"
-feature.
-
-This is written for developers who wonder how it's working.
-
-
-Specification
--------------
-
-When the feature is enabled, ranger will attempt to change the directory of
-the parent shell (from which ranger is run) to the last visited directory
-when ranger is exited.
-
-This task is, by its nature, shell dependent.  As a bash or zsh user,
-I focused on the implementation for those two shells and left the
-addition of support for csh, ksh, and other shells to those who actually use
-those shells.
-
-
-What's the problem?
--------------------
-
-Shells have several limitations, the implementation could not be done easily
-because:
-
-1. It is not possible to use something like system('cd xyz') at the end.
-This command would run in a new shell and wouldn't change the directory
-of the parent shell at all.
-
-2. Using exec('cd xyz') is not possible either, since 'cd' is a command
-which is directly integrated in to the shell and can not be run this way.
-
-
-Redirection of streams
-----------------------
-
-The only way I found is using cd `program` from inside the shell to change
-the directory to whatever `program` prints to the stdout:
-
-    bash$ cd `echo ..`
-
-Since the user interface still has to be printed, we simply redirect it to
-the stderr.  It is not sufficient however to change sys.stdout to sys.stderr,
-since curses seems not to be aware of sys.stdout and continues to print out
-the interface to the actual stdout.
-
-So what I did was swap the stdout and stderr of the whole ranger process on
-the shell command line by using:
-
-    bash$ cd `ranger 3>&1 1>&2 2>&3 3>&-`
-
-Since errors are now printed to the stdout, we have do this in ranger:
-    sys.stderr = sys.__stdout__
-
-And at the end, write the current directory to the stdout, which is now
-reachable via sys.__stderr__ due to the redirections:
-    sys.__stderr__.write(last_visited_directory)
-
-To inform the ranger process about these changes, we add a --cd-after-exit
-switch which:
-    bash$ cd `ranger --cd-after-exit 3>&1 1>&2 2>&3 3>&-`
-
-
-Argument passing
-----------------
-
-This works well enough, but there are two remaining problems:
-
-1. How to pass arguments to ranger?
-
-2. How to memorize that line? Although you can just copy+paste it
-into your bashrc and create an alias, the complexity of the line
-could lead to errors.
-
-Both problems are solved by putting the command in a file:
-
-run.sh:
-    cd "`ranger --cd-after-exit \"$@\" 3>&1 1>&2 2>&3 3>&-`"
-
-The $@ is responsible for argument passing.  By using the source command,
-the file will be evaluated without creating a distinct new shell.
-
-    bash$ source run.sh arg1 ... argN
-
-To add flexibility, replace the name "ranger" in the command to the first
-argument.  Now it requires you to pass the name of the ranger command to
-the script as the first argument:
-
-run.sh:
-    RANGER="$1"
-    shift
-    cd "`$RANGER --cd-after-exit \"$@\" 3>&1 1>&2 2>&3 3>&-`"
-
-
-Put it in a nutshell
---------------------
-
-I didn't want to have 2 files for the main program and wanted just one
-file at /usr/bin/ranger.  So I used this trick to merge both files into one:
-
-    #!/usr/bin/python
-    """":
-    <shell code>
-    """
-    <python code>
-
-If you run this file with python, or simply by typing ranger, the program will
-run normally.  If you, however, run this file by sourcing it into the shell,
-like you did with run.sh, the cd-after-exit mode will be activated.
-
-Now the way of running ranger with the cd-after-exit feature is:
-
-    bash$ source /path/to/ranger.py /path/to/ranger.py
-
-or, if properly installed:
-
-    bash$ source ranger ranger
-
-A convenient way of using this feature is adding this line to your bashrc:
-
-    alias rn='source ranger ranger'
-
-
-Open issues
------------
-
-Unfortunately there is some redundancy: you have to type the path to ranger
-twice.  I know of no way to fix this, because it is not possible to get the
-filename of the file currently being sourced.
-
-Example:
-
-    bash$ echo 'source sourced.sh' > main.sh
-    bash$ echo 'echo $0 $@' > sourced.sh
-    bash$ bash main.sh
-    main.sh
-
-If you find a way to make this print out 'sourced.sh', let me know. :)
-
-Another thing: If Ctrl+C is pressed anywhere in the program, the execution
-of the sourced shell script is stopped and the feature stops working.
-
-This was handled by using a script like that:
-
-    ranger_exec="$1"
-    shift
-    trap "" INT
-    exec 3< <($ranger_exec --cd-after-exit $@ 3>&1 1>&2 2>&3 3>&-)
-    while read ranger_output; do false; done <&3
-    cd "$ranger_output"
-    #...and some clean ups
-
-but that won't work in zsh for some reason, so I took it out again.
-
-Dec 25, 2009
diff --git a/doc/pick.sh b/doc/pick.sh
deleted file mode 100755
index e5f18da4..00000000
--- a/doc/pick.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-# I work on a branch (named hut) which contains commits
-# that should not be part of the standard distribution.
-#
-# This script picks all the good commits from hut and
-# adds them to the master branch.
-# Bad commits are marked with a "custom:" at the beginning
-# of the commit message.
-
-MASTER_BRANCH='master'
-CUSTOM_BRANCH='hut'
-ORIGINAL_BRANCH=`git branch 2>/dev/null|grep -e ^* | tr -d \*\ `
-
-git checkout -m $MASTER_BRANCH
-
-while read -r hash tag rest; do
-	if [ $tag != 'custom:' ]; then
-		git cherry-pick $hash || exit 1
-	fi
-done < <(git log --oneline --no-color $MASTER_BRANCH..$CUSTOM_BRANCH | tac)
-
-git checkout -m $CUSTOM_BRANCH
-git rebase $MASTER_BRANCH
-git checkout -m $ORIGINAL_BRANCH
diff --git a/doc/pydoc/ranger.colorschemes.default.html b/doc/pydoc/ranger.colorschemes.default.html
index 5c5dbcc9..23173585 100644
--- a/doc/pydoc/ranger.colorschemes.default.html
+++ b/doc/pydoc/ranger.colorschemes.default.html
@@ -39,7 +39,7 @@
     
 <tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
 <td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="ranger.gui.colorscheme.html#ColorScheme">ranger.gui.colorscheme.ColorScheme</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
+<dt><font face="helvetica, arial"><a href="ranger.gui.colorscheme.html#ColorScheme">ranger.gui.colorscheme.ColorScheme</a>(<a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a>)
 </font></dt><dd>
 <dl>
 <dt><font face="helvetica, arial"><a href="ranger.colorschemes.default.html#Default">Default</a>
@@ -56,6 +56,7 @@
 <td width="100%"><dl><dt>Method resolution order:</dt>
 <dd><a href="ranger.colorschemes.default.html#Default">Default</a></dd>
 <dd><a href="ranger.gui.colorscheme.html#ColorScheme">ranger.gui.colorscheme.ColorScheme</a></dd>
+<dd><a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a></dd>
 <dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
 </dl>
 <hr>
@@ -76,13 +77,17 @@ colors&nbsp;for&nbsp;faster&nbsp;access.</tt></dd></dl>
 Ready&nbsp;to&nbsp;use&nbsp;for&nbsp;curses.setattr()</tt></dd></dl>
 
 <hr>
-Data descriptors inherited from <a href="ranger.gui.colorscheme.html#ColorScheme">ranger.gui.colorscheme.ColorScheme</a>:<br>
+Data descriptors inherited from <a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a>:<br>
 <dl><dt><strong>__dict__</strong></dt>
 <dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
 </dl>
 <dl><dt><strong>__weakref__</strong></dt>
 <dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
 </dl>
+<hr>
+Data and other attributes inherited from <a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a>:<br>
+<dl><dt><strong>settings</strong> = {}</dl>
+
 </td></tr></table></td></tr></table><p>
 <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
 <tr bgcolor="#55aa55">
diff --git a/doc/pydoc/ranger.colorschemes.jungle.html b/doc/pydoc/ranger.colorschemes.jungle.html
index 41f1a80c..c5a919a6 100644
--- a/doc/pydoc/ranger.colorschemes.jungle.html
+++ b/doc/pydoc/ranger.colorschemes.jungle.html
@@ -57,6 +57,7 @@
 <dd><a href="ranger.colorschemes.jungle.html#Scheme">Scheme</a></dd>
 <dd><a href="ranger.colorschemes.default.html#Default">ranger.colorschemes.default.Default</a></dd>
 <dd><a href="ranger.gui.colorscheme.html#ColorScheme">ranger.gui.colorscheme.ColorScheme</a></dd>
+<dd><a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a></dd>
 <dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
 </dl>
 <hr>
@@ -77,13 +78,17 @@ colors&nbsp;for&nbsp;faster&nbsp;access.</tt></dd></dl>
 Ready&nbsp;to&nbsp;use&nbsp;for&nbsp;curses.setattr()</tt></dd></dl>
 
 <hr>
-Data descriptors inherited from <a href="ranger.gui.colorscheme.html#ColorScheme">ranger.gui.colorscheme.ColorScheme</a>:<br>
+Data descriptors inherited from <a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a>:<br>
 <dl><dt><strong>__dict__</strong></dt>
 <dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
 </dl>
 <dl><dt><strong>__weakref__</strong></dt>
 <dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
 </dl>
+<hr>
+Data and other attributes inherited from <a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a>:<br>
+<dl><dt><strong>settings</strong> = {}</dl>
+
 </td></tr></table></td></tr></table><p>
 <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
 <tr bgcolor="#55aa55">
diff --git a/doc/pydoc/ranger.colorschemes.snow.html b/doc/pydoc/ranger.colorschemes.snow.html
index b0e88d84..3d7b77b4 100644
--- a/doc/pydoc/ranger.colorschemes.snow.html
+++ b/doc/pydoc/ranger.colorschemes.snow.html
@@ -39,7 +39,7 @@
     
 <tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
 <td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="ranger.gui.colorscheme.html#ColorScheme">ranger.gui.colorscheme.ColorScheme</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
+<dt><font face="helvetica, arial"><a href="ranger.gui.colorscheme.html#ColorScheme">ranger.gui.colorscheme.ColorScheme</a>(<a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a>)
 </font></dt><dd>
 <dl>
 <dt><font face="helvetica, arial"><a href="ranger.colorschemes.snow.html#Snow">Snow</a>
@@ -56,6 +56,7 @@
 <td width="100%"><dl><dt>Method resolution order:</dt>
 <dd><a href="ranger.colorschemes.snow.html#Snow">Snow</a></dd>
 <dd><a href="ranger.gui.colorscheme.html#ColorScheme">ranger.gui.colorscheme.ColorScheme</a></dd>
+<dd><a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a></dd>
 <dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
 </dl>
 <hr>
@@ -76,13 +77,17 @@ colors&nbsp;for&nbsp;faster&nbsp;access.</tt></dd></dl>
 Ready&nbsp;to&nbsp;use&nbsp;for&nbsp;curses.setattr()</tt></dd></dl>
 
 <hr>
-Data descriptors inherited from <a href="ranger.gui.colorscheme.html#ColorScheme">ranger.gui.colorscheme.ColorScheme</a>:<br>
+Data descriptors inherited from <a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a>:<br>
 <dl><dt><strong>__dict__</strong></dt>
 <dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
 </dl>
 <dl><dt><strong>__weakref__</strong></dt>
 <dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
 </dl>
+<hr>
+Data and other attributes inherited from <a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a>:<br>
+<dl><dt><strong>settings</strong> = {}</dl>
+
 </td></tr></table></td></tr></table><p>
 <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
 <tr bgcolor="#55aa55">
diff --git a/doc/pydoc/ranger.defaults.options.html b/doc/pydoc/ranger.defaults.options.html
index 76e7089d..fae9598c 100644
--- a/doc/pydoc/ranger.defaults.options.html
+++ b/doc/pydoc/ranger.defaults.options.html
@@ -32,8 +32,9 @@ of&nbsp;the&nbsp;values&nbsp;stay&nbsp;the&nbsp;same.</tt></p>
     
 <tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
 <td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="ranger.colorschemes.html">ranger.colorschemes</a><br>
+</td><td width="25%" valign=top><a href="ranger.gui.color.html">ranger.gui.color</a><br>
 </td><td width="25%" valign=top><a href="re.html">re</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
+</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
 <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
 <tr bgcolor="#55aa55">
 <td colspan=3 valign=bottom>&nbsp;<br>
@@ -43,7 +44,8 @@ of&nbsp;the&nbsp;values&nbsp;stay&nbsp;the&nbsp;same.</tt></p>
 <td width="100%"><strong>autosave_bookmarks</strong> = True<br>
 <strong>collapse_preview</strong> = True<br>
 <strong>colorscheme</strong> = 'default'<br>
-<strong>directories_first</strong> = True<br>
+<strong>colorscheme_overlay</strong> = None<br>
+<strong>draw_bookmark_borders</strong> = True<br>
 <strong>draw_borders</strong> = False<br>
 <strong>flushinput</strong> = True<br>
 <strong>hidden_filter</strong> = &lt;_sre.SRE_Pattern object&gt;<br>
@@ -51,11 +53,14 @@ of&nbsp;the&nbsp;values&nbsp;stay&nbsp;the&nbsp;same.</tt></p>
 <strong>max_history_size</strong> = 20<br>
 <strong>preview_directories</strong> = True<br>
 <strong>preview_files</strong> = True<br>
-<strong>reverse</strong> = False<br>
+<strong>save_console_history</strong> = True<br>
 <strong>scroll_offset</strong> = 2<br>
 <strong>shorten_title</strong> = 3<br>
 <strong>show_cursor</strong> = False<br>
 <strong>show_hidden</strong> = False<br>
 <strong>sort</strong> = 'basename'<br>
+<strong>sort_case_insensitive</strong> = False<br>
+<strong>sort_directories_first</strong> = True<br>
+<strong>sort_reverse</strong> = False<br>
 <strong>update_title</strong> = True</td></tr></table>
 </body></html>
\ No newline at end of file
diff --git a/doc/pydoc/ranger.ext.html b/doc/pydoc/ranger.ext.html
index d58c1b87..a625bf53 100644
--- a/doc/pydoc/ranger.ext.html
+++ b/doc/pydoc/ranger.ext.html
@@ -29,6 +29,7 @@
 <a href="ranger.ext.openstruct.html">openstruct</a><br>
 <a href="ranger.ext.shell_escape.html">shell_escape</a><br>
 <a href="ranger.ext.shutil_generatorized.html">shutil_generatorized</a><br>
-</td><td width="25%" valign=top><a href="ranger.ext.waitpid_no_intr.html">waitpid_no_intr</a><br>
+</td><td width="25%" valign=top><a href="ranger.ext.signal_dispatcher.html">signal_dispatcher</a><br>
+<a href="ranger.ext.waitpid_no_intr.html">waitpid_no_intr</a><br>
 </td></tr></table></td></tr></table>
 </body></html>
\ No newline at end of file
diff --git a/doc/pydoc/ranger.fsobject.directory.html b/doc/pydoc/ranger.fsobject.directory.html
index 3def97f7..23481285 100644
--- a/doc/pydoc/ranger.fsobject.directory.html
+++ b/doc/pydoc/ranger.fsobject.directory.html
@@ -86,6 +86,8 @@
 Methods defined here:<br>
 <dl><dt><a name="Directory-__bool__"><strong>__bool__</strong></a> = <a href="#Directory-__nonzero__">__nonzero__</a>(self)</dt></dl>
 
+<dl><dt><a name="Directory-__del__"><strong>__del__</strong></a>(self)</dt></dl>
+
 <dl><dt><a name="Directory-__eq__"><strong>__eq__</strong></a>(self, other)</dt><dd><tt>Check&nbsp;for&nbsp;equality&nbsp;of&nbsp;the&nbsp;directories&nbsp;paths</tt></dd></dl>
 
 <dl><dt><a name="Directory-__hash__"><strong>__hash__</strong></a>(self)</dt></dl>
@@ -125,6 +127,10 @@ outdated&nbsp;or&nbsp;not&nbsp;done&nbsp;yet</tt></dd></dl>
 
 <dl><dt><a name="Directory-move_to_obj"><strong>move_to_obj</strong></a>(self, arg)</dt></dl>
 
+<dl><dt><a name="Directory-request_reload"><strong>request_reload</strong></a>(self)</dt></dl>
+
+<dl><dt><a name="Directory-request_resort"><strong>request_resort</strong></a>(self)</dt></dl>
+
 <dl><dt><a name="Directory-search_fnc"><strong>search_fnc</strong></a>(self, fnc, forward<font color="#909090">=True</font>)</dt></dl>
 
 <dl><dt><a name="Directory-set_cycle_list"><strong>set_cycle_list</strong></a>(self, lst)</dt></dl>
@@ -141,6 +147,8 @@ outdated&nbsp;or&nbsp;not&nbsp;done&nbsp;yet</tt></dd></dl>
 
 <hr>
 Data and other attributes defined here:<br>
+<dl><dt><strong>content_outdated</strong> = False</dl>
+
 <dl><dt><strong>cycle_list</strong> = None</dl>
 
 <dl><dt><strong>disk_usage</strong> = 0</dl>
@@ -167,17 +175,13 @@ Data and other attributes defined here:<br>
 
 <dl><dt><strong>mount_path</strong> = '/'</dl>
 
-<dl><dt><strong>old_directories_first</strong> = None</dl>
-
 <dl><dt><strong>old_filter</strong> = None</dl>
 
 <dl><dt><strong>old_hidden_filter</strong> = None</dl>
 
-<dl><dt><strong>old_reverse</strong> = None</dl>
-
 <dl><dt><strong>old_show_hidden</strong> = None</dl>
 
-<dl><dt><strong>old_sort</strong> = None</dl>
+<dl><dt><strong>order_outdated</strong> = False</dl>
 
 <dl><dt><strong>scroll_begin</strong> = 0</dl>
 
@@ -187,6 +191,8 @@ Data and other attributes defined here:<br>
 
 <hr>
 Methods inherited from <a href="ranger.fsobject.fsobject.html#FileSystemObject">ranger.fsobject.fsobject.FileSystemObject</a>:<br>
+<dl><dt><a name="Directory-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
+
 <dl><dt><a name="Directory-__str__"><strong>__str__</strong></a>(self)</dt><dd><tt>returns&nbsp;a&nbsp;string&nbsp;containing&nbsp;the&nbsp;absolute&nbsp;path</tt></dd></dl>
 
 <dl><dt><a name="Directory-get_description"><strong>get_description</strong></a>(self)</dt></dl>
@@ -375,6 +381,7 @@ Data descriptors inherited from <a href="exceptions.html#BaseException">exceptio
     
 <tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
 <td width="100%"><dl><dt><a name="-sort_by_basename"><strong>sort_by_basename</strong></a>(path)</dt><dd><tt>returns&nbsp;path.basename&nbsp;(for&nbsp;sorting)</tt></dd></dl>
+ <dl><dt><a name="-sort_by_basename_icase"><strong>sort_by_basename_icase</strong></a>(path)</dt><dd><tt>returns&nbsp;case-insensitive&nbsp;path.basename&nbsp;(for&nbsp;sorting)</tt></dd></dl>
  <dl><dt><a name="-sort_by_directory"><strong>sort_by_directory</strong></a>(path)</dt><dd><tt>returns&nbsp;0&nbsp;if&nbsp;path&nbsp;is&nbsp;a&nbsp;directory,&nbsp;otherwise&nbsp;1&nbsp;(for&nbsp;sorting)</tt></dd></dl>
  <dl><dt><a name="-time"><strong>time</strong></a>(...)</dt><dd><tt><a href="#-time">time</a>()&nbsp;-&gt;&nbsp;floating&nbsp;point&nbsp;number<br>
 &nbsp;<br>
diff --git a/doc/pydoc/ranger.fsobject.file.html b/doc/pydoc/ranger.fsobject.file.html
index b0816bd0..5365ad59 100644
--- a/doc/pydoc/ranger.fsobject.file.html
+++ b/doc/pydoc/ranger.fsobject.file.html
@@ -54,6 +54,14 @@
 <dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
 </dl>
 <hr>
+Methods defined here:<br>
+<dl><dt><a name="File-is_binary"><strong>is_binary</strong></a>(self)</dt></dl>
+
+<hr>
+Data descriptors defined here:<br>
+<dl><dt><strong>firstbytes</strong></dt>
+</dl>
+<hr>
 Data and other attributes defined here:<br>
 <dl><dt><strong>is_file</strong> = True</dl>
 
@@ -61,6 +69,8 @@ Data and other attributes defined here:<br>
 Methods inherited from <a href="ranger.fsobject.fsobject.html#FileSystemObject">ranger.fsobject.fsobject.FileSystemObject</a>:<br>
 <dl><dt><a name="File-__init__"><strong>__init__</strong></a>(self, path)</dt></dl>
 
+<dl><dt><a name="File-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
+
 <dl><dt><a name="File-__str__"><strong>__str__</strong></a>(self)</dt><dd><tt>returns&nbsp;a&nbsp;string&nbsp;containing&nbsp;the&nbsp;absolute&nbsp;path</tt></dd></dl>
 
 <dl><dt><a name="File-get_description"><strong>get_description</strong></a>(self)</dt></dl>
@@ -169,5 +179,13 @@ Data and other attributes inherited from <a href="ranger.shared.mimetype.html#Mi
 Data and other attributes inherited from <a href="ranger.shared.html#FileManagerAware">ranger.shared.FileManagerAware</a>:<br>
 <dl><dt><strong>fm</strong> = None</dl>
 
-</td></tr></table></td></tr></table>
+</td></tr></table></td></tr></table><p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#55aa55">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
+    
+<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%"><strong>N_FIRST_BYTES</strong> = 20<br>
+<strong>control_characters</strong> = set(['<font color="#c040c0">\x00</font>', '<font color="#c040c0">\x01</font>', '<font color="#c040c0">\x02</font>', '<font color="#c040c0">\x03</font>', '<font color="#c040c0">\x04</font>', '<font color="#c040c0">\x05</font>', ...])</td></tr></table>
 </body></html>
\ No newline at end of file
diff --git a/doc/pydoc/ranger.fsobject.fsobject.html b/doc/pydoc/ranger.fsobject.fsobject.html
index 0681dfaa..e619b2f9 100644
--- a/doc/pydoc/ranger.fsobject.fsobject.html
+++ b/doc/pydoc/ranger.fsobject.fsobject.html
@@ -25,6 +25,14 @@
 #&nbsp;along&nbsp;with&nbsp;this&nbsp;program.&nbsp;&nbsp;If&nbsp;not,&nbsp;see&nbsp;&lt;<a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>&gt;.</tt></p>
 <p>
 <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#aa55cc">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
+    
+<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="time.html">time</a><br>
+</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
 <tr bgcolor="#ee77aa">
 <td colspan=3 valign=bottom>&nbsp;<br>
 <font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
@@ -62,6 +70,8 @@
 Methods defined here:<br>
 <dl><dt><a name="FileSystemObject-__init__"><strong>__init__</strong></a>(self, path)</dt></dl>
 
+<dl><dt><a name="FileSystemObject-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
+
 <dl><dt><a name="FileSystemObject-__str__"><strong>__str__</strong></a>(self)</dt><dd><tt>returns&nbsp;a&nbsp;string&nbsp;containing&nbsp;the&nbsp;absolute&nbsp;path</tt></dd></dl>
 
 <dl><dt><a name="FileSystemObject-get_description"><strong>get_description</strong></a>(self)</dt></dl>
diff --git a/doc/pydoc/ranger.fsobject.loader.html b/doc/pydoc/ranger.fsobject.loader.html
index c387f773..e4124e75 100644
--- a/doc/pydoc/ranger.fsobject.loader.html
+++ b/doc/pydoc/ranger.fsobject.loader.html
@@ -105,7 +105,7 @@ Stop&nbsp;after&nbsp;approximately&nbsp;self.<strong>seconds_of_work_time</stron
 
 <hr>
 Data and other attributes defined here:<br>
-<dl><dt><strong>seconds_of_work_time</strong> = 0.029999999999999999</dl>
+<dl><dt><strong>seconds_of_work_time</strong> = 0.10000000000000001</dl>
 
 <hr>
 Data and other attributes inherited from <a href="ranger.shared.html#FileManagerAware">ranger.shared.FileManagerAware</a>:<br>
diff --git a/doc/pydoc/ranger.gui.colorscheme.html b/doc/pydoc/ranger.gui.colorscheme.html
index 52b56a83..c44d0873 100644
--- a/doc/pydoc/ranger.gui.colorscheme.html
+++ b/doc/pydoc/ranger.gui.colorscheme.html
@@ -36,13 +36,22 @@ If&nbsp;your&nbsp;colorscheme-file&nbsp;contains&nbsp;more&nbsp;than&nbsp;one&nb
 colorscheme&nbsp;=&nbsp;colorschemes.filename.classname</tt></p>
 <p>
 <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#aa55cc">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
+    
+<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="os.html">os</a><br>
+</td><td width="25%" valign=top><a href="ranger.html">ranger</a><br>
+</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
 <tr bgcolor="#ee77aa">
 <td colspan=3 valign=bottom>&nbsp;<br>
 <font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
     
 <tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
 <td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
+<dt><font face="helvetica, arial"><a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
 </font></dt><dd>
 <dl>
 <dt><font face="helvetica, arial"><a href="ranger.gui.colorscheme.html#ColorScheme">ColorScheme</a>
@@ -53,7 +62,7 @@ colorscheme&nbsp;=&nbsp;colorschemes.filename.classname</tt></p>
 <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
 <tr bgcolor="#ffc8d8">
 <td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ColorScheme">class <strong>ColorScheme</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
+<font color="#000000" face="helvetica, arial"><a name="ColorScheme">class <strong>ColorScheme</strong></a>(<a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a>)</font></td></tr>
     
 <tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
 <td colspan=2><tt>This&nbsp;is&nbsp;the&nbsp;class&nbsp;that&nbsp;colorschemes&nbsp;must&nbsp;inherit&nbsp;from.<br>
@@ -62,7 +71,13 @@ it&nbsp;defines&nbsp;<a href="#ColorScheme-get">get</a>()&nbsp;<br>
 it&nbsp;defines&nbsp;the&nbsp;<a href="#ColorScheme-get">get</a>()&nbsp;method,&nbsp;which&nbsp;returns&nbsp;the&nbsp;color&nbsp;tuple<br>
 which&nbsp;fits&nbsp;to&nbsp;the&nbsp;given&nbsp;keys.<br>&nbsp;</tt></td></tr>
 <tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
+<td width="100%"><dl><dt>Method resolution order:</dt>
+<dd><a href="ranger.gui.colorscheme.html#ColorScheme">ColorScheme</a></dd>
+<dd><a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a></dd>
+<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
+</dl>
+<hr>
+Methods defined here:<br>
 <dl><dt><a name="ColorScheme-__init__"><strong>__init__</strong></a>(self)</dt></dl>
 
 <dl><dt><a name="ColorScheme-get"><strong>get</strong></a>(self, *keys)</dt><dd><tt>Returns&nbsp;the&nbsp;(fg,&nbsp;bg,&nbsp;attr)&nbsp;for&nbsp;the&nbsp;given&nbsp;keys.<br>
@@ -83,13 +98,17 @@ selected&nbsp;files&nbsp;have&nbsp;the&nbsp;color&nbsp;inverted.<br>
 Override&nbsp;this&nbsp;method&nbsp;in&nbsp;your&nbsp;own&nbsp;colorscheme.</tt></dd></dl>
 
 <hr>
-Data descriptors defined here:<br>
+Data descriptors inherited from <a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a>:<br>
 <dl><dt><strong>__dict__</strong></dt>
 <dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
 </dl>
 <dl><dt><strong>__weakref__</strong></dt>
 <dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
 </dl>
+<hr>
+Data and other attributes inherited from <a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a>:<br>
+<dl><dt><strong>settings</strong> = {}</dl>
+
 </td></tr></table></td></tr></table><p>
 <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
 <tr bgcolor="#eeaa77">
diff --git a/doc/pydoc/ranger.gui.defaultui.html b/doc/pydoc/ranger.gui.defaultui.html
index 3254b508..8318872a 100644
--- a/doc/pydoc/ranger.gui.defaultui.html
+++ b/doc/pydoc/ranger.gui.defaultui.html
@@ -95,7 +95,7 @@ Methods inherited from <a href="ranger.gui.ui.html#UI">ranger.gui.ui.UI</a>:<br>
 
 <dl><dt><a name="DefaultUI-destroy"><strong>destroy</strong></a>(self)</dt><dd><tt>Destroy&nbsp;all&nbsp;widgets&nbsp;and&nbsp;turn&nbsp;off&nbsp;curses</tt></dd></dl>
 
-<dl><dt><a name="DefaultUI-draw"><strong>draw</strong></a>(self)</dt><dd><tt>Erase&nbsp;the&nbsp;window,&nbsp;then&nbsp;draw&nbsp;all&nbsp;objects&nbsp;in&nbsp;the&nbsp;container</tt></dd></dl>
+<dl><dt><a name="DefaultUI-draw"><strong>draw</strong></a>(self)</dt><dd><tt>Draw&nbsp;all&nbsp;objects&nbsp;in&nbsp;the&nbsp;container</tt></dd></dl>
 
 <dl><dt><a name="DefaultUI-finalize"><strong>finalize</strong></a>(self)</dt><dd><tt>Finalize&nbsp;every&nbsp;object&nbsp;in&nbsp;container&nbsp;and&nbsp;refresh&nbsp;the&nbsp;window</tt></dd></dl>
 
diff --git a/doc/pydoc/ranger.gui.ui.html b/doc/pydoc/ranger.gui.ui.html
index abd01711..9beffb00 100644
--- a/doc/pydoc/ranger.gui.ui.html
+++ b/doc/pydoc/ranger.gui.ui.html
@@ -74,7 +74,7 @@ Methods defined here:<br>
 
 <dl><dt><a name="UI-destroy"><strong>destroy</strong></a>(self)</dt><dd><tt>Destroy&nbsp;all&nbsp;widgets&nbsp;and&nbsp;turn&nbsp;off&nbsp;curses</tt></dd></dl>
 
-<dl><dt><a name="UI-draw"><strong>draw</strong></a>(self)</dt><dd><tt>Erase&nbsp;the&nbsp;window,&nbsp;then&nbsp;draw&nbsp;all&nbsp;objects&nbsp;in&nbsp;the&nbsp;container</tt></dd></dl>
+<dl><dt><a name="UI-draw"><strong>draw</strong></a>(self)</dt><dd><tt>Draw&nbsp;all&nbsp;objects&nbsp;in&nbsp;the&nbsp;container</tt></dd></dl>
 
 <dl><dt><a name="UI-finalize"><strong>finalize</strong></a>(self)</dt><dd><tt>Finalize&nbsp;every&nbsp;object&nbsp;in&nbsp;container&nbsp;and&nbsp;refresh&nbsp;the&nbsp;window</tt></dd></dl>
 
diff --git a/doc/pydoc/ranger.gui.widgets.browsercolumn.html b/doc/pydoc/ranger.gui.widgets.browsercolumn.html
index 98700199..4b324217 100644
--- a/doc/pydoc/ranger.gui.widgets.browsercolumn.html
+++ b/doc/pydoc/ranger.gui.widgets.browsercolumn.html
@@ -186,5 +186,6 @@ Fractions&nbsp;of&nbsp;a&nbsp;second&nbsp;may&nbsp;be&nbsp;present&nbsp;if&nbsp;
 <font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
     
 <tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>PREVIEW_BLACKLIST</strong> = &lt;_sre.SRE_Pattern object&gt;</td></tr></table>
+<td width="100%"><strong>PREVIEW_BLACKLIST</strong> = &lt;_sre.SRE_Pattern object&gt;<br>
+<strong>PREVIEW_WHITELIST</strong> = &lt;_sre.SRE_Pattern object&gt;</td></tr></table>
 </body></html>
\ No newline at end of file
diff --git a/doc/pydoc/ranger.gui.widgets.console.html b/doc/pydoc/ranger.gui.widgets.console.html
index cdf17194..277c87bc 100644
--- a/doc/pydoc/ranger.gui.widgets.console.html
+++ b/doc/pydoc/ranger.gui.widgets.console.html
@@ -20,8 +20,9 @@ commands,&nbsp;searching&nbsp;and&nbsp;executing&nbsp;files.</tt></p>
 <tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
 <td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="ranger.defaults.commands.html">ranger.defaults.commands</a><br>
 </td><td width="25%" valign=top><a href="curses.html">curses</a><br>
+</td><td width="25%" valign=top><a href="ranger.html">ranger</a><br>
 </td><td width="25%" valign=top><a href="string.html">string</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
+</td></tr></table></td></tr></table><p>
 <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
 <tr bgcolor="#ee77aa">
 <td colspan=3 valign=bottom>&nbsp;<br>
@@ -102,6 +103,8 @@ Methods inherited from <a href="ranger.gui.widgets.console.html#Console">Console
 
 <dl><dt><a name="CommandConsole-delete_word"><strong>delete_word</strong></a>(self)</dt></dl>
 
+<dl><dt><a name="CommandConsole-destroy"><strong>destroy</strong></a>(self)</dt></dl>
+
 <dl><dt><a name="CommandConsole-draw"><strong>draw</strong></a>(self)</dt></dl>
 
 <dl><dt><a name="CommandConsole-finalize"><strong>finalize</strong></a>(self)</dt></dl>
@@ -134,6 +137,8 @@ Data and other attributes inherited from <a href="ranger.gui.widgets.console.htm
 
 <dl><dt><strong>history</strong> = None</dl>
 
+<dl><dt><strong>historypaths</strong> = []</dl>
+
 <dl><dt><strong>last_cursor_mode</strong> = None</dl>
 
 <dl><dt><strong>mode</strong> = None</dl>
@@ -163,9 +168,6 @@ Override&nbsp;this!</tt></dd></dl>
 <dl><dt><a name="CommandConsole-contains_point"><strong>contains_point</strong></a>(self, y, x)</dt><dd><tt>Test&nbsp;whether&nbsp;the&nbsp;point&nbsp;(with&nbsp;absolute&nbsp;coordinates)&nbsp;lies<br>
 within&nbsp;the&nbsp;boundaries&nbsp;of&nbsp;this&nbsp;object.</tt></dd></dl>
 
-<dl><dt><a name="CommandConsole-destroy"><strong>destroy</strong></a>(self)</dt><dd><tt>Called&nbsp;when&nbsp;the&nbsp;object&nbsp;is&nbsp;destroyed.<br>
-Override&nbsp;this!</tt></dd></dl>
-
 <dl><dt><a name="CommandConsole-poke"><strong>poke</strong></a>(self)</dt><dd><tt>Called&nbsp;before&nbsp;drawing,&nbsp;even&nbsp;if&nbsp;invisible</tt></dd></dl>
 
 <dl><dt><a name="CommandConsole-resize"><strong>resize</strong></a>(self, y, x, hei<font color="#909090">=None</font>, wid<font color="#909090">=None</font>)</dt><dd><tt>Resize&nbsp;the&nbsp;widget</tt></dd></dl>
@@ -236,6 +238,8 @@ Methods defined here:<br>
 
 <dl><dt><a name="Console-delete_word"><strong>delete_word</strong></a>(self)</dt></dl>
 
+<dl><dt><a name="Console-destroy"><strong>destroy</strong></a>(self)</dt></dl>
+
 <dl><dt><a name="Console-draw"><strong>draw</strong></a>(self)</dt></dl>
 
 <dl><dt><a name="Console-execute"><strong>execute</strong></a>(self)</dt></dl>
@@ -272,6 +276,8 @@ Data and other attributes defined here:<br>
 
 <dl><dt><strong>history</strong> = None</dl>
 
+<dl><dt><strong>historypaths</strong> = []</dl>
+
 <dl><dt><strong>last_cursor_mode</strong> = None</dl>
 
 <dl><dt><strong>mode</strong> = None</dl>
@@ -303,9 +309,6 @@ Override&nbsp;this!</tt></dd></dl>
 <dl><dt><a name="Console-contains_point"><strong>contains_point</strong></a>(self, y, x)</dt><dd><tt>Test&nbsp;whether&nbsp;the&nbsp;point&nbsp;(with&nbsp;absolute&nbsp;coordinates)&nbsp;lies<br>
 within&nbsp;the&nbsp;boundaries&nbsp;of&nbsp;this&nbsp;object.</tt></dd></dl>
 
-<dl><dt><a name="Console-destroy"><strong>destroy</strong></a>(self)</dt><dd><tt>Called&nbsp;when&nbsp;the&nbsp;object&nbsp;is&nbsp;destroyed.<br>
-Override&nbsp;this!</tt></dd></dl>
-
 <dl><dt><a name="Console-poke"><strong>poke</strong></a>(self)</dt><dd><tt>Called&nbsp;before&nbsp;drawing,&nbsp;even&nbsp;if&nbsp;invisible</tt></dd></dl>
 
 <dl><dt><a name="Console-resize"><strong>resize</strong></a>(self, y, x, hei<font color="#909090">=None</font>, wid<font color="#909090">=None</font>)</dt><dd><tt>Resize&nbsp;the&nbsp;widget</tt></dd></dl>
@@ -381,6 +384,8 @@ Methods inherited from <a href="ranger.gui.widgets.console.html#Console">Console
 
 <dl><dt><a name="ConsoleWithTab-delete_word"><strong>delete_word</strong></a>(self)</dt></dl>
 
+<dl><dt><a name="ConsoleWithTab-destroy"><strong>destroy</strong></a>(self)</dt></dl>
+
 <dl><dt><a name="ConsoleWithTab-draw"><strong>draw</strong></a>(self)</dt></dl>
 
 <dl><dt><a name="ConsoleWithTab-execute"><strong>execute</strong></a>(self)</dt></dl>
@@ -415,6 +420,8 @@ Data and other attributes inherited from <a href="ranger.gui.widgets.console.htm
 
 <dl><dt><strong>history</strong> = None</dl>
 
+<dl><dt><strong>historypaths</strong> = []</dl>
+
 <dl><dt><strong>last_cursor_mode</strong> = None</dl>
 
 <dl><dt><strong>mode</strong> = None</dl>
@@ -446,9 +453,6 @@ Override&nbsp;this!</tt></dd></dl>
 <dl><dt><a name="ConsoleWithTab-contains_point"><strong>contains_point</strong></a>(self, y, x)</dt><dd><tt>Test&nbsp;whether&nbsp;the&nbsp;point&nbsp;(with&nbsp;absolute&nbsp;coordinates)&nbsp;lies<br>
 within&nbsp;the&nbsp;boundaries&nbsp;of&nbsp;this&nbsp;object.</tt></dd></dl>
 
-<dl><dt><a name="ConsoleWithTab-destroy"><strong>destroy</strong></a>(self)</dt><dd><tt>Called&nbsp;when&nbsp;the&nbsp;object&nbsp;is&nbsp;destroyed.<br>
-Override&nbsp;this!</tt></dd></dl>
-
 <dl><dt><a name="ConsoleWithTab-poke"><strong>poke</strong></a>(self)</dt><dd><tt>Called&nbsp;before&nbsp;drawing,&nbsp;even&nbsp;if&nbsp;invisible</tt></dd></dl>
 
 <dl><dt><a name="ConsoleWithTab-resize"><strong>resize</strong></a>(self, y, x, hei<font color="#909090">=None</font>, wid<font color="#909090">=None</font>)</dt><dd><tt>Resize&nbsp;the&nbsp;widget</tt></dd></dl>
@@ -554,6 +558,8 @@ Methods inherited from <a href="ranger.gui.widgets.console.html#Console">Console
 
 <dl><dt><a name="OpenConsole-delete_word"><strong>delete_word</strong></a>(self)</dt></dl>
 
+<dl><dt><a name="OpenConsole-destroy"><strong>destroy</strong></a>(self)</dt></dl>
+
 <dl><dt><a name="OpenConsole-draw"><strong>draw</strong></a>(self)</dt></dl>
 
 <dl><dt><a name="OpenConsole-finalize"><strong>finalize</strong></a>(self)</dt></dl>
@@ -584,6 +590,8 @@ Data and other attributes inherited from <a href="ranger.gui.widgets.console.htm
 
 <dl><dt><strong>history</strong> = None</dl>
 
+<dl><dt><strong>historypaths</strong> = []</dl>
+
 <dl><dt><strong>last_cursor_mode</strong> = None</dl>
 
 <dl><dt><strong>mode</strong> = None</dl>
@@ -613,9 +621,6 @@ Override&nbsp;this!</tt></dd></dl>
 <dl><dt><a name="OpenConsole-contains_point"><strong>contains_point</strong></a>(self, y, x)</dt><dd><tt>Test&nbsp;whether&nbsp;the&nbsp;point&nbsp;(with&nbsp;absolute&nbsp;coordinates)&nbsp;lies<br>
 within&nbsp;the&nbsp;boundaries&nbsp;of&nbsp;this&nbsp;object.</tt></dd></dl>
 
-<dl><dt><a name="OpenConsole-destroy"><strong>destroy</strong></a>(self)</dt><dd><tt>Called&nbsp;when&nbsp;the&nbsp;object&nbsp;is&nbsp;destroyed.<br>
-Override&nbsp;this!</tt></dd></dl>
-
 <dl><dt><a name="OpenConsole-poke"><strong>poke</strong></a>(self)</dt><dd><tt>Called&nbsp;before&nbsp;drawing,&nbsp;even&nbsp;if&nbsp;invisible</tt></dd></dl>
 
 <dl><dt><a name="OpenConsole-resize"><strong>resize</strong></a>(self, y, x, hei<font color="#909090">=None</font>, wid<font color="#909090">=None</font>)</dt><dd><tt>Resize&nbsp;the&nbsp;widget</tt></dd></dl>
@@ -716,6 +721,8 @@ Methods inherited from <a href="ranger.gui.widgets.console.html#Console">Console
 
 <dl><dt><a name="QuickCommandConsole-delete_word"><strong>delete_word</strong></a>(self)</dt></dl>
 
+<dl><dt><a name="QuickCommandConsole-destroy"><strong>destroy</strong></a>(self)</dt></dl>
+
 <dl><dt><a name="QuickCommandConsole-draw"><strong>draw</strong></a>(self)</dt></dl>
 
 <dl><dt><a name="QuickCommandConsole-finalize"><strong>finalize</strong></a>(self)</dt></dl>
@@ -746,6 +753,8 @@ Data and other attributes inherited from <a href="ranger.gui.widgets.console.htm
 
 <dl><dt><strong>history</strong> = None</dl>
 
+<dl><dt><strong>historypaths</strong> = []</dl>
+
 <dl><dt><strong>last_cursor_mode</strong> = None</dl>
 
 <dl><dt><strong>mode</strong> = None</dl>
@@ -775,9 +784,6 @@ Override&nbsp;this!</tt></dd></dl>
 <dl><dt><a name="QuickCommandConsole-contains_point"><strong>contains_point</strong></a>(self, y, x)</dt><dd><tt>Test&nbsp;whether&nbsp;the&nbsp;point&nbsp;(with&nbsp;absolute&nbsp;coordinates)&nbsp;lies<br>
 within&nbsp;the&nbsp;boundaries&nbsp;of&nbsp;this&nbsp;object.</tt></dd></dl>
 
-<dl><dt><a name="QuickCommandConsole-destroy"><strong>destroy</strong></a>(self)</dt><dd><tt>Called&nbsp;when&nbsp;the&nbsp;object&nbsp;is&nbsp;destroyed.<br>
-Override&nbsp;this!</tt></dd></dl>
-
 <dl><dt><a name="QuickCommandConsole-poke"><strong>poke</strong></a>(self)</dt><dd><tt>Called&nbsp;before&nbsp;drawing,&nbsp;even&nbsp;if&nbsp;invisible</tt></dd></dl>
 
 <dl><dt><a name="QuickCommandConsole-resize"><strong>resize</strong></a>(self, y, x, hei<font color="#909090">=None</font>, wid<font color="#909090">=None</font>)</dt><dd><tt>Resize&nbsp;the&nbsp;widget</tt></dd></dl>
@@ -888,6 +894,8 @@ Methods inherited from <a href="ranger.gui.widgets.console.html#Console">Console
 
 <dl><dt><a name="QuickOpenConsole-delete_word"><strong>delete_word</strong></a>(self)</dt></dl>
 
+<dl><dt><a name="QuickOpenConsole-destroy"><strong>destroy</strong></a>(self)</dt></dl>
+
 <dl><dt><a name="QuickOpenConsole-draw"><strong>draw</strong></a>(self)</dt></dl>
 
 <dl><dt><a name="QuickOpenConsole-finalize"><strong>finalize</strong></a>(self)</dt></dl>
@@ -918,6 +926,8 @@ Data and other attributes inherited from <a href="ranger.gui.widgets.console.htm
 
 <dl><dt><strong>history</strong> = None</dl>
 
+<dl><dt><strong>historypaths</strong> = []</dl>
+
 <dl><dt><strong>last_cursor_mode</strong> = None</dl>
 
 <dl><dt><strong>mode</strong> = None</dl>
@@ -947,9 +957,6 @@ Override&nbsp;this!</tt></dd></dl>
 <dl><dt><a name="QuickOpenConsole-contains_point"><strong>contains_point</strong></a>(self, y, x)</dt><dd><tt>Test&nbsp;whether&nbsp;the&nbsp;point&nbsp;(with&nbsp;absolute&nbsp;coordinates)&nbsp;lies<br>
 within&nbsp;the&nbsp;boundaries&nbsp;of&nbsp;this&nbsp;object.</tt></dd></dl>
 
-<dl><dt><a name="QuickOpenConsole-destroy"><strong>destroy</strong></a>(self)</dt><dd><tt>Called&nbsp;when&nbsp;the&nbsp;object&nbsp;is&nbsp;destroyed.<br>
-Override&nbsp;this!</tt></dd></dl>
-
 <dl><dt><a name="QuickOpenConsole-poke"><strong>poke</strong></a>(self)</dt><dd><tt>Called&nbsp;before&nbsp;drawing,&nbsp;even&nbsp;if&nbsp;invisible</tt></dd></dl>
 
 <dl><dt><a name="QuickOpenConsole-resize"><strong>resize</strong></a>(self, y, x, hei<font color="#909090">=None</font>, wid<font color="#909090">=None</font>)</dt><dd><tt>Resize&nbsp;the&nbsp;widget</tt></dd></dl>
@@ -1031,6 +1038,8 @@ Methods inherited from <a href="ranger.gui.widgets.console.html#Console">Console
 
 <dl><dt><a name="SearchConsole-delete_word"><strong>delete_word</strong></a>(self)</dt></dl>
 
+<dl><dt><a name="SearchConsole-destroy"><strong>destroy</strong></a>(self)</dt></dl>
+
 <dl><dt><a name="SearchConsole-draw"><strong>draw</strong></a>(self)</dt></dl>
 
 <dl><dt><a name="SearchConsole-finalize"><strong>finalize</strong></a>(self)</dt></dl>
@@ -1063,6 +1072,8 @@ Data and other attributes inherited from <a href="ranger.gui.widgets.console.htm
 
 <dl><dt><strong>history</strong> = None</dl>
 
+<dl><dt><strong>historypaths</strong> = []</dl>
+
 <dl><dt><strong>last_cursor_mode</strong> = None</dl>
 
 <dl><dt><strong>mode</strong> = None</dl>
@@ -1092,9 +1103,6 @@ Override&nbsp;this!</tt></dd></dl>
 <dl><dt><a name="SearchConsole-contains_point"><strong>contains_point</strong></a>(self, y, x)</dt><dd><tt>Test&nbsp;whether&nbsp;the&nbsp;point&nbsp;(with&nbsp;absolute&nbsp;coordinates)&nbsp;lies<br>
 within&nbsp;the&nbsp;boundaries&nbsp;of&nbsp;this&nbsp;object.</tt></dd></dl>
 
-<dl><dt><a name="SearchConsole-destroy"><strong>destroy</strong></a>(self)</dt><dd><tt>Called&nbsp;when&nbsp;the&nbsp;object&nbsp;is&nbsp;destroyed.<br>
-Override&nbsp;this!</tt></dd></dl>
-
 <dl><dt><a name="SearchConsole-poke"><strong>poke</strong></a>(self)</dt><dd><tt>Called&nbsp;before&nbsp;drawing,&nbsp;even&nbsp;if&nbsp;invisible</tt></dd></dl>
 
 <dl><dt><a name="SearchConsole-resize"><strong>resize</strong></a>(self, y, x, hei<font color="#909090">=None</font>, wid<font color="#909090">=None</font>)</dt><dd><tt>Resize&nbsp;the&nbsp;widget</tt></dd></dl>
diff --git a/doc/pydoc/ranger.gui.widgets.titlebar.html b/doc/pydoc/ranger.gui.widgets.titlebar.html
index 419eb5b1..0938452d 100644
--- a/doc/pydoc/ranger.gui.widgets.titlebar.html
+++ b/doc/pydoc/ranger.gui.widgets.titlebar.html
@@ -47,6 +47,8 @@ It&nbsp;displays&nbsp;the&nbsp;current&nbsp;path&nbsp;among&nbsp;other&nbsp;thin
 </dl>
 <hr>
 Methods defined here:<br>
+<dl><dt><a name="TitleBar-click"><strong>click</strong></a>(self, event)</dt><dd><tt>Handle&nbsp;a&nbsp;MouseEvent</tt></dd></dl>
+
 <dl><dt><a name="TitleBar-draw"><strong>draw</strong></a>(self)</dt></dl>
 
 <hr>
@@ -74,9 +76,6 @@ item&nbsp;can&nbsp;be&nbsp;an&nbsp;iterable&nbsp;like&nbsp;[y,&nbsp;x]&nbsp;or&n
 
 <dl><dt><a name="TitleBar-__str__"><strong>__str__</strong></a>(self)</dt></dl>
 
-<dl><dt><a name="TitleBar-click"><strong>click</strong></a>(self, event)</dt><dd><tt>Called&nbsp;when&nbsp;a&nbsp;mouse&nbsp;key&nbsp;is&nbsp;pressed&nbsp;and&nbsp;self.<strong>focused</strong>&nbsp;is&nbsp;True.<br>
-Override&nbsp;this!</tt></dd></dl>
-
 <dl><dt><a name="TitleBar-contains_point"><strong>contains_point</strong></a>(self, y, x)</dt><dd><tt>Test&nbsp;whether&nbsp;the&nbsp;point&nbsp;(with&nbsp;absolute&nbsp;coordinates)&nbsp;lies<br>
 within&nbsp;the&nbsp;boundaries&nbsp;of&nbsp;this&nbsp;object.</tt></dd></dl>
 
diff --git a/doc/pydoc/ranger.html b/doc/pydoc/ranger.html
index cba764cb..d741ca6b 100644
--- a/doc/pydoc/ranger.html
+++ b/doc/pydoc/ranger.html
@@ -57,7 +57,7 @@ Has&nbsp;the&nbsp;same&nbsp;arguments&nbsp;as&nbsp;print()&nbsp;in&nbsp;python3.
 <strong>__license__</strong> = 'GPL3'<br>
 <strong>__maintainer__</strong> = 'Roman Zimbelmann'<br>
 <strong>__version__</strong> = '1.0.4'<br>
-<strong>arg</strong> = {'cd_after_exit': False, 'debug': False, 'flags'...n': False, 'confdir': '~/.ranger', 'targets': []}</td></tr></table><p>
+<strong>arg</strong> = {'debug': False, 'flags': '', 'mode': 0, 'clean': False, 'confdir': '~/.ranger', 'targets': []}</td></tr></table><p>
 <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
 <tr bgcolor="#7799ee">
 <td colspan=3 valign=bottom>&nbsp;<br>
diff --git a/doc/pydoc/ranger.shared.settings.html b/doc/pydoc/ranger.shared.settings.html
index 29d43fc6..f50c6569 100644
--- a/doc/pydoc/ranger.shared.settings.html
+++ b/doc/pydoc/ranger.shared.settings.html
@@ -30,10 +30,8 @@
 <font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
     
 <tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="ranger.html">ranger</a><br>
-</td><td width="25%" valign=top><a href="types.html">types</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
+<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="ranger.html">ranger</a><br>
+</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
 <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
 <tr bgcolor="#ee77aa">
 <td colspan=3 valign=bottom>&nbsp;<br>
@@ -47,11 +45,59 @@
 <dt><font face="helvetica, arial"><a href="ranger.shared.settings.html#SettingsAware">SettingsAware</a>
 </font></dt></dl>
 </dd>
+<dt><font face="helvetica, arial"><a href="ranger.ext.signal_dispatcher.html#SignalDispatcher">ranger.ext.signal_dispatcher.SignalDispatcher</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
+</font></dt><dd>
+<dl>
+<dt><font face="helvetica, arial"><a href="ranger.shared.settings.html#SettingObject">SettingObject</a>
+</font></dt></dl>
+</dd>
 </dl>
  <p>
 <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
 <tr bgcolor="#ffc8d8">
 <td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="SettingObject">class <strong>SettingObject</strong></a>(<a href="ranger.ext.signal_dispatcher.html#SignalDispatcher">ranger.ext.signal_dispatcher.SignalDispatcher</a>)</font></td></tr>
+    
+<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%"><dl><dt>Method resolution order:</dt>
+<dd><a href="ranger.shared.settings.html#SettingObject">SettingObject</a></dd>
+<dd><a href="ranger.ext.signal_dispatcher.html#SignalDispatcher">ranger.ext.signal_dispatcher.SignalDispatcher</a></dd>
+<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
+</dl>
+<hr>
+Methods defined here:<br>
+<dl><dt><a name="SettingObject-__getattr__"><strong>__getattr__</strong></a>(self, name)</dt></dl>
+
+<dl><dt><a name="SettingObject-__getitem__"><strong>__getitem__</strong></a> = <a href="#SettingObject-__getattr__">__getattr__</a>(self, name)</dt></dl>
+
+<dl><dt><a name="SettingObject-__init__"><strong>__init__</strong></a>(self)</dt></dl>
+
+<dl><dt><a name="SettingObject-__setattr__"><strong>__setattr__</strong></a>(self, name, value)</dt></dl>
+
+<dl><dt><a name="SettingObject-__setitem__"><strong>__setitem__</strong></a> = <a href="#SettingObject-__setattr__">__setattr__</a>(self, name, value)</dt></dl>
+
+<hr>
+Methods inherited from <a href="ranger.ext.signal_dispatcher.html#SignalDispatcher">ranger.ext.signal_dispatcher.SignalDispatcher</a>:<br>
+<dl><dt><a name="SettingObject-signal_bind"><strong>signal_bind</strong></a>(self, signal_name, function, priority<font color="#909090">=0.5</font>, weak<font color="#909090">=False</font>)</dt></dl>
+
+<dl><dt><a name="SettingObject-signal_clear"><strong>signal_clear</strong></a> = __init__(self)</dt></dl>
+
+<dl><dt><a name="SettingObject-signal_emit"><strong>signal_emit</strong></a>(self, signal_name, **kw)</dt></dl>
+
+<dl><dt><a name="SettingObject-signal_unbind"><strong>signal_unbind</strong></a>(self, signal_handler)</dt></dl>
+
+<hr>
+Data descriptors inherited from <a href="ranger.ext.signal_dispatcher.html#SignalDispatcher">ranger.ext.signal_dispatcher.SignalDispatcher</a>:<br>
+<dl><dt><strong>__dict__</strong></dt>
+<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
+</dl>
+<dl><dt><strong>__weakref__</strong></dt>
+<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
+</dl>
+</td></tr></table> <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
 <font color="#000000" face="helvetica, arial"><a name="SettingsAware">class <strong>SettingsAware</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
     
 <tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
@@ -70,18 +116,11 @@ Data and other attributes defined here:<br>
 
 </td></tr></table></td></tr></table><p>
 <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-check_option_types"><strong>check_option_types</strong></a>(opt)</dt></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
 <tr bgcolor="#55aa55">
 <td colspan=3 valign=bottom>&nbsp;<br>
 <font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
     
 <tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>ALLOWED_SETTINGS</strong> = {'autosave_bookmarks': &lt;type 'bool'&gt;, 'collapse_preview': &lt;type 'bool'&gt;, 'colorscheme': &lt;type 'str'&gt;, 'directories_first': &lt;type 'bool'&gt;, 'draw_borders': &lt;type 'bool'&gt;, 'flushinput': &lt;type 'bool'&gt;, 'hidden_filter': &lt;function &lt;lambda&gt;&gt;, 'max_filesize_for_preview': (&lt;type 'int'&gt;, &lt;type 'NoneType'&gt;), 'max_history_size': (&lt;type 'int'&gt;, &lt;type 'NoneType'&gt;), 'preview_directories': &lt;type 'bool'&gt;, ...}</td></tr></table>
+<td width="100%"><strong>ALLOWED_SETTINGS</strong> = {'autosave_bookmarks': &lt;type 'bool'&gt;, 'collapse_preview': &lt;type 'bool'&gt;, 'colorscheme': &lt;type 'str'&gt;, 'colorscheme_overlay': (&lt;type 'NoneType'&gt;, &lt;type 'function'&gt;), 'draw_bookmark_borders': &lt;type 'bool'&gt;, 'draw_borders': &lt;type 'bool'&gt;, 'flushinput': &lt;type 'bool'&gt;, 'hidden_filter': &lt;function &lt;lambda&gt;&gt;, 'max_filesize_for_preview': (&lt;type 'int'&gt;, &lt;type 'NoneType'&gt;), 'max_history_size': (&lt;type 'int'&gt;, &lt;type 'NoneType'&gt;), ...}<br>
+<strong>COMPAT_MAP</strong> = {'sort_directories_first': 'directories_first', 'sort_reverse': 'reverse'}</td></tr></table>
 </body></html>
\ No newline at end of file
diff --git a/doc/pydoc/test.html b/doc/pydoc/test.html
index 2a0ce426..69b6f644 100644
--- a/doc/pydoc/test.html
+++ b/doc/pydoc/test.html
@@ -38,8 +38,9 @@
 <a href="test.tc_ext.html">tc_ext</a><br>
 </td><td width="25%" valign=top><a href="test.tc_history.html">tc_history</a><br>
 <a href="test.tc_keyapi.html">tc_keyapi</a><br>
-<a href="test.tc_ui.html">tc_ui</a><br>
-</td><td width="25%" valign=top><a href="test.test.html">test</a><br>
+<a href="test.tc_signal.html">tc_signal</a><br>
+</td><td width="25%" valign=top><a href="test.tc_ui.html">tc_ui</a><br>
+<a href="test.test.html">test</a><br>
 </td></tr></table></td></tr></table><p>
 <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
 <tr bgcolor="#55aa55">
@@ -47,5 +48,5 @@
 <font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
     
 <tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>__all__</strong> = ['tc_keyapi', 'tc_history', 'tc_directory', 'tc_colorscheme', 'tc_commandlist', 'tc_displayable', 'tc_ui', 'tc_bookmarks', 'tc_ext']</td></tr></table>
+<td width="100%"><strong>__all__</strong> = ['tc_keyapi', 'tc_history', 'tc_colorscheme', 'tc_bookmarks', 'tc_ext', 'tc_directory', 'tc_commandlist', 'tc_colorscheme', 'tc_keyapi', 'tc_history', 'tc_commandlist', 'tc_signal', 'tc_displayable', 'tc_signal', 'tc_directory', 'tc_ui', 'tc_ui', 'tc_bookmarks', 'tc_ext', 'tc_displayable']</td></tr></table>
 </body></html>
\ No newline at end of file
diff --git a/doc/ranger.1 b/doc/ranger.1
new file mode 100644
index 00000000..9e1ab5a0
--- /dev/null
+++ b/doc/ranger.1
@@ -0,0 +1,213 @@
+.TH RANGER 1 ranger-1.0.4
+.SH NAME
+ranger - visual file manager
+.\"-----------------------------------------
+.SH SYNOPSIS
+.B ranger
+.R [OPTIONS] [FILE]
+.\"-----------------------------------------
+.SH DESCRIPTION
+Ranger is a file manager with an ncurses frontend written in Python.
+.P
+It is designed to give you a broader overview of the file system by displaying
+previews and backviews, dividing the screen into several columns.
+The keybindings are similar to those of other console programs like
+.BR vim ", " mutt " or " ncmpcpp
+so the usage will be intuitive and efficient.
+.\"-----------------------------------------
+.SH OPTIONS
+.TP
+--version
+Print the version and exit.
+.TP
+-h, --help
+Print a list of options and exit.
+.TP
+-d, --debug
+Activate the debug mode:  Whenever an error occurs, ranger will exit and
+print a full backtrace.  The default behaviour is to merely print the
+name of the exception in the statusbar/log and to try to keep running.
+.TP
+-c, --clean
+Activate the clean mode:  Ranger will not access or create any configuration
+files nor will it leave any traces on your system.  This is useful when
+your configuration is broken, when you want to avoid clutter, etc.
+.TP
+-r \fIdir\fR, --confdir=\fIdir\fR
+Define a different configuration directory.  The default is $HOME/.ranger.
+.TP
+-m \fIn\fR, --mode=\fIn\fR
+When a filename is supplied, make it run in mode \fIn\fR. Check the
+documentation for more information on modes.
+.TP
+-f \fIflags\fR, --flags=\fIflags\fR
+When a filename is supplied, make it run with the flags \fIflags\fR. Check the
+documentation for more information on flags.
+.\"-----------------------------------------
+.SH USAGE
+.\"-----------------------------------------
+.SS General Keybindings
+Many keybindings take an additional numeric argument.  Type \fI5j\fR to move
+down 5 lines, \fI10<Space>\fR to mark 10 files or \fI3?\fR to read the
+third chapter of the documentation.
+.TP
+h, j, k, l
+Move left, down, up, right
+.TP
+^D or J, ^U or K
+Move a half page down, up
+.TP
+H, L
+Move back and forward in the history
+.TP
+gg
+Move to the top
+.TP
+G
+Move to the bottom
+.TP
+^R
+Reload everything
+.TP
+^L
+Redraw the screen
+.TP
+yy
+Yank the selection.  (mark the files as copied)
+.TP
+dd
+Cut the selection
+.TP
+pp
+Paste the copied/cut files.  By default, this will not overwrite existing
+files.  To overwrite them, use \fBpo\fR.
+.TP
+m\fIX\fR
+Create a bookmark with the name \fIX\fR
+.TP
+`\fIX\fR
+Move to the bookmark with the name \fIX\fR
+.TP
+n, N
+Find the next file, the previous file.  You can define what to look for
+by typing c\fIX\fR.  If nothing is specified, pressing n will get you to
+the newest file in the directory.
+.TP
+o\fIX\fR
+Change the sort method (like in mutt)
+.TP
+z\fIX\fR
+Change settings
+.TP
+f
+Quickly navigate by entering a part of the filename
+.TP
+Space
+Mark a file
+.TP
+v, V
+Toggle the mark-status of all files, unmark all files
+.TP
+/
+Open the search console
+.TP
+:
+Open the command console
+.TP
+?
+Opens the help screen with more keybindings and documentation
+.\"-----------------------------------------
+.SS Keybindings for using Tabs
+Tabs are used to work in different directories in the same Ranger instance.
+.TP
+g\fIN\fR
+Open a tab. N has to be a number from 0 to 9. If the tab doesn't exist yet,
+it will be created.
+.TP
+gn, ^N
+Create a new tab.
+.TP
+gt, gT
+Go to the next or previous tab.  You can also use TAB and SHIFT+TAB.
+.TP
+gc, ^W
+Close the current tab.  The last tab cannot be closed.
+.P
+.\"-----------------------------------------
+.SS Mouse Usage
+.TP
+Left Mouse Button
+Click on something and you'll move there.
+To run a file, "enter" it, like a directory, by clicking on the preview.
+.TP
+Right Mouse Button
+Enter a directory
+.TP
+Scroll Wheel
+Scroll
+.\"-----------------------------------------
+.SS Commands
+.TP
+:delete
+Destroy all files in the selection with a roundhouse kick.  Ranger will
+ask for a confirmation if you attempt to delete multiple (marked) files or
+non-empty directories.
+.TP
+:rename \fInewname\fR
+Rename the current file.  Also try the keybinding A for appending something
+to a file name.
+.TP
+:quit
+Quit ranger.  The current directory will be bookmarked as ' so you can
+re-enter it by typing `` or '' the next time you start ranger.
+.\"-----------------------------------------
+.SH TIPS
+.SS
+Change the directory after exit
+A script like this in your bashrc would make you change the directory
+of your parent shell after exiting ranger:
+.nf
+
+ranger() {
+    $(which ranger) $@ &&
+    cd "$(grep \\^\\' ~/.ranger/bookmarks | cut -b3-)"
+}
+.\"-----------------------------------------
+.SH CONFIGURATION
+The files in
+.B ranger/defaults/
+can be copied into your configuration directory (by default, this is
+$HOME/.ranger) and customized according to your wishes.  
+.B ranger/defaults/options.py
+doesn't have to be copied completely though: Just define those settings
+you want to change and they will override the default values.
+Colorschemes can be placed in $HOME/.ranger/colorschemes.
+.P
+All configuration is done in Python.
+Each configuration file should contain sufficient documentation.
+.\"-----------------------------------------
+.SH COPYRIGHT
+Copyright \(co
+2009, 2010
+Roman Zimbelmann
+.P
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+There is NO warranty;
+not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+.\"-----------------------------------------
+.SH SEE ALSO
+The project page:
+.RB < http://savannah.nongnu.org/projects/ranger >
+.P
+The mailing list:
+.RB < http://savannah.nongnu.org/mail/?group=ranger >
+.\"-----------------------------------------
+.SH BUGS
+Since Chuck Norris, the Texas Ranger, watches over this project, there ought
+to be no bugs.  If you think otherwise, please report them here:
+.P
+.RB < http://savannah.nongnu.org/bugs/?group=ranger >
diff --git a/doc/uml.txt b/doc/uml.txt
deleted file mode 100644
index 67e84ee2..00000000
--- a/doc/uml.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-UML
-===
-
-The uml documents can be opened with bouml, althought there's
-not much useful, up-to-date information.
diff --git a/doc/uml/128002 b/doc/uml/128002
deleted file mode 100644
index 0149fe5f..00000000
--- a/doc/uml/128002
+++ /dev/null
@@ -1,1090 +0,0 @@
-format 70
-"ranger" // ranger
-  revision 23
-  modified_by 2 "hut"
-  // class settings
-  //class diagram settings
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  //use case diagram settings
-  package_name_in_tab default show_context default auto_label_position default draw_all_relations default class_drawing_mode default shadow default show_stereotype_properties default
-  //sequence diagram settings
-  show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default show_stereotype_properties default
-  //collaboration diagram settings
-  show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default show_stereotype_properties default
-  //object diagram settings
-   write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default show_stereotype_properties default
-  //component diagram settings
-  package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default
-  draw_component_as_icon default show_component_req_prov default show_component_rea default show_stereotype_properties default
-  //deployment diagram settings
-  package_name_in_tab default show_context default write_horizontally default auto_label_position default draw_all_relations default shadow default
-  draw_component_as_icon default show_component_req_prov default show_component_rea default show_stereotype_properties default
-  //state diagram settings
-  package_name_in_tab default show_context default auto_label_position default write_trans_label_horizontally default show_trans_definition default draw_all_relations default shadow default
-  show_activities default region_horizontally default drawing_language default show_stereotype_properties default
-  //activity diagram settings
-  package_name_in_tab default show_context default show_opaque_action_definition default auto_label_position default write_flow_label_horizontally default draw_all_relations default shadow default
-  show_infonote default drawing_language default show_stereotype_properties default
-  
-  classview 128002 "Classes"
-    //class diagram settings
-    draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-    //collaboration diagram settings
-    show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default show_stereotype_properties default
-    //object diagram settings
-     write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default show_stereotype_properties default
-    //sequence diagram settings
-    show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default show_stereotype_properties default
-    //state diagram settings
-    package_name_in_tab default show_context default auto_label_position default write_trans_label_horizontally default show_trans_definition default draw_all_relations default shadow default
-    show_activities default region_horizontally default drawing_language default show_stereotype_properties default
-    //class settings
-    //activity diagram settings
-    package_name_in_tab default show_context default show_opaque_action_definition default auto_label_position default write_flow_label_horizontally default draw_all_relations default shadow default
-    show_infonote default drawing_language default show_stereotype_properties default
-    classdiagram 134530 "Overview"
-      draw_all_relations no hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-      size A4
-    end
-
-    sequencediagram 141058 "Basic Logic"
-      show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default show_stereotype_properties default
-      overlapping_bars size A4
-    end
-
-    classdiagram 128002 "Displayable Hierarchy"
-      draw_all_relations no hide_attributes yes hide_operations yes hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-      class_color yellow 
-      size A4
-    end
-
-    class 128002 "Displayable"
-      abstract visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      classrelation 136322 // <aggregation>
-	relation_ref 135938 // <aggregation>
-      end
-
-      operation 134530 "draw"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 134658 "press"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 134786 "click"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 134914 "destroy"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 135042 "resize"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      classrelation 143234 // <generalisation>
-	relation 142850 ---|>
-	  a public
-	    python "${type}"
-	    classrelation_ref 143234 // <generalisation>
-	  b parent class_ref 142210 // EnvironmentAware
-      end
-
-      classrelation 143362 // <generalisation>
-	relation 142978 ---|>
-	  a public
-	    python "${type}"
-	    classrelation_ref 143362 // <generalisation>
-	  b parent class_ref 141954 // FileManagerAware
-      end
-
-      classrelation 150018 // <generalisation>
-	relation 149634 ---|>
-	  a public
-	    python "${type}"
-	    classrelation_ref 150018 // <generalisation>
-	  b parent class_ref 142082 // SettingsAware
-      end
-
-      classrelation 170882 // <association>
-	relation 169986 ----
-	  a role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 170882 // <association>
-	  b role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 171010 // <association>
-      end
-
-      classrelation 171778 // <association>
-	relation_ref 170370 // <association>
-      end
-
-      operation 149378 "finalize"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 149506 "color"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 149634 "contains_point"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-    end
-
-    class 128130 "UI"
-      abstract visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      classrelation 128258 // <generalisation>
-	relation 128258 ---|>
-	  a public
-	    python "${type}"
-	    classrelation_ref 128258 // <generalisation>
-	  b parent class_ref 128386 // DisplayableContainer
-      end
-
-      operation 148482 "handle_mouse"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 148610 "handle_key"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 148738 "get_next_key"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 148866 "setup"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 148994 "setup"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 149122 "redraw"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 149250 "update_size"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 171138 "initialize"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      classrelation 201090 // <aggregation>
-	relation 198658 o---
-	  a role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 201090 // <aggregation>
-	  b role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 201218 // <aggregation>
-      end
-    end
-
-    class 128258 "DefaultUI"
-      visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      classrelation 128002 // <generalisation>
-	relation 128002 ---|>
-	  a public
-	    python "${type}"
-	    classrelation_ref 128002 // <generalisation>
-	  b parent class_ref 128130 // UI
-      end
-
-      classrelation 171906 // <association>
-	relation 170498 ----
-	  a role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 171906 // <association>
-	  b role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 172034 // <association>
-      end
-
-      operation 171266 "open_console"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 171394 "scroll"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-    end
-
-    class 128386 "DisplayableContainer"
-      abstract visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      classrelation 128386 // <generalisation>
-	relation 128386 ---|>
-	  a public
-	    python "${type}"
-	    classrelation_ref 128386 // <generalisation>
-	  b parent class_ref 128002 // Displayable
-      end
-
-      classrelation 136194 // <aggregation>
-	relation 135938 o---
-	  a role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 136194 // <aggregation>
-	  b role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 136322 // <aggregation>
-      end
-
-      operation 149762 "get_focused_obj"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 149890 "add_obj"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-    end
-
-    class 135042 "TitleBar"
-      visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      classrelation 172674 // <generalisation>
-	relation 171010 ---|>
-	  a public
-	    python "${type}"
-	    classrelation_ref 172674 // <generalisation>
-	  b parent class_ref 156034 // Widget
-      end
-    end
-
-    class 135170 "BrowserColumn"
-      visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      classrelation 136066 // <aggregation>
-	relation_ref 135810 // <aggregation>
-      end
-
-      classrelation 193410 // <generalisation>
-	relation 191362 ---|>
-	  a public
-	    python "${type}"
-	    classrelation_ref 193410 // <generalisation>
-	  b parent class_ref 175746 // Pager
-      end
-    end
-
-    class 135298 "BrowserView"
-      visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      classrelation 135554 // <generalisation>
-	relation 135554 ---|>
-	  a public
-	    python "${type}"
-	    classrelation_ref 135554 // <generalisation>
-	  b parent class_ref 128386 // DisplayableContainer
-      end
-
-      classrelation 135938 // <aggregation>
-	relation 135810 o---
-	  a role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 135938 // <aggregation>
-	  b role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 136066 // <aggregation>
-      end
-
-      classrelation 172930 // <generalisation>
-	relation 171266 ---|>
-	  a public
-	    python "${type}"
-	    classrelation_ref 172930 // <generalisation>
-	  b parent class_ref 156034 // Widget
-      end
-
-      classrelation 200834 // <aggregation>
-	relation 198530 o---
-	  a role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 200834 // <aggregation>
-	  b role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 200962 // <aggregation>
-      end
-    end
-
-    class 135426 "Console"
-      visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      classrelation 172162 // <association>
-	relation 170626 ----
-	  a role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 172162 // <association>
-	  b role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 172290 // <association>
-      end
-
-      classrelation 172546 // <generalisation>
-	relation 170882 ---|>
-	  a public
-	    python "${type}"
-	    classrelation_ref 172546 // <generalisation>
-	  b parent class_ref 156034 // Widget
-      end
-
-      operation 163202 "open"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 163330 "close"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 163458 "clear"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 163586 "move"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 163714 "type_key"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 163842 "execute"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-    end
-
-    class 141954 "FileManagerAware"
-      visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-    end
-
-    class 142082 "SettingsAware"
-      visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-    end
-
-    class 142210 "EnvironmentAware"
-      visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-    end
-
-    class 148738 "Action"
-      abstract visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-    end
-
-    class 148866 "Command"
-      visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      classrelation 163714 // <aggregation>
-	relation_ref 162946 // <aggregation>
-      end
-
-      classrelation 170498 // <unidirectional association>
-	relation 169730 --->
-	  a role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 170498 // <unidirectional association>
-	  b parent class_ref 148738 // Action
-      end
-
-      operation 164226 "execute"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-    end
-
-    class 148994 "CommandList"
-      visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      classrelation 163586 // <aggregation>
-	relation 162946 o---
-	  a role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 163586 // <aggregation>
-	  b role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 163714 // <aggregation>
-      end
-
-      classrelation 172034 // <association>
-	relation_ref 170498 // <association>
-      end
-
-      classrelation 172290 // <association>
-	relation_ref 170626 // <association>
-      end
-
-      operation 164354 "rebuild_paths"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 164482 "bind"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-    end
-
-    class 149122 "Environment"
-      visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      classrelation 171394 // <aggregation>
-	relation 170242 o---
-	  a role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 171394 // <aggregation>
-	  b role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 171522 // <aggregation>
-      end
-
-      classrelation 171650 // <association>
-	relation 170370 ----
-	  a role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 171650 // <association>
-	  b role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 171778 // <association>
-      end
-
-      operation 171522 "garbage_collect"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 171650 "enter_dir"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-    end
-
-    class 149378 "FM"
-      visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      classrelation 156546 // <generalisation>
-	relation 156162 ---|>
-	  a public
-	    python "${type}"
-	    classrelation_ref 156546 // <generalisation>
-	  b parent class_ref 148738 // Action
-      end
-
-      classrelation 179714 // <unidirectional association>
-	relation 177922 --->
-	  a role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 179714 // <unidirectional association>
-	  b parent class_ref 149122 // Environment
-      end
-
-      classrelation 179842 // <unidirectional association>
-	relation 178050 --->
-	  a role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 179842 // <unidirectional association>
-	  b parent class_ref 128258 // DefaultUI
-      end
-
-      operation 141826 "initialize"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 141954 "loop"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-    end
-
-    class 155906 "FileSystemObject"
-      abstract visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      classrelation 171522 // <aggregation>
-	relation_ref 170242 // <aggregation>
-      end
-
-      classrelation 186754 // <association>
-	relation_ref 184706 // <association>
-      end
-
-      operation 163970 "load"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 164098 "go"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-    end
-
-    class 156034 "Widget"
-      abstract visibility package 
-      cpp_decl "${comment}${template}class ${name}${inherit} {
-${members}};
-${inlines}
-"
-      java_decl "${comment}${@}${visibility}interface ${name}${extends} {
-${members}}
-"
-      php_decl "${comment}${visibility}interface ${name} {
-${members}}
-"
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl "${comment}${abstract}${local}interface ${name}${inherit} {
-${members}};
-"
-      explicit_switch_type ""
-      
-      classrelation 172418 // <generalisation>
-	relation 170754 ---|>
-	  a public
-	    python "${type}"
-	    classrelation_ref 172418 // <generalisation>
-	  b parent class_ref 128002 // Displayable
-      end
-
-      classrelation 201218 // <aggregation>
-	relation_ref 198658 // <aggregation>
-      end
-    end
-
-    classinstance 134530 "cl"
-      type class_ref 148994 // CommandList
-      attributes
-        end
-      relations
-        end
-    end
-
-    classinstance 134658 "console_cl"
-      type class_ref 148994 // CommandList
-      attributes
-        end
-      relations
-        end
-    end
-
-    class 169218 "Main"
-      visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-    end
-
-    class 175746 "Pager"
-      visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      classrelation 193282 // <generalisation>
-	relation 191234 ---|>
-	  a public
-	    python "${type}"
-	    classrelation_ref 193282 // <generalisation>
-	  b parent class_ref 156034 // Widget
-      end
-
-      classrelation 200962 // <aggregation>
-	relation_ref 198530 // <aggregation>
-      end
-    end
-
-    class 175874 "StatusBar"
-      visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      classrelation 193538 // <generalisation>
-	relation 191490 ---|>
-	  a public
-	    python "${type}"
-	    classrelation_ref 193538 // <generalisation>
-	  b parent class_ref 156034 // Widget
-      end
-    end
-
-    class 176130 "TaskView"
-      visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      classrelation 193794 // <generalisation>
-	relation 191746 ---|>
-	  a public
-	    python "${type}"
-	    classrelation_ref 193794 // <generalisation>
-	  b parent class_ref 156034 // Widget
-      end
-    end
-  end
-end
diff --git a/doc/uml/128002.diagram b/doc/uml/128002.diagram
deleted file mode 100644
index 09164d16..00000000
--- a/doc/uml/128002.diagram
+++ /dev/null
@@ -1,217 +0,0 @@
-format 70
-
-classcanvas 128002 class_ref 128002 // Displayable
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 262.407 180.109 2000
-end
-classcanvas 128130 class_ref 128130 // UI
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 182.852 363.327 2000
-end
-classcanvas 128258 class_ref 128258 // DefaultUI
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 159.717 439.896 2000
-end
-classcanvas 128642 class_ref 128386 // DisplayableContainer
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 185.704 276.894 2006
-end
-classcanvas 129410 class_ref 135042 // TitleBar
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 681.233 245.65 2000
-end
-classcanvas 129666 class_ref 135170 // BrowserColumn
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 404.259 478.907 2000
-end
-classcanvas 129922 class_ref 135298 // BrowserView
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 504.3 562.8 2000
-end
-classcanvas 131970 class_ref 135426 // Console
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 681.435 305.987 2000
-end
-note 132738 "Only one instance, since it initializes curses!"
-  xyzwh 28 354 2012 89 113
-classcanvas 132994 class_ref 141954 // FileManagerAware
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 393 33 2000
-end
-classcanvas 133122 class_ref 142082 // SettingsAware
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 249 33 2000
-end
-classcanvas 133250 class_ref 142210 // EnvironmentAware
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 71 32 2005
-end
-classcanvas 134530 class_ref 156034 // Widget
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 567 305 2000
-end
-note 136962 "Defines no methods, just for classification"
-  xyzwh 577 138 2000 135 77
-classcanvas 137218 class_ref 175746 // Pager
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 473 398 2000
-end
-classcanvas 138370 class_ref 175874 // StatusBar
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 682 364 2000
-end
-classcanvas 142850 class_ref 176130 // TaskView
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 681 562 2000
-end
-note 143362 "Inherits from pager to display file content"
-  xyzwh 292 619 2000 135 75
-relationcanvas 128386 relation_ref 128002 // <generalisation>
-  decenter_begin 529
-  from ref 128258 z 2001 to ref 128130
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 128898 relation_ref 128386 // <generalisation>
-  decenter_begin 625
-  decenter_end 339
-  from ref 128642 z 2007 to ref 128002
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 130178 relation_ref 135554 // <generalisation>
-  geometry VHr
-  from ref 129922 z 2007 to point 272 581
-  line 139906 z 2007 to ref 128642
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 130562 relation_ref 135810 // <aggregation>
-  decenter_begin 200
-  decenter_end 905
-  from ref 129922 z 2001 to ref 129666
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 130690 relation_ref 135938 // <aggregation>
-  decenter_begin 720
-  decenter_end 504
-  from ref 128642 z 2007 to ref 128002
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 132354 relation_ref 128258 // <generalisation>
-  decenter_begin 487
-  decenter_end 106
-  from ref 128130 z 2007 to ref 128642
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 133378 relation_ref 142850 // <generalisation>
-  geometry VHV
-  from ref 128002 z 2006 to point 311 125
-  line 141314 z 2006 to point 149 125
-  line 141442 z 2006 to ref 133250
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 133506 relation_ref 142978 // <generalisation>
-  geometry VHV
-  from ref 128002 z 2001 to point 311 125
-  line 141058 z 2001 to point 469 125
-  line 141186 z 2001 to ref 132994
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 134274 relation_ref 149634 // <generalisation>
-  geometry VHV
-  from ref 128002 z 2001 to point 311 125
-  line 141570 z 2001 to point 311 125
-  line 141698 z 2001 to ref 133122
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 134658 relation_ref 170754 // <generalisation>
-  geometry HVH
-  from ref 134530 z 2001 to point 463 324
-  line 145154 z 2001 to point 463 199
-  line 145282 z 2001 to ref 128002
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 134786 relation_ref 170882 // <generalisation>
-  geometry HVH
-  from ref 131970 z 2001 to point 655 324
-  line 138114 z 2001 to point 655 324
-  line 138242 z 2001 to ref 134530
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 134914 relation_ref 171010 // <generalisation>
-  geometry HVH
-  from ref 129410 z 2001 to point 655 264
-  line 137858 z 2001 to point 655 324
-  line 137986 z 2001 to ref 134530
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 135938 relation_ref 171266 // <generalisation>
-  decenter_begin 836
-  from ref 129922 z 2001 to ref 134530
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 137346 relation_ref 191234 // <generalisation>
-  geometry VHV
-  from ref 137218 z 2001 to point 500 370
-  line 147330 z 2001 to point 598 370
-  line 147458 z 2001 to ref 134530
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 137602 relation_ref 191362 // <generalisation>
-  decenter_begin 722
-  from ref 129666 z 2001 to ref 137218
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 138498 relation_ref 191490 // <generalisation>
-  geometry HVH
-  from ref 138370 z 2001 to point 655 383
-  line 138626 z 2001 to point 655 324
-  line 138754 z 2001 to ref 134530
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 142978 relation_ref 191746 // <generalisation>
-  geometry HVH
-  from ref 142850 z 2001 to point 655 581
-  line 143106 z 2001 to point 655 324
-  line 143234 z 2001 to ref 134530
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 145538 relation_ref 198530 // <aggregation>
-  geometry HVr
-  decenter_begin 713
-  decenter_end 581
-  from ref 129922 z 2001 to point 559 417
-  line 146306 z 2001 to ref 137218
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 146434 relation_ref 198658 // <aggregation>
-  geometry HVH
-  from ref 128130 z 2001 to point 394 382
-  line 146562 z 2001 to point 394 324
-  line 146690 z 2001 to ref 134530
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-line 132866 -_-_
-  from ref 132738 z 2013 to ref 128130
-line 137090 -_-_
-  from ref 136962 z 2001 to ref 134530
-line 143490 -_-_
-  from ref 143362 z 2001 to ref 129666
-end
diff --git a/doc/uml/134530 b/doc/uml/134530
deleted file mode 100644
index 9f91d104..00000000
--- a/doc/uml/134530
+++ /dev/null
@@ -1,145 +0,0 @@
-format 70
-"builtin" // builtin
-  revision 3
-  modified_by 2 "hut"
-  // class settings
-  //class diagram settings
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  //use case diagram settings
-  package_name_in_tab default show_context default auto_label_position default draw_all_relations default class_drawing_mode default shadow default show_stereotype_properties default
-  //sequence diagram settings
-  show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default show_stereotype_properties default
-  //collaboration diagram settings
-  show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default show_stereotype_properties default
-  //object diagram settings
-   write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default show_stereotype_properties default
-  //component diagram settings
-  package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default
-  draw_component_as_icon default show_component_req_prov default show_component_rea default show_stereotype_properties default
-  //deployment diagram settings
-  package_name_in_tab default show_context default write_horizontally default auto_label_position default draw_all_relations default shadow default
-  draw_component_as_icon default show_component_req_prov default show_component_rea default show_stereotype_properties default
-  //state diagram settings
-  package_name_in_tab default show_context default auto_label_position default write_trans_label_horizontally default show_trans_definition default draw_all_relations default shadow default
-  show_activities default region_horizontally default drawing_language default show_stereotype_properties default
-  //activity diagram settings
-  package_name_in_tab default show_context default show_opaque_action_definition default auto_label_position default write_flow_label_horizontally default draw_all_relations default shadow default
-  show_infonote default drawing_language default show_stereotype_properties default
-  
-  classview 134530 "builtins"
-    //class diagram settings
-    draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-    //collaboration diagram settings
-    show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default show_stereotype_properties default
-    //object diagram settings
-     write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default show_stereotype_properties default
-    //sequence diagram settings
-    show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default show_stereotype_properties default
-    //state diagram settings
-    package_name_in_tab default show_context default auto_label_position default write_trans_label_horizontally default show_trans_definition default draw_all_relations default shadow default
-    show_activities default region_horizontally default drawing_language default show_stereotype_properties default
-    //class settings
-    //activity diagram settings
-    package_name_in_tab default show_context default show_opaque_action_definition default auto_label_position default write_flow_label_horizontally default draw_all_relations default shadow default
-    show_infonote default drawing_language default show_stereotype_properties default
-    class 149250 "curses"
-      visibility protected 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      classrelation 171010 // <association>
-	relation_ref 169986 // <association>
-      end
-
-      operation 141570 "initscr"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 141698 "endwin"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 171778 "getch"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-    end
-
-    class 162690 "os"
-      visibility package 
-      cpp_decl ""
-      java_decl ""
-      php_decl ""
-      python_2_2 python_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-      idl_decl ""
-      explicit_switch_type ""
-      
-      operation 156418 "listdir"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      operation 156674 "stat"
-	public explicit_return_type ""
-	nparams 0
-	
-	
-	
-	python_def "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-	
-      end
-
-      classrelation 186626 // <association>
-	relation 184706 ----
-	  a role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 186626 // <association>
-	  b role_name "" private
-	    python "${comment}${self}${name} = ${value}
-"
-	    classrelation_ref 186754 // <association>
-      end
-    end
-  end
-end
diff --git a/doc/uml/134530.diagram b/doc/uml/134530.diagram
deleted file mode 100644
index 8ddb4d31..00000000
--- a/doc/uml/134530.diagram
+++ /dev/null
@@ -1,190 +0,0 @@
-format 70
-
-classcanvas 128002 class_ref 148738 // Action
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 151 121 2000
-end
-classcanvas 128130 class_ref 148866 // Command
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 212 31 2000
-end
-classcanvas 128258 class_ref 148994 // CommandList
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 338 18 2000
-end
-classcanvas 128642 class_ref 149122 // Environment
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 99 305 2000
-end
-classcanvas 128770 class_ref 149250 // curses
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 118 611 2000
-end
-classcanvas 128898 class_ref 149378 // FM
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 143 185 2000
-end
-classcanvas 129154 class_ref 128002 // Displayable
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 325 408 2000
-end
-classcanvas 129666 class_ref 135426 // Console
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 627 149 2006
-end
-classcanvas 129922 class_ref 128130 // UI
-  draw_all_relations default hide_attributes default hide_operations yes hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 366 235 2006
-end
-classcanvas 130178 class_ref 128386 // DisplayableContainer
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 299 311 2012
-end
-classcanvas 131458 class_ref 155906 // FileSystemObject
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 71 416 2000
-end
-classcanvas 131842 class_ref 128258 // DefaultUI
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 325 129 2012
-end
-classcanvas 132610 class_ref 156034 // Widget
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 509 237 2017
-end
-classcanvas 133250 class_ref 135170 // BrowserColumn
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 526 453 2023
-end
-classcanvas 133506 class_ref 135042 // TitleBar
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 646 391 2023
-end
-classcanvas 136322 class_ref 162690 // os
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 54 566 2000
-end
-packagecanvas 136578 
-  package_ref 134530 // builtin
-    xyzwh 29 522 2006 225 181
-end
-note 137346 "\"outer world\""
-  xyzwh 123 566 2011 117 37
-classcanvas 137602 class_ref 175746 // Pager
-  draw_all_relations default hide_attributes default hide_operations default hide_getset_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_members_multiplicity default show_members_initialization default show_attribute_modifiers default member_max_width 0 show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_relation_modifiers default show_relation_visibility default show_infonote default shadow default show_stereotype_properties default
-  xyz 537 333 2028
-end
-relationcanvas 129026 relation_ref 156162 // <generalisation>
-  decenter_begin 466
-  from ref 128898 z 2001 to ref 128002
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 129538 relation_ref 162946 // <aggregation>
-  from ref 128258 z 2001 to ref 128130
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 130306 relation_ref 128386 // <generalisation>
-  decenter_begin 441
-  decenter_end 407
-  from ref 130178 z 2001 to ref 129154
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 130434 relation_ref 135938 // <aggregation>
-  decenter_begin 603
-  decenter_end 631
-  from ref 130178 z 2001 to ref 129154
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 130562 relation_ref 128258 // <generalisation>
-  from ref 129922 z 2007 to ref 130178
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 130946 relation_ref 169730 // <unidirectional association>
-  from ref 128130 z 2001 to point 180 56
-  line 137218 z 2001 to ref 128002
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 131202 relation_ref 169986 // <association>
-  decenter_begin 514
-  from ref 129154 z 2001 to ref 128770
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 131586 relation_ref 170242 // <aggregation>
-  decenter_begin 351
-  from ref 128642 z 2001 to ref 131458
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 131714 relation_ref 170370 // <association>
-  from ref 128642 z 2001 to ref 129154
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 131970 relation_ref 128002 // <generalisation>
-  from ref 131842 z 2007 to ref 129922
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 132354 relation_ref 170498 // <association>
-  decenter_begin 435
-  decenter_end 347
-  from ref 131842 z 2013 to ref 128258
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 132738 relation_ref 170754 // <generalisation>
-  decenter_end 126
-  from ref 132610 z 2001 to point 493 430
-  line 137474 z 2001 to ref 129154
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 132866 relation_ref 170882 // <generalisation>
-  from ref 129666 z 2007 to ref 132610
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 133634 relation_ref 171010 // <generalisation>
-  from ref 133506 z 2018 to ref 132610
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 133762 relation_ref 177922 // <unidirectional association>
-  decenter_end 569
-  from ref 128898 z 2001 to ref 128642
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 135170 relation_ref 178050 // <unidirectional association>
-  from ref 128898 z 2013 to ref 131842
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 136450 relation_ref 184706 // <association>
-  from ref 136322 z 2001 to ref 131458
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 136834 relation_ref 170626 // <association>
-  from ref 129666 z 2007 to ref 128258
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 137730 relation_ref 191234 // <generalisation>
-  from ref 137602 z 2029 to ref 132610
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-relationcanvas 137858 relation_ref 191362 // <generalisation>
-  from ref 133250 z 2029 to ref 137602
-  no_role_a no_role_b
-  no_multiplicity_a no_multiplicity_b
-end
-end
diff --git a/doc/uml/141058.diagram b/doc/uml/141058.diagram
deleted file mode 100644
index 285ba67b..00000000
--- a/doc/uml/141058.diagram
+++ /dev/null
@@ -1,218 +0,0 @@
-format 70
-
-classinstance 128258 class_ref 169218 // Main
-  name ""   xyz 64 4 2000 life_line_z 2000
-classinstance 128386 class_ref 149378 // FM
-  name ""   xyz 185 32 2000 life_line_z 2000
-classinstance 128898 class_ref 128258 // DefaultUI
-  name ""   mortal  xyz 289 80 2000 life_line_z 2000
-classinstance 132226 class_ref 149122 // Environment
-  name ""   xyz 421 84 2000 life_line_z 2000
-classinstance 133122 class_ref 156034 // Widget
-  name ""   xyz 544 107 2000 life_line_z 2000
-classinstance 133762 class_ref 149250 // curses
-  name ""   xyz 632 4 2000 life_line_z 2000
-classinstance 134530 class_ref 148866 // Command
-  name ""   xyz 727 4 2000 life_line_z 2000
-note 136962 "This is outdated."
-  xyzwh 352 23 2000 145 35
-durationcanvas 128514 classinstance_ref 128258 // :Main
-  xyzwh 83 82 2010 11 40
-end
-durationcanvas 128642 classinstance_ref 128386 // :FM
-  xyzwh 204 82 2010 11 25
-end
-durationcanvas 129026 classinstance_ref 128258 // :Main
-  xyzwh 83 130 2010 11 34
-end
-durationcanvas 129154 classinstance_ref 128898 // :DefaultUI
-  xyzwh 325 130 2010 11 58
-  overlappingdurationcanvas 135426
-    xyzwh 331 142 2020 11 40
-    overlappingdurationcanvas 135682
-      xyzwh 337 151 2030 11 25
-    end
-  end
-end
-durationcanvas 129410 classinstance_ref 128258 // :Main
-  xyzwh 83 180 2010 11 35
-end
-durationcanvas 129538 classinstance_ref 128386 // :FM
-  xyzwh 204 172 2010 11 468
-  overlappingdurationcanvas 136450
-    xyzwh 210 537 2020 11 25
-  end
-end
-durationcanvas 129794 classinstance_ref 128258 // :Main
-  xyzwh 83 655 2010 11 27
-end
-durationcanvas 129922 classinstance_ref 128898 // :DefaultUI
-  xyzwh 325 655 2010 11 27
-end
-durationcanvas 130178 classinstance_ref 128898 // :DefaultUI
-  xyzwh 325 265 2010 11 26
-end
-durationcanvas 130434 classinstance_ref 128898 // :DefaultUI
-  xyzwh 325 311 2010 11 26
-end
-durationcanvas 130690 classinstance_ref 128898 // :DefaultUI
-  xyzwh 325 381 2010 11 43
-end
-durationcanvas 131074 classinstance_ref 128898 // :DefaultUI
-  xyzwh 325 467 2010 11 53
-  overlappingdurationcanvas 134914
-    xyzwh 331 489 2020 11 25
-  end
-end
-durationcanvas 132354 classinstance_ref 132226 // :Environment
-  xyzwh 469 606 2010 11 32
-end
-durationcanvas 132866 classinstance_ref 132226 // :Environment
-  xyzwh 469 184 2010 11 27
-end
-durationcanvas 133250 classinstance_ref 133122 // :Widget
-  xyzwh 571 280 2010 11 25
-end
-durationcanvas 133506 classinstance_ref 133122 // :Widget
-  xyzwh 571 323 2010 11 25
-end
-durationcanvas 133890 classinstance_ref 133762 // :curses
-  xyzwh 658 389 2010 11 31
-end
-durationcanvas 135170 classinstance_ref 133122 // :Widget
-  xyzwh 571 501 2010 11 27
-end
-durationcanvas 135938 classinstance_ref 134530 // :Command
-  xyzwh 767 506 2010 11 72
-end
-durationcanvas 136706 classinstance_ref 133122 // :Widget
-  xyzwh 571 563 2010 11 34
-end
-msg 128770 synchronous
-  from durationcanvas_ref 128514
-  to durationcanvas_ref 128642
-  yz 82 2015 msg operation_ref 141826 // "initialize()"
-  show_full_operations_definition default drawing_language default
-  label_xy 117 64
-msg 129282 synchronous
-  from durationcanvas_ref 129026
-  to durationcanvas_ref 129154
-  yz 130 2015 msg operation_ref 171138 // "initialize()"
-  show_full_operations_definition default drawing_language default
-  label_xy 124 111
-msg 129666 synchronous
-  from durationcanvas_ref 129410
-  to durationcanvas_ref 129538
-  yz 180 2015 msg operation_ref 141954 // "loop()"
-  show_full_operations_definition default drawing_language default
-  label_xy 129 162
-msg 130050 synchronous
-  from durationcanvas_ref 129794
-  to durationcanvas_ref 129922
-  yz 655 2015 msg operation_ref 134914 // "destroy()"
-  show_full_operations_definition default drawing_language default
-  label_xy 119 636
-msg 130306 synchronous
-  from durationcanvas_ref 129538
-  to durationcanvas_ref 130178
-  yz 265 2015 msg operation_ref 134530 // "draw()"
-  show_full_operations_definition default drawing_language default
-  label_xy 245 247
-msg 130562 synchronous
-  from durationcanvas_ref 129538
-  to durationcanvas_ref 130434
-  yz 311 2015 msg operation_ref 149378 // "finalize()"
-  show_full_operations_definition default drawing_language default
-  label_xy 240 293
-msg 130818 synchronous
-  from durationcanvas_ref 129538
-  to durationcanvas_ref 130690
-  yz 382 2015 msg operation_ref 148738 // "get_next_key()"
-  show_full_operations_definition default drawing_language default
-  label_xy 229 361
-msg 130946 return
-  from durationcanvas_ref 130690
-  to durationcanvas_ref 129538
-  yz 412 2020 unspecifiedmsg
-  show_full_operations_definition default drawing_language default
-msg 131202 synchronous
-  from durationcanvas_ref 129538
-  to durationcanvas_ref 131074
-  yz 467 2015 msg operation_ref 148610 // "handle_key()"
-  show_full_operations_definition default drawing_language default
-  label_xy 234 449
-msg 132482 synchronous
-  from durationcanvas_ref 129538
-  to durationcanvas_ref 132354
-  yz 606 2015 msg operation_ref 171522 // "garbage_collect()"
-  show_full_operations_definition default drawing_language default
-  label_xy 260 587
-msg 132994 synchronous
-  from durationcanvas_ref 129538
-  to durationcanvas_ref 132866
-  yz 185 2020 msg operation_ref 171650 // "enter_dir()"
-  show_full_operations_definition default drawing_language default
-  label_xy 222 164
-msg 133378 synchronous
-  from durationcanvas_ref 130178
-  to durationcanvas_ref 133250
-  yz 280 2015 msg operation_ref 134530 // "draw()"
-  show_full_operations_definition default drawing_language default
-  label_xy 407 262
-msg 133634 synchronous
-  from durationcanvas_ref 130434
-  to durationcanvas_ref 133506
-  yz 323 2015 msg operation_ref 149378 // "finalize()"
-  show_full_operations_definition default drawing_language default
-  label_xy 405 303
-msg 134018 synchronous
-  from durationcanvas_ref 130690
-  to durationcanvas_ref 133890
-  yz 391 2015 msg operation_ref 171778 // "getch()"
-  show_full_operations_definition default drawing_language default
-  label_xy 713 361
-msg 134402 return
-  from durationcanvas_ref 133890
-  to durationcanvas_ref 130690
-  yz 408 2020 unspecifiedmsg
-  show_full_operations_definition default drawing_language default
-reflexivemsg 135042 synchronous
-  to durationcanvas_ref 134914
-  yz 489 2025 msg operation_ref 148482 // "handle_mouse()"
-  show_full_operations_definition default drawing_language default
-  label_xy 345 462
-msg 135298 synchronous
-  from durationcanvas_ref 134914
-  to durationcanvas_ref 135170
-  yz 502 2030 msg operation_ref 134786 // "click()"
-  show_full_operations_definition default drawing_language default
-  label_xy 474 484
-reflexivemsg 135554 synchronous
-  to durationcanvas_ref 135426
-  yz 142 2025 msg operation_ref 148866 // "setup()"
-  show_full_operations_definition default drawing_language default
-  label_xy 340 120
-reflexivemsg 135810 synchronous
-  to durationcanvas_ref 135682
-  yz 151 2035 msg operation_ref 149890 // "add_obj()"
-  show_full_operations_definition default drawing_language default
-  label_xy 372 143
-msg 136066 synchronous
-  from durationcanvas_ref 135170
-  to durationcanvas_ref 135938
-  yz 506 2015 msg operation_ref 164226 // "execute()"
-  show_full_operations_definition default drawing_language default
-  label_xy 593 488
-msg 136578 synchronous
-  from durationcanvas_ref 135938
-  to durationcanvas_ref 136450
-  yz 537 2025 explicitmsg "<command>"
-  show_full_operations_definition default drawing_language default
-  label_xy 222 520
-msg 136834 synchronous
-  from durationcanvas_ref 135938
-  to durationcanvas_ref 136706
-  yz 567 2030 explicitmsg "<command>"
-  show_full_operations_definition default drawing_language default
-  label_xy 581 554
-end
diff --git a/doc/uml/2.session b/doc/uml/2.session
deleted file mode 100644
index 5365445d..00000000
--- a/doc/uml/2.session
+++ /dev/null
@@ -1,26 +0,0 @@
-window_sizes 1678 1033 393 1275 795 144
-motifplus_style
-diagrams
-  classdiagram_ref 128002 // Displayable Hierarchy
-    1275 795 100 4 0 0
-  active  classdiagram_ref 134530 // Overview
-    1275 795 100 4 0 0
-  sequencediagram_ref 141058 // Basic Logic
-    1275 795 100 4 0 0
-end
-show_stereotypes
-selected classdiagram_ref 134530 // Overview
-open
-  class_ref 128002 // Displayable
-  class_ref 128130 // UI
-  class_ref 128258 // DefaultUI
-  class_ref 135170 // BrowserColumn
-  class_ref 148866 // Command
-  class_ref 148994 // CommandList
-  class_ref 149122 // Environment
-  class_ref 149378 // FM
-  class_ref 155906 // FileSystemObject
-  class_ref 175746 // Pager
-  class_ref 149250 // curses
-end
-end
diff --git a/doc/uml/cpp_includes b/doc/uml/cpp_includes
deleted file mode 100644
index 531b86f7..00000000
--- a/doc/uml/cpp_includes
+++ /dev/null
@@ -1,13 +0,0 @@
-// "a type" "needed cpp_includes"
-"vector" "#include <vector>
-using namespace std;"
-
-"list" "#include <list>
-using namespace std;"
-
-"map" "#include <map>
-using namespace std;"
-
-"string" "#include <string>
-using namespace std;"
-
diff --git a/doc/uml/generation_settings b/doc/uml/generation_settings
deleted file mode 100644
index 8cd2bc14..00000000
--- a/doc/uml/generation_settings
+++ /dev/null
@@ -1,310 +0,0 @@
-
-  python_default_defs 
-  cpp_h_extension "h" cpp_src_extension "cpp" java_extension "java" php_extension "php" python_extension "py" idl_extension "idl"
-  cpp_inline_dont_force_incl_in_h
-
-  type_forms 15 // uml cpp java idl cpp_in cpp_out cpp_inout cpp_return
-    "void" "void" "void" "void" "${type}" "${type} &" "${type}" "${type}"
-    "any" "void *" "Object" "any" "const ${type}" "${type}" "${type} &" "${type}"
-    "bool" "bool" "boolean" "boolean" "${type}" "${type} &" "${type} &" "${type}"
-    "char" "char" "char" "char" "${type}" "${type} &" "${type} &" "${type}"
-    "uchar" "unsigned char" "char" "octet" "${type}" "${type} &" "${type} &" "${type}"
-    "byte" "unsigned char" "byte" "octet" "${type}" "${type} &" "${type} &" "${type}"
-    "short" "short" "short" "short" "${type}" "${type} &" "${type} &" "${type}"
-    "ushort" "unsigned short" "short" "unsigned short" "${type}" "${type} &" "${type} &" "${type}"
-    "int" "int" "int" "long" "${type}" "${type} &" "${type} &" "${type}"
-    "uint" "unsigned int" "int" "unsigned long" "${type}" "${type} &" "${type} &" "${type}"
-    "long" "long" "long" "long" "${type}" "${type} &" "${type} &" "${type}"
-    "ulong" "unsigned long" "long" "unsigned long" "${type}" "${type} &" "${type} &" "${type}"
-    "float" "float" "float" "float" "${type}" "${type} &" "${type} &" "${type}"
-    "double" "double" "double" "double" "${type}" "${type} &" "${type} &" "${type}"
-    "string" "string" "String" "string" "${type}" "${type} &" "${type} &" "${type}"
-  
-  relations_stereotypes 5 // uml cpp java pythonidl
-    "sequence" "vector" "Vector" "list" "sequence"
-    "vector" "vector" "Vector" "list" "sequence"
-    "list" "list" "List" "list" "sequence"
-    "set" "set" "Set" "set" "sequence"
-    "map" "map" "Map" "dict" "sequence"
-  
-  classes_stereotypes 14 // uml cpp java php python idl
-    "class" "class" "class" "class" "class" "valuetype"
-    "interface" "class" "interface" "interface" "class" "interface"
-    "exception" "class" "class" "class" "class" "exception"
-    "enum" "enum" "enum" "enum" "enum" "enum"
-    "enum_pattern" "enum" "enum_pattern" "enum" "enum" "enum"
-    "struct" "struct" "class" "class" "class" "struct"
-    "union" "union" "class" "class" "class" "union"
-    "typedef" "typedef" "ignored" "ignored" "ignored" "typedef"
-    "boundary" "class" "class" "class" "class" "interface"
-    "control" "class" "class" "class" "class" "valuetype"
-    "entity" "class" "class" "class" "class" "valuetype"
-    "actor" "ignored" "ignored" "ignored" "ignored" "ignored"
-    "@interface" "ignored" "@interface" "ignored" "ignored" "ignored"
-    "stereotype" "ignored" "ignored" "ignored" "ignored" "ignored"
-  
-  cpp_enum_default_type_forms "${type}" "${type} &" "${type} &" "${type}" // in out inout return
-  other_cpp_types_default_type_forms "const ${type} &" "${type} &" "${type} &" "${type}" // in out inout return
-
-  cpp_default_h_content "#ifndef ${NAMESPACE}_${NAME}_H
-#define ${NAMESPACE}_${NAME}_H
-
-${comment}
-${includes}
-${declarations}
-${namespace_start}
-${definition}
-${namespace_end}
-#endif
-"
-  cpp_default_src_content "${comment}
-${includes}
-${namespace_start}
-${members}
-${namespace_end}"
-  cpp_default_class_decl "${comment}${template}class ${name}${inherit} {
-${members}};
-${inlines}
-"
-  cpp_default_external_class_decl "${name}
-#include <${name}.h>
-"
-  cpp_default_struct_decl "${comment}${template}struct ${name}${inherit} {
-${members}};
-${inlines}
-"
-  cpp_default_union_decl "${comment}${template}union ${name} {
-${members}};
-${inlines}
-"
-  cpp_default_enum_decl "${comment}enum ${name} {
-${items}
-};
-"
-  cpp_default_typedef_decl "${comment}typedef ${type} ${name};
-"
-  cpp_default_attribute_declaration "    ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value};
-" // multiplicity 1
-  "    ${comment}${static}${mutable}${volatile}${const}${stereotype}<${type}> ${name}${value};
-" // multiplicity * a..b
-  "    ${comment}${static}${mutable}${volatile}${const}${type} ${name}${multiplicity}${value};
-" // multiplicity [..]
-  cpp_default_enum_item_declaration "  ${name}${value},${comment}"
-  cpp_association_aggregation_declaration
-    "    ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value};
-" // multiplicity 1
-    "    ${comment}${static}${mutable}${volatile}${const}${stereotype}<${type} *> ${name}${value};
-" // multiplicity * a..b
-    "    ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${multiplicity}${value};
-" // multiplicity [..]
-  cpp_aggregation_by_value_declaration
-    "    ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value};
-" // multiplicity 1
-    "    ${comment}${static}${mutable}${volatile}${const}${stereotype}<${type}> ${name}${value};
-" // multiplicity * a..b
-    "    ${comment}${static}${mutable}${volatile}${const}${type} ${name}${multiplicity}${value};
-" // multiplicity [..]
-  cpp_get "get_${name}" inline const value_const public
-  cpp_set "set_${name}" public
-  cpp_default_operation_declaration "    ${comment}${friend}${static}${inline}${virtual}${type} ${name}${(}${)}${const}${volatile}${throw}${abstract};
-"
-  cpp_default_operation_definition "${comment}${inline}${type} ${class}::${name}${(}${)}${const}${volatile}${throw}${staticnl}{
-  ${body}}
-"
-  java_default_src_content "${comment}
-${package}
-${imports}
-${definition}"
-  java_default_class_decl "${comment}${@}${visibility}${final}${abstract}class ${name}${extends}${implements} {
-${members}}
-"
-  java_default_external_class_decl "${name}"
-  java_default_interface_decl "${comment}${@}${visibility}interface ${name}${extends} {
-${members}}
-"
-  java5_default_enum_decl "${comment}${@}${visibility}${final}${abstract}enum ${name}${implements} {
-${items};
-${members}}
-"
-  java_default_enum_decl "${comment}${@}${visibility}final class ${name} {
-${members}
-  private final int value;
-
-  public int value() {
-    return value;
-  }
-
-  public static ${name} fromInt(int value) {
-    switch (value) {
-${cases}    default: throw new Error();
-    }
-
-  }
-  private ${name}(int v) { value = v; };
-}
-"
-  java_default_attribute_declaration "  ${comment}${@}${visibility}${static}${final}${transient}${volatile}${type} ${name}${value};
-" // multiplicity 1
-  "  ${comment}${@}${visibility}${static}${final}${transient}${volatile}${stereotype}<${type}> ${name}${value};
-" // multiplicity * a..b
-  "  ${comment}${@}${visibility}${static}${final}${transient}${volatile}${type}${multiplicity} ${name}${value};
-" // multiplicity N
-  java5_default_enum_item_declaration "  ${@}${name}${value},${comment}"
-  java_default_enum_item_declaration "  ${comment}${@}public static final int _${name}${value};
-public static final ${class} ${name} = new ${class}(_${name});
-"
-  java_default_enum_case "    case _${name}: return ${name};
-"
-  java_association_aggregation_declaration
-    "  ${comment}${@}${visibility}${static}${final}${transient}${volatile}${type} ${name}${value};
-" // multiplicity 1
-    "  ${comment}${@}${visibility}${static}${final}${transient}${volatile}${stereotype}<${type}> ${name}${value};
-" // multiplicity * a..b
-    "  ${comment}${@}${visibility}${static}${final}${transient}${volatile}${type}${multiplicity} ${name}${value};
-" // multiplicity N
-  java_get "get${Name}" final public
-  java_set "set${Name}" public
-  java_default_operation_definition "  ${comment}${@}${visibility}${final}${static}${abstract}${synchronized}${type} ${name}${(}${)}${throws}${staticnl}{
-  ${body}}
-"
-  php_default_src_content "<?php
-${comment}
-${definition}
-?>
-"
-  php_default_class_decl "${comment}${final}${visibility}${abstract}class ${name}${extends}${implements} {
-${members}}
-"
-  php_default_enum_decl "${comment}${visibility}final class ${name} {
-${items}}
-"
-  php_default_external_class_decl "${name}"
-  php_default_interface_decl "${comment}${visibility}interface ${name} {
-${members}}
-"
-  php_default_attribute_declaration "  ${comment}${visibility}${const}${static}${var}${name}${value};
-"
-  php_default_enum_item_decl "  const ${name}${value};${comment}
-"
-  php_default_relation_declaration"  ${comment}${visibility}${const}${static}${var}${name}${value};
-"
-  php_get "get${Name}" final
-  php_set "set${Name}"
-  php_default_operation_definition "  ${comment}${final}${visibility}${abstract}${static}function ${name}${(}${)}
-{
-  ${body}}
-"
-  python_2_2
-  python_indent_step "    "
-  python_default_src_content "${comment}
-${import}
-${definition}"
-  python_default_class_decl "class ${name}${inherit}:
-${docstring}${members}
-"
-  python_default_enum_decl "class ${name}:
-${docstring}${members}
-"
-  python_default_external_class_decl "${name}"
-  python_default_attribute_declaration "${comment}${self}${name} = ${value}
-" // multiplicity 1
-  "${comment}${self}${name} = ${stereotype}()
-" // multiplicity != 1
-  python_default_enum_item_decl "${comment}${self}${name} = ${value}
-"
-  python_default_relation_declaration"${comment}${self}${name} = ${value}
-" // multiplicity 1
-  "${comment}${self}${name} = ${stereotype}()
-" // multiplicity != 1
-  python_default_composition_declaration"${comment}${self}${name} = ${type}()
-" // multiplicity 1
-  "${comment}${self}${name} = ${stereotype}()
-" // multiplicity != 1
-  python_default_operation_definition "${@}${static}${abstract}def ${name}${(}${)}:
-${docstring}${body}
-"
-  python_default_initoperation_definition "${@}${static}${abstract}def ${name}${(}${p0}${v0}${)}:
-${docstring}super(${class}, ${p0}).__init__()
-${body}
-"
-  python_get "get${Name}"
-  python_set "set${Name}"
-  idl_default_src_content "#ifndef ${MODULE}_${NAME}_H
-#define ${MODULE}_${NAME}_H
-
-${comment}
-${includes}
-${module_start}
-${definition}
-${module_end}
-#endif
-"
-  idl_default_interface_decl "${comment}${abstract}${local}interface ${name}${inherit} {
-${members}};
-"
-  idl_default_valuetype_decl "${comment}${abstract}${custom}valuetype ${name}${inherit} {
-${members}};
-"
-  idl_default_struct_decl "${comment}struct ${name} {
-${members}};
-"
-  idl_default_typedef_decl "${comment}typedef ${type} ${name};
-"
-  idl_default_exception_decl "${comment}exception ${name} {
-${members}};
-"
-  idl_default_union_decl "${comment}union ${name} switch(${switch}) {
-${members}};
-"
-  idl_default_enum_decl "${comment}enum ${name} {
-${items}};
-"
-  idl_default_external_class_decl "${name}
-#include \"${name}.idl\"
-"
-  idl_default_attribute_declaration "  ${comment}${readonly}${attribute}${type} ${name};
-" // multiplicity 1
-  "  ${comment}${readonly}${attribute}${stereotype}<${type}> ${name};
-" // multiplicity * a..b
-  "  ${comment}${readonly}${attribute}${stereotype}<${type},${multiplicity}> ${name};
-" // multiplicity N
-  idl_default_valuetype_attribute_declaration "  ${comment}${visibility}${type} ${name};
-" // multiplicity 1
-  "  ${comment}${visibility}${stereotype}<${type}> ${name};
-" // multiplicity * a..b
-  "  ${comment}${visibility}${stereotype}<${type},${multiplicity}> ${name};
-" // multiplicity N
-  idl_default_const_declaration "  ${comment}const ${type} ${name}${value};
-" // multiplicity 1
-  "  ${comment}const ${stereotype}<${type}> ${name}${value};
-" // multiplicity * a..b
-  "  ${comment}const ${stereotype}<${type},${multiplicity}> ${name}${value};
-" // multiplicity N
-  idl_default_enum_item_declaration "  ${name},${comment}"
-  idl_default_union_item_declaration "  ${comment}case ${case} : ${readonly}${type} ${name};" // multiplicity 1
-  "  ${comment}case ${case} : ${readonly}${stereotype}<${type}> ${name};" // multiplicity * a..b
-  "  ${comment}case ${case} : ${readonly}${stereotype}<${type},${multiplicity}> ${name};" // multiplicity N
-  idl_association_aggregation_declaration
-    "  ${comment}${readonly}${attribute}${type} ${name};
-" // multiplicity 1
-    "  ${comment}${readonly}${attribute}${stereotype}<${type}> ${name};
-" // multiplicity * a..b
-    "  ${comment}${readonly}${attribute}${stereotype}<${type},${multiplicity}> ${name};
-" // multiplicity N
-  idl_valuetype_association_aggregation_declaration
-    "  ${comment}${visibility}${type} ${name};
-" // multiplicity 1
-    "  ${comment}${visibility}${stereotype}<${type}> ${name};
-" // multiplicity * a..b
-    "  ${comment}${visibility}${stereotype}<${type},${multiplicity}> ${name};
-" // multiplicity N
-  idl_union_association_aggregation_declaration
-    "  ${comment}case ${case} : ${readonly}${type} ${name};" // multiplicity 1
-    "  ${comment}case ${case} : ${readonly}${stereotype}<${type}> ${name};" // multiplicity * a..b
-    "  ${comment}case ${case} : ${readonly}${stereotype}<${type},${multiplicity}> ${name};" // multiplicity N
-  idl_get "get_${name}"
-  idl_set "set_${name}"  twoways
-  idl_default_operation_declaration "  ${comment}${oneway}${type} ${name}${(}${)}${raisesnl}${raises};
-"
-  uml_get_name uml uml_set_name uml
-end
diff --git a/doc/uml/idl_includes b/doc/uml/idl_includes
deleted file mode 100644
index fceab64b..00000000
--- a/doc/uml/idl_includes
+++ /dev/null
@@ -1 +0,0 @@
-// "a type" "needed idl_includes"
diff --git a/doc/uml/java_imports b/doc/uml/java_imports
deleted file mode 100644
index bbd370ac..00000000
--- a/doc/uml/java_imports
+++ /dev/null
@@ -1 +0,0 @@
-// "a type" "needed java_imports"
diff --git a/doc/uml/python_imports b/doc/uml/python_imports
deleted file mode 100644
index 4a1bd3a8..00000000
--- a/doc/uml/python_imports
+++ /dev/null
@@ -1 +0,0 @@
-// "a type" "needed python_imports"
diff --git a/doc/uml/stereotypes b/doc/uml/stereotypes
deleted file mode 100644
index 3680bceb..00000000
--- a/doc/uml/stereotypes
+++ /dev/null
@@ -1,59 +0,0 @@
-
-  package_stereotypes  6 "facade" "framework" "model library" "stub" "toplevel" "profile"
-    -_-> 3 "access" "import" "from"
-  end
-  
-  class_stereotypes  19 "actor" "auxiliary" "boundary" "control" "entity" "enum" "enum_pattern" "exception" "focus" "implementationClass" "interface" "@interface" "metaclass" "stereotype" "struct" "type" "typedef" "union" "utility"
-    ---- 4 "list" "set" "vector" "map"
-    ---> 4 "list" "set" "vector" "map"
-    ---|> 4 "{complete,disjoint}" "{incomplete,disjoint}" "{complete,overlapping}" "{incomplete,overlapping}"
-    o--- 4 "list" "set" "vector" "map"
-    *--- 4 "list" "set" "vector" "map"
-    o--> 4 "list" "set" "vector" "map"
-    *--> 4 "list" "set" "vector" "map"
-    -_-> 4 "friend" "from" "import" "instantiate"
-    -_-|> 1 "bind"
-  end
-  
-  use_case_stereotypes 1 "realization"
-  
-    ---|> 4 "{complete,disjoint}" "{incomplete,disjoint}" "{complete,overlapping}" "{incomplete,overlapping}"
-    -_-> 2 "include" "extend"
-  end
-  
-  artifact_stereotypes  7 "document" "file" "script" "source" "text" "library" "executable"
-    -_-> 4 "deploy" "manifest" "import" "from"
-  end
-  
-  attribute_stereotypes  4 "list" "set" "vector" "map"
-  operation_stereotypes  0
-  state_stereotypes  3 "machine" "submachine" "top"
-  activity_stereotypes  0
-  flow_stereotypes  3 "interrupt" "multicast" "multireceive"
-  interruptibleactivityregion_stereotypes  0
-  pseudostate_stereotypes  0
-  stateaction_stereotypes  2 "send-signal" "receive-signal"
-  parameter_stereotypes  0
-  parameterset_stereotypes  0
-  activitynode_stereotypes  0
-  activityaction_stereotypes  0
-  activityobject_stereotypes  2 "datastore" "centralBuffer"
-  expansionregion_stereotypes  0
-  activitypartition_stereotypes  0
-  pin_stereotypes  0
-  component_stereotypes  6 "buildComponent" "entity" "implement" "process" "service" "subsystem"
-  deploymentnode_stereotypes  3 "cpu" "device" "executionEnvironment"
-  classview_stereotypes  0
-  usecaseview_stereotypes  0
-  componentview_stereotypes  0
-  deploymentview_stereotypes  0
-  classdiagram_stereotypes  0
-  seqdiagram_stereotypes  0
-  msg_stereotypes  0
-  coldiagram_stereotypes  0
-  usecasediagram_stereotypes  0
-  statediagram_stereotypes  0
-  activitydiagram_stereotypes  0
-  componentdiagram_stereotypes  0
-  deploymentdiagram_stereotypes  0
-end
diff --git a/doc/uml/tools b/doc/uml/tools
deleted file mode 100644
index 3579028b..00000000
--- a/doc/uml/tools
+++ /dev/null
@@ -1,18 +0,0 @@
-// 'tool' "the executable" "displayed string" {target}+
-tool "HTML documentation" "ghtml" Class Operation Attribute Generalisation Realize Dependency Association DirectionalAssociation Aggregation AggregationByValue DirectionalAggregation DirectionalAggregationByValue ExtraMember ClassInstance State Region StateAction Initial EntryPoint Final Terminate ExitPoint DeepHistory ShallowHistory Junction Choice Fork Join Transition Activity InterruptibleActivityRegion ExpansionRegion ActivityObject ActivityAction Parameter ParameterSet Pin ExpansionNode InitialActivityNode FinalActivityNode ExitPointActivityNode DecisionActivityNode MergeActivityNode ForkActivityNode JoinActivityNode Flow Project Package UseCaseView ClassView ComponentView DeploymentView UseCaseDiagram SeqDiagram ColDiagram ClassDiagram ObjectDiagram StateDiagram ActivityDiagram ComponentDiagram DeploymentDiagram UseCase Component Node Artifact Inherit DependOn
-tool "HTML doc. (flat)" "ghtml -flat" Class Operation Attribute Generalisation Realize Dependency Association DirectionalAssociation Aggregation AggregationByValue DirectionalAggregation DirectionalAggregationByValue ExtraMember ClassInstance State Region StateAction Initial EntryPoint Final Terminate ExitPoint DeepHistory ShallowHistory Junction Choice Fork Join Transition Activity InterruptibleActivityRegion ExpansionRegion ActivityObject ActivityAction Parameter ParameterSet Pin ExpansionNode InitialActivityNode FinalActivityNode ExitPointActivityNode DecisionActivityNode MergeActivityNode ForkActivityNode JoinActivityNode Flow Project Package UseCaseView ClassView ComponentView DeploymentView UseCaseDiagram SeqDiagram ColDiagram ClassDiagram ObjectDiagram StateDiagram ActivityDiagram ComponentDiagram DeploymentDiagram UseCase Component Node Artifact Inherit DependOn
-tool "HTML doc. (svg)" "ghtml -svg" Class Operation Attribute Generalisation Realize Dependency Association DirectionalAssociation Aggregation AggregationByValue DirectionalAggregation DirectionalAggregationByValue ExtraMember ClassInstance State Region StateAction Initial EntryPoint Final Terminate ExitPoint DeepHistory ShallowHistory Junction Choice Fork Join Transition Activity InterruptibleActivityRegion ExpansionRegion ActivityObject ActivityAction Parameter ParameterSet Pin ExpansionNode InitialActivityNode FinalActivityNode ExitPointActivityNode DecisionActivityNode MergeActivityNode ForkActivityNode JoinActivityNode Flow Project Package UseCaseView ClassView ComponentView DeploymentView UseCaseDiagram SeqDiagram ColDiagram ClassDiagram ObjectDiagram StateDiagram ActivityDiagram ComponentDiagram DeploymentDiagram UseCase Component Node Artifact Inherit DependOn
-tool "HTML doc. (flat, svg)" "ghtml -flat -svg" Class Operation Attribute Generalisation Realize Dependency Association DirectionalAssociation Aggregation AggregationByValue DirectionalAggregation DirectionalAggregationByValue ExtraMember ClassInstance State Region StateAction Initial EntryPoint Final Terminate ExitPoint DeepHistory ShallowHistory Junction Choice Fork Join Transition Activity InterruptibleActivityRegion ExpansionRegion ActivityObject ActivityAction Parameter ParameterSet Pin ExpansionNode InitialActivityNode FinalActivityNode ExitPointActivityNode DecisionActivityNode MergeActivityNode ForkActivityNode JoinActivityNode Flow Project Package UseCaseView ClassView ComponentView DeploymentView UseCaseDiagram SeqDiagram ColDiagram ClassDiagram ObjectDiagram StateDiagram ActivityDiagram ComponentDiagram DeploymentDiagram UseCase Component Node Artifact Inherit DependOn
-tool "Generate .pro" "gpro" Artifact
-tool "Import Rose" "irose" Project Package
-tool "C++ utilities" "cpp_util" Class
-tool "Generate XMI 1.2" "gxmi" Project
-tool "Generate XMI 2.1" "gxmi2" Project
-tool "Import XMI 2.1" "ixmi2" Project Package
-tool "C++ state machine" "stmgen" State
-tool "Use case wizard" "usecasewizard" UseCase
-tool "Check-in" "file_control ci" Project Package
-tool "Check-out" "file_control co" Project Package
-tool "Deploy classes" "deplcl" ClassView
-tool "Global Change" "global_change" Class Project Package ClassView DeploymentView
-tool "Uml projection" "uml_proj" Class Operation Attribute Generalisation Realize Dependency Association DirectionalAssociation Aggregation AggregationByValue DirectionalAggregation DirectionalAggregationByValue Project Package ClassView
diff --git a/doc/uml/uml.prj b/doc/uml/uml.prj
deleted file mode 100644
index 078dae9e..00000000
--- a/doc/uml/uml.prj
+++ /dev/null
@@ -1,43 +0,0 @@
-format 70
-"uml"
-  revision 3
-  modified_by 2 "hut"
-
-
-  
-  // class settings
-  default_attribute_visibility private default_relation_visibility private default_operation_visibility public
-  //class diagram settings
-  draw_all_relations yes hide_attributes no hide_operations no hide_getset_operations no show_members_full_definition no show_members_visibility no show_members_stereotype no show_members_multiplicity no show_members_initialization no show_attribute_modifiers no member_max_width 127 show_parameter_dir yes show_parameter_name yes package_name_in_tab no class_drawing_mode natural drawing_language uml show_context_mode no auto_label_position yes show_relation_modifiers no show_relation_visibility no show_infonote no shadow yes show_stereotype_properties no
-  //use case diagram settings
-  package_name_in_tab no show_context no auto_label_position yes draw_all_relations yes class_drawing_mode actor shadow yes show_stereotype_properties no
-  //sequence diagram settings
-  show_full_operations_definition no write_horizontally yes class_drawing_mode natural drawing_language uml draw_all_relations yes shadow yes show_stereotype_properties no
-  //collaboration diagram settings
-  show_full_operations_definition no show_hierarchical_rank no write_horizontally yes drawing_language uml package_name_in_tab no show_context no draw_all_relations yes shadow yes show_stereotype_properties no
-  //object diagram settings
-   write_horizontally yes package_name_in_tab no show_context no auto_label_position yes draw_all_relations yes shadow yes show_stereotype_properties no
-  //component diagram settings
-  package_name_in_tab no show_context no auto_label_position yes draw_all_relations yes shadow yes
-  draw_component_as_icon no show_component_req_prov no show_component_rea no show_stereotype_properties no
-  //deployment diagram settings
-  package_name_in_tab no show_context no write_horizontally yes auto_label_position yes draw_all_relations yes shadow yes
-  draw_component_as_icon no show_component_req_prov no show_component_rea no show_stereotype_properties no
-  //state diagram settings
-  package_name_in_tab no show_context no auto_label_position yes write_trans_label_horizontally yes show_trans_definition no draw_all_relations yes shadow yes
-  show_activities yes region_horizontally yes drawing_language uml show_stereotype_properties no
-  //activity diagram settings
-  package_name_in_tab no show_context no show_opaque_action_definition no auto_label_position yes write_flow_label_horizontally no draw_all_relations yes shadow yes
-  show_infonote yes drawing_language uml show_stereotype_properties no
-  
-  class_color yellow duration_color transparent continuation_color gray note_color blue fragment_color transparent subject_color transparent usecase_color yellow package_color transparent component_color green artifact_color green deploymentnode_color gray state_color yellow stateaction_color transparent activity_color transparent activityregion_color transparent activitypartition_color transparent activityaction_color transparent parameterpin_color white 
-  font_size 13
-  diagram_format A4
-
-  mark_for_import
-  
-  package_ref 128002 // ranger
-
-  package_ref 134530 // builtin
-
-end
diff --git a/ranger.py b/ranger.py
index 9703b243..636bd384 100755
--- a/ranger.py
+++ b/ranger.py
@@ -20,16 +20,10 @@
 # ----------------------------------------------------------------------------
 #
 # An embedded shell script. It allows you to change the directory
-# of the parent shell to the last visited directory in ranger after exit.
-# For more information, check out doc/cd-after-exit.txt
-# To enable this, start ranger with:
-#     source /path/ranger /path/ranger
+# after you exit ranger by starting it with: source ranger ranger
 """":
 if [ $1 ]; then
-	ranger_exec="$1"
-	shift
-	cd "`exec $ranger_exec --cd-after-exit $@ 3>&1 1>&2 2>&3 3>&-`"
-	unset ranger_exec
+	$@ && cd "$(grep \^\' ~/.ranger/bookmarks | cut -b3-)"
 else
 	echo "usage: source path/to/ranger.py path/to/ranger.py"
 fi
@@ -45,7 +39,7 @@ __doc__ = """Ranger - file browser for the unix terminal"""
 # is neither in the same directory as this file, nor in one of
 # pythons global import paths.
 try:
-	from ranger import main
+	from ranger.__main__ import main
 
 except ImportError:
 	import sys
diff --git a/ranger/__init__.py b/ranger/__init__.py
index e2a4983d..f46a1e76 100644
--- a/ranger/__init__.py
+++ b/ranger/__init__.py
@@ -34,7 +34,7 @@ USAGE = '%prog [options] [path/filename]'
 DEFAULT_CONFDIR = '~/.ranger'
 RANGERDIR = os.path.dirname(__file__)
 LOGFILE = '/tmp/errorlog'
-arg = OpenStruct(cd_after_exit=False,
+arg = OpenStruct(
 		debug=False, clean=False, confdir=DEFAULT_CONFDIR,
 		mode=0, flags='', targets=[])
 
@@ -64,6 +64,3 @@ def relpath_conf(*paths):
 def relpath(*paths):
 	"""returns the path relative to rangers library directory"""
 	return os.path.join(RANGERDIR, *paths)
-
-
-from ranger.__main__ import main
diff --git a/ranger/__main__.py b/ranger/__main__.py
index bd01bf4a..674ad8f6 100644
--- a/ranger/__main__.py
+++ b/ranger/__main__.py
@@ -29,38 +29,23 @@ def parse_arguments():
 
 	parser = OptionParser(usage=USAGE, version='ranger ' + __version__)
 
-	# Instead of using this directly, use the embedded
-	# shell script by running ranger with:
-	# source /path/to/ranger /path/to/ranger
-	parser.add_option('--cd-after-exit',
-			action='store_true',
-			help=SUPPRESS_HELP)
-
 	parser.add_option('-d', '--debug', action='store_true',
 			help="activate debug mode")
-
 	parser.add_option('-c', '--clean', action='store_true',
 			help="don't touch/require any config files. ")
-
-	parser.add_option('-r', '--confdir', dest='confdir', type='string',
-			default=DEFAULT_CONFDIR,
+	parser.add_option('-r', '--confdir', type='string',
+			metavar='dir', default=DEFAULT_CONFDIR,
 			help="the configuration directory. (%default)")
-
-	parser.add_option('-m', '--mode', type='int', dest='mode', default=0,
+	parser.add_option('-m', '--mode', type='int', default=0, metavar='n',
 			help="if a filename is supplied, run it with this mode")
-
-	parser.add_option('-f', '--flags', type='string', dest='flags', default='',
+	parser.add_option('-f', '--flags', type='string', default='',
+			metavar='string',
 			help="if a filename is supplied, run it with these flags.")
 
 	options, positional = parser.parse_args()
-
 	arg = OpenStruct(options.__dict__, targets=positional)
-
 	arg.confdir = os.path.expanduser(arg.confdir)
 
-	if arg.cd_after_exit:
-		sys.stderr = sys.__stdout__
-
 	if not arg.clean:
 		try:
 			os.makedirs(arg.confdir)
@@ -71,9 +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)
-
 	return arg
 
 def main():
@@ -100,9 +83,10 @@ def main():
 	if getdefaultlocale()[1] not in ('utf8', 'UTF-8'):
 		for locale in ('en_US.utf8', 'en_US.UTF-8'):
 			try: setlocale(LC_ALL, locale)
-			except: pass  #sometimes there is none available though...
-	else:
-		setlocale(LC_ALL, '')
+			except: pass
+			else: break
+		else: setlocale(LC_ALL, '')
+	else: setlocale(LC_ALL, '')
 
 	arg = parse_arguments()
 	ranger.arg = arg
@@ -132,7 +116,6 @@ def main():
 	try:
 		my_ui = UI()
 		my_fm = FM(ui=my_ui)
-		my_fm.stderr_to_out = arg.cd_after_exit
 
 		# Run the file manager
 		my_fm.initialize()
@@ -142,9 +125,6 @@ def main():
 		# Finish, clean up
 		if 'my_ui' in vars():
 			my_ui.destroy()
-		if arg.cd_after_exit:
-			try: sys.__stderr__.write(my_fm.env.cwd.path)
-			except: pass
 
 if __name__ == '__main__':
 	top_dir = os.path.dirname(sys.path[0])
diff --git a/ranger/api/options.py b/ranger/api/options.py
index 7ead8c90..4748823d 100644
--- a/ranger/api/options.py
+++ b/ranger/api/options.py
@@ -16,6 +16,7 @@
 import re
 from re import compile as regexp
 from ranger import colorschemes as allschemes
+from ranger.gui import color
 
 class AttrToString(object):
 	"""
diff --git a/ranger/colorschemes/default.py b/ranger/colorschemes/default.py
index d1a7e820..24f8ab91 100644
--- a/ranger/colorschemes/default.py
+++ b/ranger/colorschemes/default.py
@@ -21,7 +21,7 @@ class Default(ColorScheme):
 		fg, bg, attr = default_colors
 
 		if context.reset:
-			pass
+			return default_colors
 
 		elif context.in_browser:
 			if context.selected:
@@ -40,11 +40,17 @@ class Default(ColorScheme):
 			if context.container:
 				fg = red
 			if context.directory:
+				attr |= bold
 				fg = blue
 			elif context.executable and not \
-					any((context.media, context.container)):
+					any((context.media, context.container,
+						context.fifo, context.socket)):
 				attr |= bold
 				fg = green
+			if context.socket:
+				fg = magenta
+			if context.fifo:
+				fg = yellow
 			if context.link:
 				fg = context.good and cyan or magenta
 			if context.tag_marker and not context.selected:
@@ -66,6 +72,9 @@ class Default(ColorScheme):
 				fg = context.bad and red or green
 			elif context.directory:
 				fg = blue
+			elif context.tab:
+				if context.good:
+					bg = green
 			elif context.link:
 				fg = cyan
 
diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index e55d65b1..6910871b 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -18,15 +18,288 @@ import shutil
 from inspect import cleandoc
 
 import ranger
-from ranger.shared import EnvironmentAware, SettingsAware
+from ranger.ext.direction import Direction
+from ranger.shared import FileManagerAware, EnvironmentAware, SettingsAware
 from ranger import fsobject
 from ranger.gui.widgets import console_mode as cmode
 from ranger.fsobject import File
 
-class Actions(EnvironmentAware, SettingsAware):
+class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
 	search_method = 'ctime'
 	search_forward = False
 
+	# --------------------------
+	# -- Backwards Compatibility
+	# --------------------------
+	# All methods defined here are just for backwards compatibility,
+	# allowing old configuration files to work with newer versions.
+	# You can delete them and they should change nothing if you use
+	# an up-to-date configuration file.
+
+	def dummy(self, *args, **keywords):
+		"""For backwards compatibility only."""
+
+	handle_mouse = resize = dummy
+
+	def move_left(self, narg=1):
+		"""Enter the parent directory"""
+		self.move(left=1, narg=narg)
+
+	def move_right(self, narg=None):
+		"""Enter the current directory or execute the current file"""
+		self.move(right=1, narg=narg)
+
+	def move_pointer(self, relative=0, absolute=None, narg=None):
+		"""Move the pointer down by <relative> or to <absolute>"""
+		dct = dict(down=relative, narg=narg)
+		if absolute is not None:
+			dct['to'] = absolute
+		self.move(**dct)
+
+	def move_pointer_by_pages(self, relative):
+		"""Move the pointer down by <relative> pages"""
+		self.move(down=relative, pages=True)
+
+	def move_pointer_by_percentage(self, relative=0, absolute=None, narg=None):
+		"""Move the pointer down to <absolute>%"""
+		self.move(to=absolute, percentage=True, narg=narg)
+
+	# --------------------------
+	# -- Basic Commands
+	# --------------------------
+
+	def exit(self):
+		"""Exit the program"""
+		raise SystemExit()
+
+	def reset(self):
+		"""Reset the filemanager, clearing the directory buffer"""
+		old_path = self.env.cwd.path
+		self.env.garbage_collect(-1)
+		self.enter_dir(old_path)
+
+	def reload_cwd(self):
+		try:
+			cwd = self.env.cwd
+		except:
+			pass
+		cwd.unload()
+		cwd.load_content()
+
+	def notify(self, text, duration=4, bad=False):
+		if isinstance(text, Exception):
+			if ranger.arg.debug:
+				raise
+			bad = True
+		text = str(text)
+		self.log.appendleft(text)
+		if hasattr(self.ui, 'notify'):
+			self.ui.notify(text, duration=duration, bad=bad)
+
+	def redraw_window(self):
+		"""Redraw the window"""
+		self.ui.redraw_window()
+
+	def open_console(self, mode=':', string=''):
+		"""Open the console if the current UI supports that"""
+		if hasattr(self.ui, 'open_console'):
+			self.ui.open_console(mode, string)
+
+	def execute_file(self, files, **kw):
+		"""Execute a file.
+		app is the name of a method in Applications, without the "app_"
+		flags is a string consisting of runner.ALLOWED_FLAGS
+		mode is a positive integer.
+		Both flags and mode specify how the program is run."""
+
+		if isinstance(files, set):
+			files = list(files)
+		elif type(files) not in (list, tuple):
+			files = [files]
+
+		return self.run(files=list(files), **kw)
+
+	# --------------------------
+	# -- Moving Around
+	# --------------------------
+
+	def move(self, narg=None, **kw):
+		"""
+		A universal movement method.
+
+		Accepts these parameters:
+		(int) down, (int) up, (int) left, (int) right, (int) to,
+		(bool) absolute, (bool) relative, (bool) pages,
+		(bool) percentage
+
+		to=X is translated to down=X, absolute=True
+
+		Example:
+		self.move(down=4, pages=True)  # moves down by 4 pages.
+		self.move(to=2, pages=True)  # moves to page 2.
+		self.move(to=1, percentage=True)  # moves to 80%
+		"""
+		direction = Direction(kw)
+		if 'left' in direction:
+			steps = direction.left()
+			if narg is not None:
+				steps *= narg
+			try:
+				directory = os.path.join(*(['..'] * steps))
+			except:
+				return
+			self.env.enter_dir(directory)
+
+		elif 'right' in direction:
+			mode = 0
+			if narg is not None:
+				mode = narg
+			cf = self.env.cf
+			selection = self.env.get_selection()
+			if not self.env.enter_dir(cf) and selection:
+				if self.execute_file(selection, mode=mode) is False:
+					self.open_console(cmode.OPEN_QUICK)
+
+		elif direction.vertical():
+			newpos = direction.move(
+					direction=direction.down(),
+					override=narg,
+					maximum=len(self.env.cwd),
+					current=self.env.cwd.pointer,
+					pagesize=self.ui.browser.hei)
+			self.env.cwd.move(absolute=newpos)
+
+	def history_go(self, relative):
+		"""Move back and forth in the history"""
+		self.env.history_go(relative)
+
+	def scroll(self, relative):
+		"""Scroll down by <relative> lines"""
+		if hasattr(self.ui, 'scroll'):
+			self.ui.scroll(relative)
+			self.env.cf = self.env.cwd.pointed_obj
+
+	def enter_dir(self, path, remember=False, history=True):
+		"""Enter the directory at the given path"""
+		if remember:
+			cwd = self.env.cwd
+			result = self.env.enter_dir(path, history=history)
+			self.bookmarks.remember(cwd)
+			return result
+		return self.env.enter_dir(path, history=history)
+
+	def cd(self, path, remember=True):
+		"""enter the directory at the given path, remember=True"""
+		self.enter_dir(path, remember=remember)
+
+	def traverse(self):
+		cf = self.env.cf
+		cwd = self.env.cwd
+		if cf is not None and cf.is_directory:
+			self.enter_dir(cf.path)
+		elif cwd.pointer >= len(cwd) - 1:
+			while True:
+				self.move(left=1)
+				cwd = self.env.cwd
+				if cwd.pointer < len(cwd) - 1:
+					break
+				if cwd.path == '/':
+					break
+			self.move(down=1)
+			self.traverse()
+		else:
+			self.move(down=1)
+			self.traverse()
+
+	# --------------------------
+	# -- Shortcuts / Wrappers
+	# --------------------------
+
+	def execute_command(self, cmd, **kw):
+		return self.run(cmd, **kw)
+
+	def edit_file(self, file=None):
+		"""Calls execute_file with the current file and app='editor'"""
+		if file is None:
+			file = self.env.cf
+		elif isinstance(file, str):
+			file = File(os.path.expanduser(file))
+		if file is None:
+			return
+		self.execute_file(file, app = 'editor')
+
+	def toggle_boolean_option(self, string):
+		"""Toggle a boolean option named <string>"""
+		if isinstance(self.env.settings[string], bool):
+			self.env.settings[string] ^= True
+
+	def set_option(self, optname, value):
+		"""Set the value of an option named <optname>"""
+		self.env.settings[optname] = value
+
+	def sort(self, func=None, reverse=None):
+		if reverse is not None:
+			self.env.settings['sort_reverse'] = bool(reverse)
+
+		if func is not None:
+			self.env.settings['sort'] = str(func)
+
+	def set_filter(self, fltr):
+		try:
+			self.env.cwd.filter = fltr
+		except:
+			pass
+
+	def mark(self, all=False, toggle=False, val=None, movedown=None, narg=1):
+		"""
+		A wrapper for the directory.mark_xyz functions.
+
+		Arguments:
+		all - change all files of the current directory at once?
+		toggle - toggle the marked-status?
+		val - mark or unmark?
+		"""
+
+		if self.env.cwd is None:
+			return
+
+		cwd = self.env.cwd
+
+		if not cwd.accessible:
+			return
+
+		if movedown is None:
+			movedown = not all
+
+		if val is None and toggle is False:
+			return
+
+		if all:
+			if toggle:
+				cwd.toggle_all_marks()
+			else:
+				cwd.mark_all(val)
+		else:
+			for i in range(cwd.pointer, min(cwd.pointer + narg, len(cwd))):
+				item = cwd.files[i]
+				if item is not None:
+					if toggle:
+						cwd.toggle_mark(item)
+					else:
+						cwd.mark_item(item, val)
+
+		if movedown:
+			self.move(down=narg)
+
+		if hasattr(self.ui, 'redraw_main_column'):
+			self.ui.redraw_main_column()
+		if hasattr(self.ui, 'status'):
+			self.ui.status.need_redraw = True
+
+	# --------------------------
+	# -- Searching
+	# --------------------------
+
 	def search(self, order=None, forward=True):
 		original_order = order
 		if self.search_forward:
@@ -74,26 +347,11 @@ class Actions(EnvironmentAware, SettingsAware):
 			self.search_method = order
 			self.search_forward = forward
 
-	def resize(self):
-		"""Update the size of the UI"""
-		self.ui.update_size()
-
-	def exit(self):
-		"""Exit the program"""
-		raise SystemExit()
-
-	def enter_dir(self, path, remember=False):
-		"""Enter the directory at the given path"""
-		if remember:
-			cwd = self.env.cwd
-			result = self.env.enter_dir(path)
-			self.bookmarks.remember(cwd)
-			return result
-		return self.env.enter_dir(path)
-
-	def cd(self, path, remember=True):
-		"""enter the directory at the given path, remember=True"""
-		self.enter_dir(path, remember)
+	# --------------------------
+	# -- Tags
+	# --------------------------
+	# Tags are saved in ~/.ranger/tagged and simply mark if a
+	# file is important to you in any context.
 
 	def tag_toggle(self, movedown=None):
 		try:
@@ -107,7 +365,7 @@ class Actions(EnvironmentAware, SettingsAware):
 		if movedown is None:
 			movedown = len(sel) == 1
 		if movedown:
-			self.move_pointer(relative=1)
+			self.move(down=1)
 
 		if hasattr(self.ui, 'redraw_main_column'):
 			self.ui.redraw_main_column()
@@ -124,11 +382,16 @@ class Actions(EnvironmentAware, SettingsAware):
 		if movedown is None:
 			movedown = len(sel) == 1
 		if movedown:
-			self.move_pointer(relative=1)
+			self.move(down=1)
 
 		if hasattr(self.ui, 'redraw_main_column'):
 			self.ui.redraw_main_column()
 
+	# --------------------------
+	# -- Bookmarks
+	# --------------------------
+	# Using ranger.container.bookmarks.
+
 	def enter_bookmark(self, key):
 		"""Enter the bookmark with the name <key>"""
 		try:
@@ -148,35 +411,10 @@ class Actions(EnvironmentAware, SettingsAware):
 		"""Delete the bookmark with the name <key>"""
 		self.bookmarks.delete(key)
 
-	def move_left(self, narg=None):
-		"""Enter the parent directory"""
-		if narg is None:
-			narg = 1
-		try:
-			directory = os.path.join(*(['..'] * narg))
-		except:
-			return
-		self.env.enter_dir(directory)
-
-	def move_right(self, mode=0, narg=None):
-		"""Enter the current directory or execute the current file"""
-		cf = self.env.cf
-		sel = self.env.get_selection()
-
-		if isinstance(narg, int):
-			mode = narg
-		if not self.env.enter_dir(cf):
-			if sel:
-				if self.execute_file(sel, mode=mode) is False:
-					self.open_console(cmode.OPEN_QUICK)
-
-	def history_go(self, relative):
-		"""Move back and forth in the history"""
-		self.env.history_go(relative)
-
-	def handle_mouse(self):
-		"""Handle mouse-buttons if one was pressed"""
-		self.ui.handle_mouse()
+	# --------------------------
+	# -- Pager
+	# --------------------------
+	# These commands open the built-in pager and set specific sources.
 
 	def display_command_help(self, console_widget):
 		if not hasattr(self.ui, 'open_pager'):
@@ -239,229 +477,59 @@ class Actions(EnvironmentAware, SettingsAware):
 			pager = self.ui.open_embedded_pager()
 			pager.set_source(f)
 
-	def execute_file(self, files, **kw):
-		"""Execute a file.
-		app is the name of a method in Applications, without the "app_"
-		flags is a string consisting of runner.ALLOWED_FLAGS
-		mode is a positive integer.
-		Both flags and mode specify how the program is run."""
-
-		if isinstance(files, set):
-			files = list(files)
-		elif type(files) not in (list, tuple):
-			files = [files]
-
-		return self.run(files=list(files), **kw)
-
-	def execute_command(self, cmd, **kw):
-		return self.run(cmd, **kw)
-
-	def edit_file(self, file=None):
-		"""Calls execute_file with the current file and app='editor'"""
-		if file is None:
-			file = self.env.cf
-		elif isinstance(file, str):
-			file = File(os.path.expanduser(file))
-		if file is None:
-			return
-		self.execute_file(file, app = 'editor')
-
-	def open_console(self, mode=':', string=''):
-		"""Open the console if the current UI supports that"""
-		if hasattr(self.ui, 'open_console'):
-			self.ui.open_console(mode, string)
-
-	def move_pointer(self, relative = 0, absolute = None, narg=None):
-		"""Move the pointer down by <relative> or to <absolute>"""
-		self.env.cwd.move(relative=relative,
-				absolute=absolute, narg=narg)
-
-	def move(self, dir, narg=None):
-		if narg is not None:
-			dir = dir * narg
-
-		self.notify(str(dir))
-
-		if dir.right is not None:
-			if dir.right >= 0:
-				if dir.has_explicit_direction:
-					self.move_right(narg=dir.right)
-				else:
-					self.move_right(narg=dir.original_right - 1)
-			elif dir.right < 0:
-				self.move_left(narg=dir.left)
+	# --------------------------
+	# -- Tabs
+	# --------------------------
+	# This implementation of tabs is very simple and keeps track of
+	# directory paths only.
+
+	def tab_open(self, name, path=None):
+		do_emit_signal = name != self.current_tab
+		self.current_tab = name
+		if path or (name in self.tabs):
+			self.enter_dir(path or self.tabs[name])
 		else:
-			if dir.percent:
-				if dir.absolute:
-					self.move_pointer_by_percentage( \
-							absolute=dir.down, narg=narg)
-				else:
-					self.move_pointer_by_percentage( \
-							relative=dir.down, narg=narg)
-			elif dir.pages:
-				self.move_pointer_by_pages(dir.down)
-			elif dir.absolute:
-				if dir.has_explicit_direction:
-					self.move_pointer(absolute=dir.down)
-				else:
-					self.move_pointer(absolute=dir.original_down)
-			else:
-				self.move_pointer(relative=dir.down)
-
-	def draw_bookmarks(self):
-		self.ui.browser.draw_bookmarks = True
-
-	def hide_bookmarks(self):
-		self.ui.browser.draw_bookmarks = False
-
-	def move_pointer_by_pages(self, relative):
-		"""Move the pointer down by <relative> pages"""
-		self.env.cwd.move(relative=int(relative * self.env.termsize[0]))
-
-	def move_pointer_by_percentage(self, relative=0, absolute=None, narg=None):
-		"""Move the pointer down by <relative>% or to <absolute>%"""
-		try:
-			factor = len(self.env.cwd) / 100.0
-		except:
-			return
-
-		if narg is not None:
-			absolute = narg
-
-		if absolute is not None:
-			absolute = int(absolute * factor)
-
-		self.env.cwd.move(
-				relative=int(relative * factor),
-				absolute=absolute)
-
-	def scroll(self, relative):
-		"""Scroll down by <relative> lines"""
-		if hasattr(self.ui, 'scroll'):
-			self.ui.scroll(relative)
-			self.env.cf = self.env.cwd.pointed_obj
-
-	def redraw_window(self):
-		"""Redraw the window"""
-		self.ui.redraw_window()
-
-	def reset(self):
-		"""Reset the filemanager, clearing the directory buffer"""
-		old_path = self.env.cwd.path
-		self.env.directories = {}
-		self.enter_dir(old_path)
-
-	def toggle_boolean_option(self, string):
-		"""Toggle a boolean option named <string>"""
-		if isinstance(self.env.settings[string], bool):
-			self.env.settings[string] ^= True
-
-	def sort(self, func=None, reverse=None):
-		if reverse is not None:
-			self.env.settings['reverse'] = bool(reverse)
-
-		if func is not None:
-			self.env.settings['sort'] = str(func)
-
-	def force_load_preview(self):
-		cf = self.env.cf
-		if hasattr(cf, 'unload') and hasattr(cf, 'load_content'):
-			cf.unload()
-			cf.load_content()
-
-	def reload_cwd(self):
-		try:
-			cwd = self.env.cwd
-		except:
-			pass
-		cwd.unload()
-		cwd.load_content()
-
-	def traverse(self):
-		cf = self.env.cf
-		cwd = self.env.cwd
-		if cf is not None and cf.is_directory:
-			self.enter_dir(cf.path)
-		elif cwd.pointer >= len(cwd) - 1:
-			while True:
-				self.enter_dir('..')
-				cwd = self.env.cwd
-				if cwd.pointer < len(cwd) - 1:
-					break
-				if cwd.path == '/':
-					break
-			self.move_pointer(1)
-			self.traverse()
-		else:
-			self.move_pointer(1)
-			self.traverse()
-
-	def set_filter(self, fltr):
-		try:
-			self.env.cwd.filter = fltr
-		except:
-			pass
-
-	def notify(self, text, duration=4, bad=False):
-		if isinstance(text, Exception):
-			if ranger.arg.debug:
-				raise
-			bad = True
-		text = str(text)
-		self.log.appendleft(text)
-		if hasattr(self.ui, 'notify'):
-			self.ui.notify(text, duration=duration, bad=bad)
-
-	def hint(self, text):
-		self.notify(text)
-
-	def mark(self, all=False, toggle=False, val=None, movedown=None, narg=1):
-		"""
-		A wrapper for the directory.mark_xyz functions.
-
-		Arguments:
-		all - change all files of the current directory at once?
-		toggle - toggle the marked-status?
-		val - mark or unmark?
-		"""
-
-		if self.env.cwd is None:
-			return
-
-		cwd = self.env.cwd
-
-		if not cwd.accessible:
-			return
-
-		if movedown is None:
-			movedown = not all
-
-		if val is None and toggle is False:
-			return
-
-		if all:
-			if toggle:
-				cwd.toggle_all_marks()
-			else:
-				cwd.mark_all(val)
-		else:
-			for i in range(cwd.pointer, min(cwd.pointer + narg, len(cwd))):
-				item = cwd.files[i]
-				if item is not None:
-					if toggle:
-						cwd.toggle_mark(item)
-					else:
-						cwd.mark_item(item, val)
-
-		if movedown:
-			self.move_pointer(relative=narg)
-
-		if hasattr(self.ui, 'redraw_main_column'):
-			self.ui.redraw_main_column()
-		if hasattr(self.ui, 'status'):
-			self.ui.status.need_redraw = True
-
-	# ------------------------------------ filesystem operations
+			self._update_current_tab()
+		if do_emit_signal:
+			self.signal_emit('tab.change')
+
+	def tab_close(self, name=None):
+		if name is None:
+			name = self.current_tab
+		if name == self.current_tab:
+			direction = -1 if name == self._get_tab_list()[-1] else 1
+			previous = self.current_tab
+			self.tab_move(direction)
+			if previous == self.current_tab:
+				return  # can't close last tab
+		if name in self.tabs:
+			del self.tabs[name]
+
+	def tab_move(self, offset):
+		assert isinstance(offset, int)
+		tablist = self._get_tab_list()
+		current_index = tablist.index(self.current_tab)
+		newtab = tablist[(current_index + offset) % len(tablist)]
+		if newtab != self.current_tab:
+			self.tab_open(newtab)
+
+	def tab_new(self):
+		for i in range(10):
+			i = (i + 1) % 10
+			if not i in self.tabs:
+				self.tab_open(i)
+				break
+
+	def _get_tab_list(self):
+		assert len(self.tabs) > 0, "There must be >=1 tabs at all times"
+		return sorted(self.tabs)
+
+	def _update_current_tab(self):
+		self.tabs[self.current_tab] = self.env.cwd.path
+
+	# --------------------------
+	# -- File System Operations
+	# --------------------------
 
 	def copy(self):
 		"""Copy the selected items"""
@@ -567,7 +635,6 @@ class Actions(EnvironmentAware, SettingsAware):
 		except OSError as err:
 			self.notify(err)
 
-
 	def rename(self, src, dest):
 		if hasattr(src, 'path'):
 			src = src.path
diff --git a/ranger/core/environment.py b/ranger/core/environment.py
index 4301d237..0b38c475 100644
--- a/ranger/core/environment.py
+++ b/ranger/core/environment.py
@@ -21,15 +21,15 @@ from os.path import abspath, normpath, join, expanduser, isdir
 
 from ranger.fsobject.directory import Directory, NoDirectoryGiven
 from ranger.container import KeyBuffer, History
+from ranger.ext.signal_dispatcher import SignalDispatcher
 from ranger.shared import SettingsAware
 
-class Environment(SettingsAware):
+class Environment(SettingsAware, SignalDispatcher):
 	"""A collection of data which is relevant for more than
 	one class.
 	"""
 
 	cwd = None  # current directory
-	cf = None  # current file
 	copy = None
 	cmd = None
 	cut = None
@@ -42,7 +42,9 @@ class Environment(SettingsAware):
 	keybuffer = None
 
 	def __init__(self, path):
+		SignalDispatcher.__init__(self)
 		self.path = abspath(expanduser(path))
+		self._cf = None
 		self.pathway = ()
 		self.directories = {}
 		self.keybuffer = KeyBuffer(None, None)
@@ -59,6 +61,22 @@ class Environment(SettingsAware):
 		from ranger.shared import EnvironmentAware
 		EnvironmentAware.env = self
 
+		self.signal_bind('move', self._set_cf_from_signal, priority=0.1,
+				weak=True)
+
+	def _set_cf_from_signal(self, signal):
+		self._cf = signal.new
+
+	def _set_cf(self, value):
+		if value is not self._cf:
+			previous = self._cf
+			self.signal_emit('move', previous=previous, new=value)
+
+	def _get_cf(self):
+		return self._cf
+
+	cf = property(_get_cf, _set_cf)
+
 	def key_append(self, key):
 		"""Append a key to the keybuffer"""
 
@@ -100,14 +118,14 @@ class Environment(SettingsAware):
 			except KeyError:
 				return directory
 
-	def garbage_collect(self):
+	def garbage_collect(self, age):
 		"""Delete unused directory objects"""
-		from ranger.fsobject.fsobject import FileSystemObject
-		for key in tuple(self.directories.keys()):
+		for key in tuple(self.directories):
 			value = self.directories[key]
-			if isinstance(value, FileSystemObject):
-				if value.is_older_than(1200):
-					del self.directories[key]
+			if value.is_older_than(age): # and not value in self.pathway:
+				del self.directories[key]
+				if value.is_directory:
+					value.files = None
 
 	def get_selection(self):
 		if self.cwd:
@@ -154,6 +172,8 @@ class Environment(SettingsAware):
 		if path is None: return
 		path = str(path)
 
+		previous = self.cwd
+
 		# get the absolute path
 		path = normpath(join(self.path, expanduser(path)))
 
@@ -165,9 +185,12 @@ class Environment(SettingsAware):
 		except NoDirectoryGiven:
 			return False
 
+		try:
+			os.chdir(path)
+		except:
+			return True
 		self.path = path
 		self.cwd = new_cwd
-		os.chdir(path)
 
 		self.cwd.load_content_if_outdated()
 
@@ -186,11 +209,14 @@ class Environment(SettingsAware):
 		self.assign_cursor_positions_for_subdirs()
 
 		# set the current file.
-		self.cwd.directories_first = self.settings.directories_first
+		self.cwd.sort_directories_first = self.settings.sort_directories_first
+		self.cwd.sort_reverse = self.settings.sort_reverse
 		self.cwd.sort_if_outdated()
 		self.cf = self.cwd.pointed_obj
 
 		if history:
 			self.history.add(new_cwd)
 
+		self.signal_emit('cd', previous=previous, new=self.cwd)
+
 		return True
diff --git a/ranger/core/fm.py b/ranger/core/fm.py
index 994447b0..25e66407 100644
--- a/ranger/core/fm.py
+++ b/ranger/core/fm.py
@@ -19,6 +19,9 @@ The File Manager, putting the pieces together
 
 from time import time
 from collections import deque
+from curses import KEY_MOUSE, KEY_RESIZE
+import os
+import sys
 
 import ranger
 from ranger.core.actions import Actions
@@ -26,23 +29,27 @@ from ranger.container import Bookmarks
 from ranger.core.runner import Runner
 from ranger import relpath_conf
 from ranger.ext.get_executables import get_executables
+from ranger.ext.signal_dispatcher import SignalDispatcher
 from ranger import __version__
 from ranger.fsobject import Loader
 
 CTRL_C = 3
 TICKS_BEFORE_COLLECTING_GARBAGE = 100
+TIME_BEFORE_FILE_BECOMES_GARBAGE = 1200
 
-class FM(Actions):
+class FM(Actions, SignalDispatcher):
 	input_blocked = False
 	input_blocked_until = 0
-	stderr_to_out = False
 	def __init__(self, ui=None, bookmarks=None, tags=None):
 		"""Initialize FM."""
 		Actions.__init__(self)
+		SignalDispatcher.__init__(self)
 		self.ui = ui
 		self.log = deque(maxlen=20)
 		self.bookmarks = bookmarks
 		self.tags = tags
+		self.tabs = {}
+		self.current_tab = 1
 		self.loader = Loader()
 		self._executables = None
 		self.apps = self.settings.apps.CustomApplications()
@@ -55,6 +62,10 @@ class FM(Actions):
 		from ranger.shared import FileManagerAware
 		FileManagerAware.fm = self
 
+		self.log.append('Ranger {0} started! Process ID is {1}.' \
+				.format(__version__, os.getpid()))
+		self.log.append('Running on Python ' + sys.version.replace('\n',''))
+
 	@property
 	def executables(self):
 		if self._executables is None:
@@ -88,6 +99,8 @@ class FM(Actions):
 			self.ui = DefaultUI()
 			self.ui.initialize()
 
+		self.env.signal_bind('cd', self._update_current_tab)
+
 	def block_input(self, sec=0):
 		self.input_blocked = sec != 0
 		self.input_blocked_until = time() + sec
@@ -131,16 +144,21 @@ class FM(Actions):
 				key = ui.get_next_key()
 
 				if key > 0:
-					if self.input_blocked and \
-							time() > self.input_blocked_until:
-						self.input_blocked = False
-					if not self.input_blocked:
-						ui.handle_key(key)
+					if key == KEY_MOUSE:
+						ui.handle_mouse()
+					elif key == KEY_RESIZE:
+						ui.update_size()
+					else:
+						if self.input_blocked and \
+								time() > self.input_blocked_until:
+							self.input_blocked = False
+						if not self.input_blocked:
+							ui.handle_key(key)
 
 				gc_tick += 1
 				if gc_tick > TICKS_BEFORE_COLLECTING_GARBAGE:
 					gc_tick = 0
-					env.garbage_collect()
+					env.garbage_collect(TIME_BEFORE_FILE_BECOMES_GARBAGE)
 
 		except KeyboardInterrupt:
 			# this only happens in --debug mode. By default, interrupts
diff --git a/ranger/defaults/apps.py b/ranger/defaults/apps.py
index 347b9ce2..9543badb 100644
--- a/ranger/defaults/apps.py
+++ b/ranger/defaults/apps.py
@@ -59,6 +59,7 @@ class CustomApplications(Applications):
 
 		if f.extension is not None:
 			if f.extension in ('pdf'):
+				c.flags += 'd'
 				return self.either(c, 'evince', 'zathura', 'apvlv')
 			if f.extension in ('html', 'htm', 'xhtml', 'swf'):
 				return self.either(c, 'firefox', 'opera', 'elinks')
@@ -114,7 +115,7 @@ class CustomApplications(Applications):
 	@depends_on('mplayer')
 	def app_mplayer(self, c):
 		if c.mode is 1:
-			return tup('mplayer', *c)
+			return tup('mplayer', '-fs', *c)
 
 		elif c.mode is 2:
 			args = "mplayer -fs -sid 0 -vfm ffmpeg -lavdopts " \
@@ -126,7 +127,7 @@ class CustomApplications(Applications):
 			return tup('mplayer', '-mixer', 'software', *c)
 
 		else:
-			return tup('mplayer', '-fs', *c)
+			return tup('mplayer', *c)
 
 	@depends_on("eog")
 	def app_eye_of_gnome(self, c):
@@ -151,15 +152,18 @@ class CustomApplications(Applications):
 		if len(c.files) > 1:
 			return tup('feh', *c)
 
-		from collections import deque
+		try:
+			from collections import deque
 
-		directory = self.fm.env.get_directory(c.file.dirname)
-		images = [f.path for f in directory.files if f.image]
-		position = images.index(c.file.path)
-		deq = deque(images)
-		deq.rotate(-position)
+			directory = self.fm.env.get_directory(c.file.dirname)
+			images = [f.path for f in directory.files if f.image]
+			position = images.index(c.file.path)
+			deq = deque(images)
+			deq.rotate(-position)
 
-		return tup('feh', *deq)
+			return tup('feh', *deq)
+		except:
+			return tup('feh', *c)
 
 	@depends_on("gimp")
 	def app_gimp(self, c):
@@ -231,6 +235,6 @@ class CustomApplications(Applications):
 	@depends_on('totem')
 	def app_totem(self, c):
 		if c.mode is 0:
-			return tup("totem", "--fullscreen", *c)
-		if c.mode is 1:
 			return tup("totem", *c)
+		if c.mode is 1:
+			return tup("totem", "--fullscreen", *c)
diff --git a/ranger/defaults/commands.py b/ranger/defaults/commands.py
index b1518013..f653168f 100644
--- a/ranger/defaults/commands.py
+++ b/ranger/defaults/commands.py
@@ -199,9 +199,10 @@ class find(Command):
 		search = parse(self.line).rest(1)
 		search = re.escape(search)
 		self.fm.env.last_search = re.compile(search, re.IGNORECASE)
+		self.fm.search_method = 'search'
 
 		if self.count == 1:
-			self.fm.move_right()
+			self.fm.move(right=1)
 			self.fm.block_input(0.5)
 
 	def quick_open(self):
@@ -239,11 +240,25 @@ class quit(Command):
 	"""
 	:quit
 
+	Closes the current tab.  If there is only one tab, quit the program.
+	"""
+
+	def execute(self):
+		if len(self.fm.tabs) <= 1:
+			self.fm.exit()
+		self.fm.tab_close()
+
+
+class quit_now(Command):
+	"""
+	:quit!
+
 	Quits the program immediately.
 	"""
+	name = 'quit!'
 
 	def execute(self):
-		raise SystemExit
+		self.fm.exit()
 
 
 class delete(Command):
@@ -277,8 +292,11 @@ class delete(Command):
 			# user did not confirm deletion
 			return
 
-		if self.fm.env.cwd.marked_items \
-		or (self.fm.env.cf.is_directory and not self.fm.env.cf.empty()):
+		cwd = self.fm.env.cwd
+		cf = self.fm.env.cf
+
+		if cwd.marked_items or (cf.is_directory and not cf.islink \
+				and len(os.listdir(cf.path)) > 0):
 			# better ask for a confirmation, when attempting to
 			# delete multiple files or a non-empty directory.
 			return self.fm.open_console(self.mode, delete.WARNING)
@@ -495,5 +513,7 @@ def get_command(name, abbrev=True):
 def command_generator(start):
 	return (cmd + ' ' for cmd in by_name if cmd.startswith(start))
 
-alias(e=edit)  # to make :e unambiguous.
+alias(e=edit, q=quit)  # for unambiguity
+alias(**{'q!':quit_now})
+alias(qall=quit_now)
 
diff --git a/ranger/defaults/keys.py b/ranger/defaults/keys.py
index f48c7012..a236ad9f 100644
--- a/ranger/defaults/keys.py
+++ b/ranger/defaults/keys.py
@@ -53,28 +53,32 @@ def _vimlike_aliases(map):
 	alias(KEY_HOME, 'gg')
 	alias(KEY_END, 'G')
 
+
+def _emacs_aliases(map):
+	alias = map.alias
+	alias(KEY_LEFT, ctrl('b'))
+	alias(KEY_RIGHT, ctrl('f'))
+	alias(KEY_HOME, ctrl('a'))
+	alias(KEY_END, ctrl('e'))
+	alias(KEY_DC, ctrl('d'))
+	alias(DEL, ctrl('h'))
+
+
 def initialize_commands(map):
 	"""Initialize the commands for the main user interface"""
 
 	# -------------------------------------------------------- movement
 	_vimlike_aliases(map)
-	map.alias(KEY_LEFT, KEY_BACKSPACE, DEL)
-
-	map(KEY_DOWN, fm.move_pointer(relative=1))
-	map(KEY_UP, fm.move_pointer(relative=-1))
-	map(KEY_RIGHT, KEY_ENTER, ctrl('j'), fm.move_right())
-	map(KEY_LEFT, KEY_BACKSPACE, DEL, fm.move_left(1))
-	map(KEY_HOME, fm.move_pointer(absolute=0))
-	map(KEY_END, fm.move_pointer(absolute=-1))
+	_basic_movement(map)
 
-	map(KEY_HOME, fm.move_pointer(absolute=0))
-	map(KEY_END, fm.move_pointer(absolute=-1))
+	map.alias(KEY_LEFT, KEY_BACKSPACE, DEL)
+	map.alias(KEY_RIGHT, KEY_ENTER, ctrl('j'))
 
-	map('%', fm.move_pointer_by_percentage(absolute=50))
-	map(KEY_NPAGE, fm.move_pointer_by_pages(1))
-	map(KEY_PPAGE, fm.move_pointer_by_pages(-1))
-	map(ctrl('d'), 'J', fm.move_pointer_by_pages(0.5))
-	map(ctrl('u'), 'K', fm.move_pointer_by_pages(-0.5))
+	map('%', fm.move(to=50, percentage=True))
+	map(KEY_NPAGE, ctrl('f'), fm.move(down=1, pages=True))
+	map(KEY_PPAGE, ctrl('b'), fm.move(up=1, pages=True))
+	map(ctrl('d'), 'J', fm.move(down=0.5, pages=True))
+	map(ctrl('u'), 'K', fm.move(up=0.5, pages=True))
 
 	map(']', fm.traverse())
 	map('[', fm.history_go(-1))
@@ -107,14 +111,16 @@ def initialize_commands(map):
 	map('du', fm.execute_command('du --max-depth=1 -h | less'))
 
 	# -------------------------------------------------- toggle options
-	map('b', hint="show_//h//idden //p//review_files //d//irectories_first " \
-		"//c//ollapse_preview flush//i//nput")
-	map('bh', fm.toggle_boolean_option('show_hidden'))
-	map('bp', fm.toggle_boolean_option('preview_files'))
-	map('bP', fm.toggle_boolean_option('preview_directories'))
-	map('bi', fm.toggle_boolean_option('flushinput'))
-	map('bd', fm.toggle_boolean_option('directories_first'))
-	map('bc', fm.toggle_boolean_option('collapse_preview'))
+	map('b', fm.notify('Warning: settings are now changed with z!', bad=True))
+	map('z', hint="show_//h//idden //p//review_files //d//irectories_first " \
+		"//c//ollapse_preview flush//i//nput ca//s//e_insensitive")
+	map('zh', fm.toggle_boolean_option('show_hidden'))
+	map('zp', fm.toggle_boolean_option('preview_files'))
+	map('zP', fm.toggle_boolean_option('preview_directories'))
+	map('zi', fm.toggle_boolean_option('flushinput'))
+	map('zd', fm.toggle_boolean_option('sort_directories_first'))
+	map('zc', fm.toggle_boolean_option('collapse_preview'))
+	map('zs', fm.toggle_boolean_option('sort_case_insensitive'))
 
 	# ------------------------------------------------------------ sort
 	map('o', 'O', hint="//s//ize //b//ase//n//ame //m//time //t//ype //r//everse")
@@ -133,7 +139,7 @@ def initialize_commands(map):
 			map('O' + key, fm.sort(func=val, reverse=True))
 
 	map('or', 'Or', 'oR', 'OR', lambda arg: \
-			arg.fm.sort(reverse=not arg.fm.settings.reverse))
+			arg.fm.sort(reverse=not arg.fm.settings.sort_reverse))
 
 	# ----------------------------------------------- console shortcuts
 	@map("A")
@@ -146,6 +152,8 @@ def initialize_commands(map):
 	map('f', fm.open_console(cmode.COMMAND_QUICK, 'find '))
 	map('tf', fm.open_console(cmode.COMMAND, 'filter '))
 	map('d', hint='d//u// (disk usage) d//d// (cut)')
+	map('@', fm.open_console(cmode.OPEN, '@'))
+	map('#', fm.open_console(cmode.OPEN, 'p!'))
 
 	# --------------------------------------------- jump to directories
 	map('gh', fm.cd('~'))
@@ -162,24 +170,32 @@ def initialize_commands(map):
 	map('gs', fm.cd('/srv'))
 	map('gR', fm.cd(RANGERDIR))
 
+	# ------------------------------------------------------------ tabs
+	map('gc', ctrl('W'), fm.tab_close())
+	map('gt', TAB, fm.tab_move(1))
+	map('gT', KEY_BTAB, fm.tab_move(-1))
+	map('gn', ctrl('N'), fm.tab_new())
+	for n in range(10):
+		map('g' + str(n), fm.tab_open(n))
+
 	# ------------------------------------------------------- searching
 	map('/', fm.open_console(cmode.SEARCH))
 
 	map('n', fm.search())
 	map('N', fm.search(forward=False))
 
-	map(TAB, fm.search(order='tag'))
+	map('ct', fm.search(order='tag'))
 	map('cc', fm.search(order='ctime'))
 	map('cm', fm.search(order='mimetype'))
 	map('cs', fm.search(order='size'))
-	map('c', hint='//c//time //m//imetype //s//ize')
+	map('c', hint='//c//time //m//imetype //s//ize //t//agged')
 
 	# ------------------------------------------------------- bookmarks
 	for key in ALLOWED_BOOKMARK_KEYS:
 		map("`" + key, "'" + key, fm.enter_bookmark(key))
 		map("m" + key, fm.set_bookmark(key))
 		map("um" + key, fm.unset_bookmark(key))
-	map("`", "'", "m", draw_bookmarks=True)
+	map("`", "'", "m", "um", draw_bookmarks=True)
 
 	# ---------------------------------------------------- change views
 	map('i', fm.display_file())
@@ -204,10 +220,18 @@ def initialize_commands(map):
 
 	# ------------------------------------------------ system functions
 	_system_functions(map)
-	map('ZZ', fm.exit())
+	map('ZZ', 'ZQ', fm.exit())
 	map(ctrl('R'), fm.reset())
 	map('R', fm.reload_cwd())
-	map(ctrl('C'), fm.exit())
+	@map(ctrl('C'))
+	def ctrl_c(arg):
+		try:
+			item = arg.fm.loader.queue[0]
+		except:
+			arg.fm.notify("Type Q or :quit<Enter> to exit Ranger")
+		else:
+			arg.fm.notify("Aborting: " + item.get_description())
+			arg.fm.loader.remove(index=0)
 
 	map(':', ';', fm.open_console(cmode.COMMAND))
 	map('>', fm.open_console(cmode.COMMAND_QUICK))
@@ -220,33 +244,24 @@ def initialize_commands(map):
 def initialize_console_commands(map):
 	"""Initialize the commands for the console widget only"""
 
+	_basic_movement(map)
+	_emacs_aliases(map)
+
 	# -------------------------------------------------------- movement
 	map(KEY_UP, wdg.history_move(-1))
 	map(KEY_DOWN, wdg.history_move(1))
-
-	map(ctrl('b'), KEY_LEFT, wdg.move(relative = -1))
-	map(ctrl('f'), KEY_RIGHT, wdg.move(relative = 1))
-	map(ctrl('a'), KEY_HOME, wdg.move(absolute = 0))
-	map(ctrl('e'), KEY_END, wdg.move(absolute = -1))
+	map(KEY_HOME, wdg.move(right=0, absolute=True))
+	map(KEY_END, wdg.move(right=-1, absolute=True))
 
 	# ----------------------------------------- deleting / pasting text
-	map(ctrl('d'), KEY_DC, wdg.delete(0))
-	map(ctrl('h'), KEY_BACKSPACE, DEL, wdg.delete(-1))
+	map(KEY_DC, wdg.delete(0))
+	map(KEY_BACKSPACE, DEL, wdg.delete(-1))
 	map(ctrl('w'), wdg.delete_word())
 	map(ctrl('k'), wdg.delete_rest(1))
 	map(ctrl('u'), wdg.delete_rest(-1))
 	map(ctrl('y'), wdg.paste())
 
-	# ----------------------------------------------------- typing keys
-	def type_key(arg):
-		arg.wdg.type_key(arg.keys)
-
-	for i in range(ord(' '), ord('~')+1):
-		map(i, type_key)
-
 	# ------------------------------------------------ system functions
-	_system_functions(map)
-
 	map(KEY_F1, lambda arg: arg.fm.display_command_help(arg.wdg))
 	map(ctrl('c'), ESC, wdg.close())
 	map(ctrl('j'), KEY_ENTER, wdg.execute())
@@ -286,42 +301,44 @@ def initialize_embedded_pager_commands(map):
 	map('q', 'i', ESC, lambda arg: arg.fm.ui.close_embedded_pager())
 	map.rebuild_paths()
 
+
 def _base_pager_commands(map):
 	_basic_movement(map)
 	_vimlike_aliases(map)
 	_system_functions(map)
 
 	# -------------------------------------------------------- movement
-	map(KEY_LEFT, wdg.move_horizontal(relative=-4))
-	map(KEY_RIGHT, wdg.move_horizontal(relative=4))
-	map(KEY_NPAGE, wdg.move(relative=1, pages=True))
-	map(KEY_PPAGE, wdg.move(relative=-1, pages=True))
-	map(ctrl('d'), wdg.move(relative=0.5, pages=True))
-	map(ctrl('u'), wdg.move(relative=-0.5, pages=True))
-	map(' ', wdg.move(relative=0.8, pages=True))
+	map(KEY_LEFT, wdg.move(left=4))
+	map(KEY_RIGHT, wdg.move(right=4))
+	map(KEY_NPAGE, ctrl('f'), wdg.move(down=1, pages=True))
+	map(KEY_PPAGE, ctrl('b'), wdg.move(up=1, pages=True))
+	map(ctrl('d'), wdg.move(down=0.5, pages=True))
+	map(ctrl('u'), wdg.move(up=0.5, pages=True))
+	map(' ', wdg.move(down=0.8, pages=True))
 
 	# ---------------------------------------------------------- others
 	map('E', fm.edit_file())
 	map('?', fm.display_help())
 
 	# --------------------------------------------- less-like shortcuts
-	map.alias(KEY_NPAGE, 'd')
-	map.alias(KEY_PPAGE, 'u')
+	map.alias(KEY_NPAGE, 'f')
+	map.alias(KEY_PPAGE, 'b')
+	map.alias(ctrl('d'), 'd')
+	map.alias(ctrl('u'), 'u')
 
 
 def _system_functions(map):
-	# Each commandlist should have this bindings
-	map(KEY_RESIZE, fm.resize())
-	map(KEY_MOUSE, fm.handle_mouse())
 	map('Q', fm.exit())
 	map(ctrl('L'), fm.redraw_window())
 
 
 def _basic_movement(map):
-	map(KEY_DOWN, wdg.move(relative=1))
-	map(KEY_UP, wdg.move(relative=-1))
-	map(KEY_HOME, wdg.move(absolute=0))
-	map(KEY_END, wdg.move(absolute=-1))
+	map(KEY_DOWN, wdg.move(down=1))
+	map(KEY_UP, wdg.move(up=1))
+	map(KEY_RIGHT, wdg.move(right=1))
+	map(KEY_LEFT, wdg.move(left=1))
+	map(KEY_HOME, wdg.move(to=0))
+	map(KEY_END, wdg.move(to=-1))
 
 
 
@@ -339,7 +356,7 @@ def base_directions():
 	map('<end>', dir=Direction(down=-1, absolute=True))
 	map('<pagedown>', dir=Direction(down=1, pages=True))
 	map('<pageup>', dir=Direction(down=-1, pages=True))
-	map('%<any>', dir=Direction(down=1, percent=True, absolute=True))
+	map('%<any>', dir=Direction(down=1, percentage=True, absolute=True))
 	map('<space>', dir=Direction(down=1, pages=True))
 	map('<CR>', dir=Direction(down=1))
 
diff --git a/ranger/defaults/options.py b/ranger/defaults/options.py
index a7090285..6b2a0dc9 100644
--- a/ranger/defaults/options.py
+++ b/ranger/defaults/options.py
@@ -33,7 +33,8 @@ of the values stay the same.
 
 from ranger.api.options import *
 
-# Which files are hidden if show_hidden is False?
+# Which files should be hidden?  Toggle this by typing `zh' or
+# changing the setting `show_hidden'
 hidden_filter = regexp(
 	r'lost\+found|^\.|~$|\.(:?pyc|pyo|bak|swp)$')
 show_hidden = False
@@ -50,8 +51,19 @@ preview_directories = True
 max_filesize_for_preview = 300 * 1024  # 300kb
 collapse_preview = True
 
+# Save the console history on exit?
+save_console_history = True
+
 # Draw borders around columns?
 draw_borders = False
+draw_bookmark_borders = True
+
+# How many columns are there, and what are their relative widths?
+column_ratios = (1, 1, 4, 3)
+
+# Display the file size in the main column or status bar?
+display_size_in_main_column = True
+display_size_in_status_bar = False
 
 # Set a title for the window?
 update_title = True
@@ -80,6 +92,26 @@ show_cursor = False
 
 # One of: size, basename, mtime, type
 sort = 'basename'
-reverse = False
-directories_first = True
+sort_reverse = False
+sort_case_insensitive = False
+sort_directories_first = True
+
+
+# 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.
+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
 
+# The above function was just an example, let's set it back to None
+colorscheme_overlay = None
diff --git a/ranger/ext/direction.py b/ranger/ext/direction.py
index 30eb87ce..417f3add 100644
--- a/ranger/ext/direction.py
+++ b/ranger/ext/direction.py
@@ -13,109 +13,123 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-class NoDefault(object):
-	pass
-
-class Direction(object):
-	"""An object with a down and right method"""
-	def __init__(self, right=None, down=None, absolute=False,
-			percent=False, pages=False, **keywords):
-		self.has_explicit_direction = False
-
-		if 'up' in keywords:
-			self.down = -keywords['up']
-		else:
-			self.down = down
-
-		if 'left' in keywords:
-			self.right = -keywords['left']
+"""
+Directions provide convenience methods for movement operations.
+
+Direction objects are handled just like dicts but provide
+methods like up() and down() which give you the correct value
+for the vertical direction, even if only the "up" or "down" key
+has been defined.
+
+Example application:
+d = Direction(down=5)
+print(d.up()) # prints -5
+print(bool(d.horizontal())) # False, since no horizontal direction is defined
+"""
+
+class Direction(dict):
+	__doc__ = __doc__  # for nicer pydoc
+
+	def __init__(self, dictionary=None, **keywords):
+		if dictionary is not None:
+			dict.__init__(self, dictionary)
 		else:
-			self.right = right
+			dict.__init__(self, keywords)
+		if 'to' in self:
+			self['down'] = self['to']
+			self['absolute'] = True
 
-		if 'relative' in keywords:
-			self.absolute = not relative
-		else:
-			self.absolute = absolute
+	def copy(self):
+		return Direction(**self)
 
-		if 'default' in keywords:
-			self.default = keywords['default']
-		else:
-			self.default = NoDefault
+	def _get_bool(self, first, second, fallback=None):
+		try: return self[first]
+		except:
+			try: return not self[second]
+			except: return fallback
 
-		self.original_down = self.down
-		self.original_right = self.right
+	def _get_direction(self, first, second, fallback=0):
+		try: return self[first]
+		except:
+			try: return -self[second]
+			except: return fallback
 
-		self.percent = percent
-		self.pages = pages
-	
-	@property
 	def up(self):
-		if self.down is None:
-			return None
-		return -self.down
-
-	@property
-	def left(self):
-		if self.right is None:
-			return None
-		return -self.right
+		return -Direction.down(self)
 
-	@property
-	def relative(self):
-		return not self.absolute
+	def down(self):
+		return Direction._get_direction(self, 'down', 'up')
 
-	def down_or_default(self, default):
-		if self.has_been_modified:
-			return self.down
-		return default
+	def right(self):
+		return Direction._get_direction(self, 'right', 'left')
 
-	def steps_down(self, page_length=10):
-		if self.pages:
-			return self.down * page_length
-		else:
-			return self.down
+	def absolute(self):
+		return Direction._get_bool(self, 'absolute', 'relative')
 
-	def steps_right(self, page_length=10):
-		if self.pages:
-			return self.right * page_length
-		else:
-			return self.right
+	def left(self):
+		return -Direction.right(self)
 
-	def copy(self):
-		new = type(self)()
-		new.__dict__.update(self.__dict__)
-		return new
-
-	def __mul__(self, other):
-		copy = self.copy()
-		if self.absolute:
-			if self.down is not None:
-				copy.down = other
-			if self.right is not None:
-				copy.right = other
-		else:
-			if self.down is not None:
-				copy.down *= other
-			if self.right is not None:
-				copy.right *= other
-		copy.original_down = self.original_down
-		copy.original_right = self.original_right
-		return copy
-	__rmul__ = __mul__
-
-	def __str__(self):
-		s = ['<Direction']
-		if self.down is not None:
-			s.append(" down=" + str(self.down))
-		if self.right is not None:
-			s.append(" right=" + str(self.right))
-		if self.absolute:
-			s.append(" absolute")
+	def relative(self):
+		return not Direction.absolute(self)
+
+	def vertical_direction(self):
+		down = Direction.down(self)
+		return (down > 0) - (down < 0)
+
+	def horizontal_direction(self):
+		right = Direction.right(self)
+		return (right > 0) - (right < 0)
+
+	def vertical(self):
+		return set(self) & set(['up', 'down'])
+
+	def horizontal(self):
+		return set(self) & set(['left', 'right'])
+
+	def pages(self):
+		return 'pages' in self and self['pages']
+
+	def percentage(self):
+		return 'percentage' in self and self['percentage']
+
+	def multiply(self, n):
+		for key in ('up', 'right', 'down', 'left'):
+			try:
+				self[key] *= n
+			except:
+				pass
+
+	def set(self, n):
+		for key in ('up', 'right', 'down', 'left'):
+			if key in self:
+				self[key] = n
+
+	def move(self, direction, override=None, minimum=0, maximum=9999,
+			current=0, pagesize=1, offset=0):
+		"""
+		Calculates the new position in a given boundary.
+
+		Example:
+		d = Direction(pages=True)
+		d.move(direction=3) # = 3
+		d.move(direction=3, current=2) # = 5
+		d.move(direction=3, pagesize=5) # = 15
+		d.move(direction=3, pagesize=5, maximum=10) # = 10
+		d.move(direction=9, override=2) # = 18
+		"""
+		pos = direction
+		if override is not None:
+			if self.absolute():
+				pos = override
+			else:
+				pos *= override
+		if self.pages():
+			pos *= pagesize
+		elif self.percentage():
+			pos *= maximum / 100.0
+		if self.absolute():
+			if pos < minimum:
+				pos += maximum
 		else:
-			s.append(" relative")
-		if self.pages:
-			s.append(" pages")
-		if self.percent:
-			s.append(" percent")
-		s.append('>')
-		return ''.join(s)
+			pos += current
+		return int(max(min(pos, maximum + offset), minimum))
diff --git a/ranger/ext/move.py b/ranger/ext/move.py
deleted file mode 100644
index 948adae6..00000000
--- a/ranger/ext/move.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2009, 2010  Roman Zimbelmann <romanz@lavabit.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-def move_between(current, minimum, maximum, relative=0, absolute=None):
-	i = current
-	if isinstance(absolute, int):
-		i = absolute
-	if isinstance(relative, int):
-		i += relative
-	i = max(minimum, min(maximum - 1, i))
-	return i
diff --git a/ranger/ext/signal_dispatcher.py b/ranger/ext/signal_dispatcher.py
new file mode 100644
index 00000000..c1630c0c
--- /dev/null
+++ b/ranger/ext/signal_dispatcher.py
@@ -0,0 +1,103 @@
+# Copyright (C) 2009, 2010  Roman Zimbelmann <romanz@lavabit.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import weakref
+from types import MethodType
+
+class Signal(dict):
+	stopped = False
+	def __init__(self, **keywords):
+		dict.__init__(self, keywords)
+		self.__dict__ = self
+
+	def stop(self):
+		self.stopped = True
+
+
+class SignalHandler(object):
+	active = True
+	def __init__(self, signal_name, function, priority, pass_signal):
+		self.priority = max(0, min(1, priority))
+		self.signal_name = signal_name
+		self.function = function
+		self.pass_signal = pass_signal
+
+
+class SignalDispatcher(object):
+	def __init__(self):
+		self._signals = dict()
+
+	signal_clear = __init__
+
+	def signal_bind(self, signal_name, function, priority=0.5, weak=False):
+		assert isinstance(signal_name, str)
+		try:
+			handlers = self._signals[signal_name]
+		except:
+			handlers = self._signals[signal_name] = []
+		nargs = function.__code__.co_argcount
+
+		try:
+			instance = function.__self__
+		except:
+			if weak:
+				function = weakref.proxy(function)
+		else:
+			nargs -= 1
+			if weak:
+				function = (function.__func__, weakref.proxy(function.__self__))
+		handler = SignalHandler(signal_name, function, priority, nargs > 0)
+		handlers.append(handler)
+		handlers.sort(key=lambda handler: -handler.priority)
+		return handler
+
+	def signal_unbind(self, signal_handler):
+		try:
+			handlers = self._signals[signal_handler.signal_name]
+		except:
+			pass
+		else:
+			try:
+				handlers.remove(signal_handler)
+			except:
+				pass
+
+	def signal_emit(self, signal_name, **kw):
+		assert isinstance(signal_name, str)
+		try:
+			handlers = self._signals[signal_name]
+		except:
+			return
+		if not handlers:
+			return
+
+		signal = Signal(origin=self, name=signal_name, **kw)
+
+		# propagate
+		for handler in tuple(handlers):
+			if handler.active:
+				try:
+					if isinstance(handler.function, tuple):
+						fnc = MethodType(*handler.function)
+					else:
+						fnc = handler.function
+					if handler.pass_signal:
+						fnc(signal)
+					else:
+						fnc()
+					if signal.stopped:
+						return
+				except ReferenceError:
+					handlers.remove(handler)
diff --git a/ranger/fsobject/directory.py b/ranger/fsobject/directory.py
index 8bb8a78a..79e32bff 100644
--- a/ranger/fsobject/directory.py
+++ b/ranger/fsobject/directory.py
@@ -17,7 +17,6 @@ import os
 from collections import deque
 from time import time
 
-from ranger import log
 from ranger.fsobject import BAD_INFO, File, FileSystemObject
 from ranger.shared import SettingsAware
 from ranger.ext.accumulator import Accumulator
@@ -27,9 +26,13 @@ def sort_by_basename(path):
 	"""returns path.basename (for sorting)"""
 	return path.basename
 
+def sort_by_basename_icase(path):
+	"""returns case-insensitive path.basename (for sorting)"""
+	return path.basename_lower
+
 def sort_by_directory(path):
 	"""returns 0 if path is a directory, otherwise 1 (for sorting)"""
-	return 1 - int( isinstance( path, Directory ) )
+	return 1 - path.is_directory
 
 class NoDirectoryGiven(Exception):
 	pass
@@ -54,12 +57,8 @@ class Directory(FileSystemObject, Accumulator, SettingsAware):
 	last_update_time = -1
 	load_content_mtime = -1
 
-	old_show_hidden = None
-	old_directories_first = None
-	old_reverse = None
-	old_sort = None
-	old_filter = None
-	old_hidden_filter = None
+	order_outdated = False
+	content_outdated = False
 
 	sort_dict = {
 		'basename': sort_by_basename,
@@ -79,13 +78,20 @@ class Directory(FileSystemObject, Accumulator, SettingsAware):
 
 		self.marked_items = list()
 
-		# to find out if something has changed:
-		self.old_show_hidden = self.settings.show_hidden
-		self.old_directories_first = self.settings.directories_first
-		self.old_sort = self.settings.sort
-		self.old_filter = self.filter
-		self.old_hidden_filter = self.settings.hidden_filter
-		self.old_reverse = self.settings.reverse
+		for opt in ('sort_directories_first', 'sort', 'sort_reverse',
+				'sort_case_insensitive'):
+			self.settings.signal_bind('setopt.' + opt,
+					self.request_resort, weak=True)
+
+		for opt in ('filter', 'hidden_filter', 'show_hidden'):
+			self.settings.signal_bind('setopt.' + opt,
+				self.request_reload, weak=True)
+
+	def request_resort(self):
+		self.order_outdated = True
+
+	def request_reload(self):
+		self.content_outdated = True
 
 	def get_list(self):
 		return self.files
@@ -203,7 +209,6 @@ class Directory(FileSystemObject, Accumulator, SettingsAware):
 					else:
 						self.mark_item(item, False)
 
-				self.old_directories_first = None
 				self.sort()
 
 				if len(self.files) > 0:
@@ -236,8 +241,12 @@ class Directory(FileSystemObject, Accumulator, SettingsAware):
 		if not self.loading:
 			self.load_once()
 
+			if not self.accessible:
+				self.content_loaded = True
+				return
+
 			if schedule is None:
-				schedule = self.size > 30
+				schedule = True   # was: self.size > 30
 
 			if self.load_generator is None:
 				self.load_generator = self.load_bit_by_bit()
@@ -265,12 +274,17 @@ class Directory(FileSystemObject, Accumulator, SettingsAware):
 			sort_func = self.sort_dict[self.settings.sort]
 		except:
 			sort_func = sort_by_basename
+
+		if self.settings.sort_case_insensitive and \
+				sort_func == sort_by_basename:
+			sort_func = sort_by_basename_icase
+
 		self.files.sort(key = sort_func)
 
-		if self.settings.reverse:
+		if self.settings.sort_reverse:
 			self.files.reverse()
 
-		if self.settings.directories_first:
+		if self.settings.sort_directories_first:
 			self.files.sort(key = sort_by_directory)
 
 		if self.pointer is not None:
@@ -278,15 +292,10 @@ class Directory(FileSystemObject, Accumulator, SettingsAware):
 		else:
 			self.correct_pointer()
 
-		self.old_directories_first = self.settings.directories_first
-		self.old_sort = self.settings.sort
-		self.old_reverse = self.settings.reverse
-
 	def sort_if_outdated(self):
 		"""Sort the containing files if they are outdated"""
-		if self.old_directories_first != self.settings.directories_first \
-				or self.old_sort != self.settings.sort \
-				or self.old_reverse != self.settings.reverse:
+		if self.order_outdated:
+			self.order_outdated = False
 			self.sort()
 			return True
 		return False
@@ -361,12 +370,8 @@ class Directory(FileSystemObject, Accumulator, SettingsAware):
 
 		if self.load_content_once(*a, **k): return True
 
-		if self.old_show_hidden != self.settings.show_hidden or \
-				self.old_filter != self.filter or \
-				self.old_hidden_filter != self.settings.hidden_filter:
-			self.old_filter = self.filter
-			self.old_hidden_filter = self.settings.hidden_filter
-			self.old_show_hidden = self.settings.show_hidden
+		if self.content_outdated:
+			self.content_outdated = False
 			self.load_content(*a, **k)
 			return True
 
@@ -374,6 +379,7 @@ class Directory(FileSystemObject, Accumulator, SettingsAware):
 			real_mtime = os.stat(self.path).st_mtime
 		except OSError:
 			real_mtime = None
+			return False
 		if self.stat:
 			cached_mtime = self.load_content_mtime
 		else:
diff --git a/ranger/fsobject/file.py b/ranger/fsobject/file.py
index 86621095..aa44016e 100644
--- a/ranger/fsobject/file.py
+++ b/ranger/fsobject/file.py
@@ -13,6 +13,28 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+control_characters = set(chr(n) for n in set(range(0, 9)) | set(range(14,32)))
+N_FIRST_BYTES = 20
+
 from .fsobject import FileSystemObject as SuperClass
 class File(SuperClass):
 	is_file = True
+
+	@property
+	def firstbytes(self):
+		try:
+			return self._firstbytes
+		except:
+			try:
+				f = open(self.path, 'r')
+				self._firstbytes = f.read(N_FIRST_BYTES)
+				f.close()
+				return self._firstbytes
+			except:
+				pass
+
+	def is_binary(self):
+		if self.firstbytes and control_characters & set(self.firstbytes):
+			return True
+		return False
+
diff --git a/ranger/fsobject/fsobject.py b/ranger/fsobject/fsobject.py
index 4278c3e8..1ab3addd 100644
--- a/ranger/fsobject/fsobject.py
+++ b/ranger/fsobject/fsobject.py
@@ -17,6 +17,7 @@ CONTAINER_EXTENSIONS = 'rar zip tar gz bz bz2 tgz 7z iso cab'.split()
 DOCUMENT_EXTENSIONS = 'pdf doc ppt odt'.split()
 DOCUMENT_BASENAMES = 'README TODO LICENSE COPYING INSTALL'.split()
 
+import time
 from . import T_FILE, T_DIRECTORY, T_UNKNOWN, T_NONEXISTANT, BAD_INFO
 from ranger.shared import MimeTypeAware, FileManagerAware
 from ranger.ext.shell_escape import shell_escape
@@ -81,6 +82,9 @@ class FileSystemObject(MimeTypeAware, FileManagerAware):
 		self.set_mimetype()
 		self.use()
 
+	def __repr__(self):
+		return "<{0} {1}>".format(self.__class__.__name__, self.path)
+
 	@property
 	def shell_escaped_basename(self):
 		if self._shell_escaped_basename is None:
@@ -109,12 +113,12 @@ class FileSystemObject(MimeTypeAware, FileManagerAware):
 
 	def use(self):
 		"""mark the filesystem-object as used at the current time"""
-		import time
 		self.last_used = time.time()
 
 	def is_older_than(self, seconds):
 		"""returns whether this object wasn't use()d in the last n seconds"""
-		import time
+		if seconds < 0:
+			return True
 		return self.last_used + seconds < time.time()
 
 	def set_mimetype(self):
diff --git a/ranger/fsobject/loader.py b/ranger/fsobject/loader.py
index b47dd9c9..4f4424e4 100644
--- a/ranger/fsobject/loader.py
+++ b/ranger/fsobject/loader.py
@@ -77,7 +77,7 @@ class Loader(FileManagerAware):
 
 	def remove(self, item=None, index=None):
 		if item is not None and index is None:
-			for test, i in zip(self.queue, range(len(self.queue))):
+			for i, test in enumerate(self.queue):
 				if test == item:
 					index = i 
 					break
diff --git a/ranger/gui/colorscheme.py b/ranger/gui/colorscheme.py
index 199a5523..dffacffb 100644
--- a/ranger/gui/colorscheme.py
+++ b/ranger/gui/colorscheme.py
@@ -41,11 +41,20 @@ If your colorscheme-file contains more than one colorscheme, specify it with:
 colorscheme = colorschemes.filename.classname
 """
 
+import os
 from curses import color_pair
+from inspect import isclass, ismodule
+
+import ranger
 from ranger.gui.color import get_color
 from ranger.gui.context import Context
+from ranger.shared.settings import SettingsAware
+
+# 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(object):
+class ColorScheme(SettingsAware):
 	"""
 	This is the class that colorschemes must inherit from.
 
@@ -73,6 +82,14 @@ class ColorScheme(object):
 
 			# 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
 			self.cache[keys] = color
 			return color
 
@@ -102,3 +119,55 @@ class ColorScheme(object):
 			attr |= 2097152
 			fg = 4
 		return fg, -1, attr
+
+def _colorscheme_name_to_class(signal):
+	# Find the colorscheme.  First look for it at ~/.ranger/colorschemes,
+	# then at RANGERDIR/colorschemes.  If the file contains a class
+	# named Scheme, it is used.  Otherwise, an arbitrary other class
+	# is picked.
+	if isinstance(signal.value, ColorScheme): return
+
+	scheme_name = signal.value
+	usecustom = not ranger.arg.clean
+
+	def exists(colorscheme):
+		return os.path.exists(colorscheme + '.py')
+
+	def is_scheme(x):
+		return isclass(x) and issubclass(x, ColorScheme)
+
+	# create ~/.ranger/colorschemes/__init__.py if it doesn't exist
+	if usecustom:
+		if os.path.exists(ranger.relpath_conf('colorschemes')):
+			initpy = ranger.relpath_conf('colorschemes', '__init__.py')
+			if not os.path.exists(initpy):
+				open(initpy, 'a').close()
+
+	if usecustom and \
+			exists(ranger.relpath_conf('colorschemes', scheme_name)):
+		scheme_supermodule = 'colorschemes'
+	elif exists(ranger.relpath('colorschemes', scheme_name)):
+		scheme_supermodule = 'ranger.colorschemes'
+	else:
+		scheme_supermodule = None  # found no matching file.
+
+	if scheme_supermodule is None:
+		# XXX: dont print while curses is running
+		print("ERROR: colorscheme not found, fall back to builtin scheme")
+		if ranger.arg.debug:
+			raise Exception("Cannot locate colorscheme!")
+		signal.value = ColorScheme()
+	else:
+		scheme_module = getattr(__import__(scheme_supermodule,
+				globals(), locals(), [scheme_name], 0), scheme_name)
+		assert ismodule(scheme_module)
+		if hasattr(scheme_module, 'Scheme') \
+				and is_scheme(scheme_module.Scheme):
+			signal.value = scheme_module.Scheme()
+		else:
+			for name, var in scheme_module.__dict__.items():
+				if var != ColorScheme and is_scheme(var):
+					signal.value = var()
+					break
+			else:
+				raise Exception("The module contains no valid colorscheme!")
diff --git a/ranger/gui/context.py b/ranger/gui/context.py
index d31124ca..4ea50714 100644
--- a/ranger/gui/context.py
+++ b/ranger/gui/context.py
@@ -17,7 +17,7 @@ CONTEXT_KEYS = ['reset', 'error',
 		'in_browser', 'in_statusbar', 'in_titlebar', 'in_console',
 		'in_pager', 'in_taskview',
 		'directory', 'file', 'hostname',
-		'executable', 'media', 'link',
+		'executable', 'media', 'link', 'fifo', 'socket',
 		'video', 'audio', 'image', 'media', 'document', 'container',
 		'selected', 'empty', 'main_column', 'message', 'background',
 		'good', 'bad',
@@ -26,7 +26,7 @@ CONTEXT_KEYS = ['reset', 'error',
 		'marked', 'tagged', 'tag_marker',
 		'help_markup',
 		'seperator', 'key', 'special', 'border',
-		'title', 'text', 'highlight', 'bars', 'quotes',
+		'title', 'text', 'highlight', 'bars', 'quotes', 'tab',
 		'keybuffer']
 
 class Context(object):
diff --git a/ranger/gui/defaultui.py b/ranger/gui/defaultui.py
index e6a365de..08e0b204 100644
--- a/ranger/gui/defaultui.py
+++ b/ranger/gui/defaultui.py
@@ -15,8 +15,6 @@
 
 from ranger.gui.ui import UI
 
-RATIO = ( 3, 3, 12, 9 )
-
 class DefaultUI(UI):
 	def setup(self):
 		"""Build up the UI by initializing widgets."""
@@ -32,9 +30,10 @@ class DefaultUI(UI):
 		self.add_child(self.titlebar)
 
 		# Create the browser view
-		self.browser = BrowserView(self.win, RATIO)
+		self.browser = BrowserView(self.win, self.settings.column_ratios)
+		self.settings.signal_bind('setopt.column_ratios',
+				self.browser.change_ratios)
 		self.add_child(self.browser)
-		self.main_column = self.browser.main_column
 
 		# Create the process manager
 		self.taskview = TaskView(self.win)
diff --git a/ranger/gui/displayable.py b/ranger/gui/displayable.py
index ceefb3f1..a7a0945d 100644
--- a/ranger/gui/displayable.py
+++ b/ranger/gui/displayable.py
@@ -72,6 +72,7 @@ class Displayable(EnvironmentAware, FileManagerAware, CursesShortcuts):
 		self.hei = 0
 		self.paryx = (0, 0)
 		self.parent = None
+		self.fresh = True
 
 		self._old_visible = self.visible
 
@@ -154,7 +155,7 @@ class Displayable(EnvironmentAware, FileManagerAware, CursesShortcuts):
 
 	def resize(self, y, x, hei=None, wid=None):
 		"""Resize the widget"""
-		do_move = False
+		do_move = self.fresh
 		try:
 			maxy, maxx = self.env.termsize
 		except TypeError:
@@ -212,6 +213,7 @@ class Displayable(EnvironmentAware, FileManagerAware, CursesShortcuts):
 			except:
 				pass
 
+			self.fresh = False
 			self.paryx = self.win.getparyx()
 			self.y, self.x = self.paryx
 			if self.parent:
@@ -291,7 +293,7 @@ class DisplayableContainer(Displayable):
 			return True
 
 		for displayable in self.container:
-			if event in displayable:
+			if displayable.visible and event in displayable:
 				if displayable.click(event):
 					return True
 
@@ -314,7 +316,7 @@ class DisplayableContainer(Displayable):
 	def remove_child(self, obj):
 		"""Remove the object from the container."""
 		try:
-			container.remove(obj)
+			self.container.remove(obj)
 		except ValueError:
 			pass
 		else:
diff --git a/ranger/gui/mouse_event.py b/ranger/gui/mouse_event.py
index d588fd8e..f3955825 100644
--- a/ranger/gui/mouse_event.py
+++ b/ranger/gui/mouse_event.py
@@ -41,6 +41,15 @@ class MouseEvent(object):
 		except:
 			return False
 
+	def mouse_wheel_direction(self):
+		if self.bstate & curses.BUTTON4_PRESSED:
+			return -1
+		elif self.bstate & curses.BUTTON2_PRESSED \
+				or self.bstate > curses.ALL_MOUSE_EVENTS:
+			return 1
+		else:
+			return 0
+
 	def ctrl(self):
 		return self.bstate & curses.BUTTON_CTRL
 
diff --git a/ranger/gui/ui.py b/ranger/gui/ui.py
index 2d86736c..c7c2090a 100644
--- a/ranger/gui/ui.py
+++ b/ranger/gui/ui.py
@@ -84,8 +84,6 @@ class UI(DisplayableContainer):
 
 	def suspend(self):
 		"""Turn off curses"""
-		# from ranger import log
-		# log("suspending ui!")
 		self.win.keypad(0)
 		curses.nocbreak()
 		curses.echo()
@@ -111,8 +109,8 @@ class UI(DisplayableContainer):
 
 	def destroy(self):
 		"""Destroy all widgets and turn off curses"""
-		DisplayableContainer.destroy(self)
 		self.suspend()
+		DisplayableContainer.destroy(self)
 
 	def handle_mouse(self):
 		"""Handles mouse input"""
@@ -121,10 +119,6 @@ class UI(DisplayableContainer):
 		except _curses.error:
 			return
 
-		# from ranger import log
-		# log('{0:0>28b} ({0})'.format(event.bstate))
-		# log('y: {0}  x: {1}'.format(event.y, event.x))
-
 		DisplayableContainer.click(self, event)
 
 	def handle_key(self, key):
@@ -153,7 +147,7 @@ class UI(DisplayableContainer):
 
 		if cmd.function:
 			try:
-				cmd.function(CommandArgs.from_widget(self))
+				cmd.function(CommandArgs.from_widget(self.fm))
 			except Exception as error:
 				self.fm.notify(error)
 			if kbuf.done:
@@ -197,7 +191,7 @@ class UI(DisplayableContainer):
 		self.env.termsize = self.win.getmaxyx()
 
 	def draw(self):
-		"""Erase the window, then draw all objects in the container"""
+		"""Draw all objects in the container"""
 		self.win.touchwin()
 		DisplayableContainer.draw(self)
 		if self._draw_title and self.settings.update_title:
diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py
index 238a4803..0d46ee06 100644
--- a/ranger/gui/widgets/browsercolumn.py
+++ b/ranger/gui/widgets/browsercolumn.py
@@ -15,6 +15,7 @@
 
 """The BrowserColumn widget displays the contents of a directory or file."""
 import re
+import stat
 from time import time
 
 from . import Widget
@@ -41,6 +42,15 @@ PREVIEW_BLACKLIST = re.compile(r"""
 		$
 """, re.VERBOSE | re.IGNORECASE)
 
+PREVIEW_WHITELIST = re.compile(r"""
+		\.(
+			txt | py | c
+		)
+		# ignore filetype-independent suffixes:
+			(\.part|\.bak|~)?
+		$
+""", re.VERBOSE | re.IGNORECASE)
+
 class BrowserColumn(Pager):
 	main_column = False
 	display_infostring = False
@@ -65,6 +75,12 @@ class BrowserColumn(Pager):
 		Widget.__init__(self, win)
 		self.level = level
 
+		self.settings.signal_bind('setopt.display_size_in_main_column',
+				self.request_redraw, weak=True)
+
+	def request_redraw(self):
+		self.need_redraw = True
+
 	def resize(self, y, x, hei, wid):
 		Widget.resize(self, y, x, hei, wid)
 
@@ -86,7 +102,7 @@ class BrowserColumn(Pager):
 					self.fm.enter_dir(self.target.path)
 
 				if index < len(self.target):
-					self.fm.move_pointer(absolute = index)
+					self.fm.move(to=index)
 			elif event.pressed(3):
 				try:
 					clicked_file = self.target.files[index]
@@ -96,7 +112,7 @@ class BrowserColumn(Pager):
 
 		else:
 			if self.level > 0:
-				self.fm.move_right()
+				self.fm.move(right=0)
 
 		return True
 
@@ -124,6 +140,9 @@ class BrowserColumn(Pager):
 			self.need_redraw = True
 			self.old_dir = self.target
 
+		if self.target:  # don't garbage collect this directory please
+			self.target.use()
+
 		if self.target and self.target.is_directory \
 				and (self.level <= 0 or self.settings.preview_directories):
 			if self.target.pointed_obj != self.old_cf:
@@ -149,10 +168,24 @@ class BrowserColumn(Pager):
 			self.last_redraw_time = time()
 
 	def _preview_this_file(self, target):
+		if not (target \
+				and self.settings.preview_files \
+				and target.is_file \
+				and target.accessible \
+				and target.stat \
+				and not target.stat.st_mode & stat.S_IFIFO):
+			return False
+
 		maxsize = self.settings.max_filesize_for_preview
-		return self.settings.preview_files \
-				and not PREVIEW_BLACKLIST.search(target.basename) \
-				and (maxsize is None or maxsize >= target.size)
+		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):
+			return False
+		if target.is_binary():
+			return False
+		return True
 
 	def _draw_file(self):
 		"""Draw a preview of the file, if the settings allow it"""
@@ -183,8 +216,6 @@ class BrowserColumn(Pager):
 
 		base_color = ['in_browser']
 
-		self.target.use()
-
 		self.win.move(0, 0)
 
 		if not self.target.content_loaded:
@@ -215,18 +246,18 @@ class BrowserColumn(Pager):
 			i = line + self.scroll_begin
 
 			try:
-				drawed = self.target.files[i]
+				drawn = self.target.files[i]
 			except IndexError:
 				break
 
-			this_color = base_color + list(drawed.mimetype_tuple)
-			text = drawed.basename
-			tagged = self.fm.tags and drawed.realpath in self.fm.tags
+			this_color = base_color + list(drawn.mimetype_tuple)
+			text = drawn.basename
+			tagged = self.fm.tags and drawn.realpath in self.fm.tags
 
 			if i == selected_i:
 				this_color.append('selected')
 
-			if drawed.marked:
+			if drawn.marked:
 				this_color.append('marked')
 				if self.main_column:
 					text = " " + text
@@ -236,19 +267,25 @@ class BrowserColumn(Pager):
 				if self.main_column:
 					text = self.tagged_marker + text
 
-			if drawed.is_directory:
+			if drawn.is_directory:
 				this_color.append('directory')
 			else:
 				this_color.append('file')
 
-			if drawed.stat is not None and drawed.stat.st_mode & stat.S_IXUSR:
-				this_color.append('executable')
+			if drawn.stat:
+				mode = drawn.stat.st_mode
+				if mode & stat.S_IXUSR:
+					this_color.append('executable')
+				if stat.S_ISFIFO(mode):
+					this_color.append('fifo')
+				if stat.S_ISSOCK(mode):
+					this_color.append('socket')
 
-			if drawed.islink:
+			if drawn.islink:
 				this_color.append('link')
-				this_color.append(drawed.exists and 'good' or 'bad')
+				this_color.append(drawn.exists and 'good' or 'bad')
 
-			string = drawed.basename
+			string = drawn.basename
 			try:
 				if self.main_column:
 					if tagged:
@@ -258,8 +295,9 @@ class BrowserColumn(Pager):
 				else:
 					self.win.addnstr(line, 0, text, self.wid)
 
-				if self.display_infostring and drawed.infostring:
-					info = drawed.infostring
+				if self.display_infostring and drawn.infostring \
+						and self.settings.display_size_in_main_column:
+					info = drawn.infostring
 					x = self.wid - 1 - len(info)
 					if x > self.x:
 						self.win.addstr(line, x, str(info) + ' ')
@@ -320,19 +358,11 @@ class BrowserColumn(Pager):
 		self.scroll_begin = self._get_scroll_begin()
 		self.target.scroll_begin = self.scroll_begin
 
-	# TODO: does not work if options.scroll_offset is high,
-	# relative > 1 and you scroll from scroll_begin = 1 to 0
 	def scroll(self, relative):
 		"""scroll by n lines"""
 		self.need_redraw = True
-		self._set_scroll_begin()
-		old_value = self.target.scroll_begin
-		self.target.scroll_begin += relative
-		self._set_scroll_begin()
-
-		if self.target.scroll_begin == old_value:
-			self.target.move(relative = relative)
-			self.target.scroll_begin += relative
+		self.target.move(relative=relative)
+		self.target.scroll_begin += 3 * relative
 
 	def __str__(self):
 		return self.__class__.__name__ + ' at level ' + str(self.level)
diff --git a/ranger/gui/widgets/browserview.py b/ranger/gui/widgets/browserview.py
index 8d6dc611..1995b714 100644
--- a/ranger/gui/widgets/browserview.py
+++ b/ranger/gui/widgets/browserview.py
@@ -15,6 +15,7 @@
 
 """The BrowserView manages a set of BrowserColumns."""
 import curses
+from ranger.ext.signal_dispatcher import Signal
 from . import Widget
 from .browsercolumn import BrowserColumn
 from .pager import Pager
@@ -30,13 +31,31 @@ class BrowserView(Widget, DisplayableContainer):
 
 	def __init__(self, win, ratios, preview = True):
 		DisplayableContainer.__init__(self, win)
-		self.ratios = ratios
 		self.preview = preview
-		self.old_cf = self.env.cf
-		self.old_prevfile = None
-		self.old_prevdir = None
+		self.columns = []
+
+		self.pager = Pager(self.win, embedded=True)
+		self.pager.visible = False
+		self.add_child(self.pager)
+
+		self.change_ratios(ratios, resize=False)
+
+		for option in ('preview_directories', 'preview_files'):
+			self.settings.signal_bind('setopt.' + option,
+					self._request_clear_if_has_borders, weak=True)
+
+		self.fm.env.signal_bind('move', self.request_clear)
+		self.settings.signal_bind('setopt.column_ratios', self.request_clear)
+
+	def change_ratios(self, ratios, resize=True):
+		if isinstance(ratios, Signal):
+			ratios = ratios.value
+
+		for column in self.columns:
+			column.destroy()
+			self.remove_child(column)
+		self.columns = []
 
-		# normalize ratios:
 		ratio_sum = float(sum(ratios))
 		self.ratios = tuple(x / ratio_sum for x in ratios)
 
@@ -46,42 +65,38 @@ class BrowserView(Widget, DisplayableContainer):
 					(self.ratios[-1] * 0.1))
 
 		offset = 1 - len(ratios)
-		if preview: offset += 1
+		if self.preview: offset += 1
 
 		for level in range(len(ratios)):
 			fl = BrowserColumn(self.win, level + offset)
 			self.add_child(fl)
+			self.columns.append(fl)
 
 		try:
-			self.main_column = self.container[preview and -2 or -1]
+			self.main_column = self.columns[self.preview and -2 or -1]
 		except IndexError:
 			self.main_column = None
 		else:
 			self.main_column.display_infostring = True
 			self.main_column.main_column = True
 
-		self.pager = Pager(self.win, embedded=True)
-		self.pager.visible = False
-		self.add_child(self.pager)
+		self.resize(self.y, self.x, self.hei, self.wid)
+
+	def _request_clear_if_has_borders(self):
+		if self.settings.draw_borders:
+			self.request_clear()
+
+	def request_clear(self):
+		self.need_clear = True
 
 	def draw(self):
 		if self.draw_bookmarks:
 			self._draw_bookmarks()
 		else:
-			if self.old_cf != self.env.cf:
-				self.need_clear = True
-			if self.settings.draw_borders:
-				if self.old_prevdir != self.settings.preview_directories:
-					self.need_clear = True
-				if self.old_prevfile != self.settings.preview_files:
-					self.need_clear = True
 			if self.need_clear:
 				self.win.erase()
 				self.need_redraw = True
 				self.need_clear = False
-				self.old_cf = self.env.cf
-				self.old_prevfile = self.settings.preview_files
-				self.old_prevdir = self.settings.preview_directories
 			DisplayableContainer.draw(self)
 			if self.settings.draw_borders:
 				self._draw_borders()
@@ -102,13 +117,14 @@ class BrowserView(Widget, DisplayableContainer):
 				pass
 
 	def _draw_bookmarks(self):
+		self.color_reset()
 		self.need_clear = True
 
 		sorted_bookmarks = sorted(item for item in self.fm.bookmarks \
 				if '/.' not in item[1].path)
 
 		def generator():
-			return zip(range(self.hei), sorted_bookmarks)
+			return zip(range(self.hei-1), sorted_bookmarks)
 
 		try:
 			maxlen = max(len(item[1].path) for i, item in generator())
@@ -116,10 +132,19 @@ class BrowserView(Widget, DisplayableContainer):
 			return
 		maxlen = min(maxlen + 5, self.wid)
 
+		whitespace = " " * maxlen
 		for line, items in generator():
 			key, mark = items
 			string = " " + key + ": " + mark.path
-			self.addnstr(line, 0, string.ljust(maxlen), self.wid)
+			self.addstr(line, 0, whitespace)
+			self.addnstr(line, 0, string, self.wid)
+
+		if self.settings.draw_bookmark_borders:
+			self.win.hline(line+1, 0, curses.ACS_HLINE, maxlen)
+
+			if maxlen < self.wid:
+				self.win.vline(0, maxlen, curses.ACS_VLINE, line+1)
+				self.win.addch(line+1, maxlen, curses.ACS_LRCORNER)
 
 	def _draw_borders(self):
 		win = self.win
@@ -128,17 +153,13 @@ class BrowserView(Widget, DisplayableContainer):
 		left_start = 0
 		right_end = self.wid - 1
 
-		rows = [row for row in self.container \
-				if isinstance(row, BrowserColumn)]
-		rows.sort(key=lambda row: row.x)
-
-		for child in rows:
+		for child in self.columns:
 			if not child.has_preview():
 				left_start = child.x + child.wid
 			else:
 				break
 		if not self.pager.visible:
-			for child in reversed(rows):
+			for child in reversed(self.columns):
 				if not child.has_preview():
 					right_end = child.x - 1
 				else:
@@ -151,7 +172,7 @@ class BrowserView(Widget, DisplayableContainer):
 				right_end - left_start)
 		win.vline(1, left_start, curses.ACS_VLINE, self.hei - 2)
 
-		for child in rows:
+		for child in self.columns:
 			if not child.has_preview():
 				continue
 			if child.main_column and self.pager.visible:
@@ -203,7 +224,7 @@ class BrowserView(Widget, DisplayableContainer):
 						max(1, self.wid - left - pad))
 
 			try:
-				self.container[i].resize(pad, left, hei - pad * 2, \
+				self.columns[i].resize(pad, left, hei - pad * 2, \
 						max(1, wid - 1))
 			except KeyError:
 				pass
@@ -211,11 +232,10 @@ class BrowserView(Widget, DisplayableContainer):
 			left += wid
 
 	def click(self, event):
-		n = event.ctrl() and 1 or 3
-		if event.pressed(4):
-			self.main_column.scroll(relative = -n)
-		elif event.pressed(2) or event.key_invalid():
-			self.main_column.scroll(relative = n)
+		n = event.ctrl() and 5 or 1
+		direction = event.mouse_wheel_direction()
+		if direction:
+			self.main_column.scroll(direction)
 		else:
 			DisplayableContainer.click(self, event)
 
@@ -225,8 +245,8 @@ class BrowserView(Widget, DisplayableContainer):
 		self.need_clear = True
 		self.pager.open()
 		try:
-			self.container[-2].visible = False
-			self.container[-3].visible = False
+			self.columns[-1].visible = False
+			self.columns[-2].visible = False
 		except IndexError:
 			pass
 
@@ -236,15 +256,15 @@ class BrowserView(Widget, DisplayableContainer):
 		self.need_clear = True
 		self.pager.close()
 		try:
-			self.container[-2].visible = True
-			self.container[-3].visible = True
+			self.columns[-1].visible = True
+			self.columns[-2].visible = True
 		except IndexError:
 			pass
 
 	def poke(self):
 		DisplayableContainer.poke(self)
 		if self.settings.collapse_preview and self.preview:
-			has_preview = self.container[-2].has_preview()
+			has_preview = self.columns[-2].has_preview()
 			if self.preview_available != has_preview:
 				self.preview_available = has_preview
 				self.resize(self.y, self.x, self.hei, self.wid)
diff --git a/ranger/gui/widgets/console.py b/ranger/gui/widgets/console.py
index 4dea98c7..aaa85d8e 100644
--- a/ranger/gui/widgets/console.py
+++ b/ranger/gui/widgets/console.py
@@ -25,8 +25,10 @@ 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
+from ranger import log, relpath_conf
 from ranger.ext.shell_escape import shell_quote
+from ranger.ext.direction import Direction
+import ranger
 
 DEFAULT_HISTORY = 0
 SEARCH_HISTORY = 1
@@ -52,17 +54,38 @@ class Console(Widget):
 	histories = None
 	override = None
 	allow_close = False
+	historypaths = []
 
 	def __init__(self, win):
 		from ranger.container import History
 		Widget.__init__(self, win)
 		self.keymap = self.settings.keys.console_keys
 		self.clear()
-		self.histories = [None] * 4
-		self.histories[DEFAULT_HISTORY] = History()
-		self.histories[SEARCH_HISTORY] = History()
-		self.histories[QUICKOPEN_HISTORY] = History()
-		self.histories[OPEN_HISTORY] = History()
+		self.histories = []
+		# load histories from files
+		if not ranger.arg.clean:
+			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)
+				self.histories.append(hist)
+				if ranger.arg.clean: continue
+				try: f = open(path, 'r')
+				except: continue
+				for line in f:
+					hist.add(line[:-1])
+				f.close()
+
+	def destroy(self):
+		# save histories from files
+		if ranger.arg.clean or not self.settings.save_console_history:
+			return
+		for i, path in enumerate(self.historypaths):
+			try: f = open(path, 'w')
+			except: continue
+			for entry in self.histories[i]:
+				f.write(entry + '\n')
+			f.close()
 
 	def init(self):
 		"""override this. Called directly after class change"""
@@ -73,12 +96,16 @@ class Console(Widget):
 
 		self.win.erase()
 		self.addstr(0, 0, self.prompt)
-		self.addstr(self.line)
+		overflow = -self.wid + len(self.prompt) + len(self.line) + 1
+		if overflow > 0: 
+			self.addstr(self.line[overflow:])
+		else:
+			self.addstr(self.line)
 
 	def finalize(self):
 		try:
 			self.fm.ui.win.move(self.y,
-					self.x + self.pos + len(self.prompt))
+					self.x + min(self.wid-1, self.pos + len(self.prompt)))
 		except:
 			pass
 
@@ -135,9 +162,15 @@ class Console(Widget):
 		except KeyError:
 			# An unclean hack to allow unicode input.
 			# This whole part should be replaced.
-			self.type_key(chr(keytuple[0]))
-			self.env.key_clear()
-			return
+			try:
+				chrkey = chr(keytuple[0])
+			except:
+				pass
+			else:
+				self.type_key(chrkey)
+			finally:
+				self.env.key_clear()
+				return
 
 		if cmd == self.commandlist.dummy_object:
 			return
@@ -181,14 +214,16 @@ class Console(Widget):
 		self.history.fast_forward()
 		self.history.modify(self.line)
 
-	def move(self, relative = 0, absolute = None):
-		if absolute is not None:
-			if absolute < 0:
-				self.pos = len(self.line) + 1 + absolute
-			else:
-				self.pos = absolute
-
-		self.pos = min(max(0, self.pos + relative), len(self.line))
+	def move(self, **keywords):
+		from ranger import log
+		log(keywords)
+		direction = Direction(keywords)
+		if direction.horizontal():
+			self.pos = direction.move(
+					direction=direction.right(),
+					minimum=0,
+					maximum=len(self.line) + 1,
+					current=self.pos)
 
 	def delete_rest(self, direction):
 		self.tab_deque = None
@@ -227,7 +262,7 @@ class Console(Widget):
 		pos = self.pos + mod
 
 		self.line = self.line[0:pos] + self.line[pos+1:]
-		self.move(relative = mod)
+		self.move(right=mod)
 		self.on_line_change()
 
 	def execute(self):
@@ -388,6 +423,8 @@ class OpenConsole(ConsoleWithTab):
 
 	def execute(self):
 		command, flags = self._parse()
+		if not command and 'p' in flags:
+			command = 'cat %f'
 		if command:
 			if _CustomTemplate.delimiter in command:
 				command = self._substitute_metachars(command)
diff --git a/ranger/gui/widgets/pager.py b/ranger/gui/widgets/pager.py
index c5ed8af1..e915f790 100644
--- a/ranger/gui/widgets/pager.py
+++ b/ranger/gui/widgets/pager.py
@@ -18,8 +18,7 @@ The pager displays text and allows you to scroll inside it.
 """
 import re
 from . import Widget
-from ranger.ext.move import move_between
-from ranger import log
+from ranger.ext.direction import Direction
 
 BAR_REGEXP = re.compile(r'\|\d+\?\|')
 QUOTES_REGEXP = re.compile(r'"[^"]+?"')
@@ -46,6 +45,10 @@ class Pager(Widget):
 		else:
 			self.keymap = self.settings.keys.pager_keys
 
+	def move_horizontal(self, *a, **k):
+		"""For compatibility"""
+		self.fm.notify("Your keys.py is out of date. Can't scroll!", bad=True)
+
 	def open(self):
 		self.scroll_begin = 0
 		self.markup = None
@@ -112,50 +115,26 @@ class Pager(Widget):
 			if TITLE_REGEXP.match(line):
 				self.color_at(i, 0, -1, 'title', *baseclr)
 
-
-	def move(self, relative=0, absolute=None, pages=None, narg=None):
-		i = self.scroll_begin
-		if isinstance(absolute, int):
-			if isinstance(narg, int):
-				absolute = narg
-			if absolute < 0:
-				i = absolute + len(self.lines)
-			else:
-				i = absolute
-
-		if relative != 0:
-			if isinstance(pages, int):
-				relative *= pages * self.hei
-			if isinstance(narg, int):
-				relative *= narg
-		i = int(i + relative)
-
-		length = len(self.lines) - self.hei
-		if i >= length:
-			self._get_line(i+self.hei)
-
-		length = len(self.lines) - self.hei
-		if i >= length:
-			i = length
-
-		if i < 0:
-			i = 0
-
-		self.scroll_begin = i
-
-	def move_horizontal(self, relative=0, absolute=None, narg=None):
-		if narg is not None:
-			if absolute is None:
-				relative = relative < 0 and -narg or narg
-			else:
-				absolute = narg
-
-		self.startx = move_between(
-				current=self.startx,
-				minimum=0,
-				maximum=999,
-				relative=relative,
-				absolute=absolute)
+	def move(self, narg=None, **kw):
+		direction = Direction(kw)
+		if direction.horizontal():
+			self.startx = direction.move(
+					direction=direction.right(),
+					override=narg,
+					maximum=self._get_max_width(),
+					current=self.startx,
+					pagesize=self.wid,
+					offset=-self.wid)
+		if direction.vertical():
+			if self.source_is_stream:
+				self._get_line(self.scroll_begin + self.hei * 2)
+			self.scroll_begin = direction.move(
+					direction=direction.down(),
+					override=narg,
+					maximum=len(self.lines),
+					current=self.scroll_begin,
+					pagesize=self.hei,
+					offset=-self.hei)
 
 	def press(self, key):
 		try:
@@ -201,13 +180,13 @@ class Pager(Widget):
 
 	def click(self, event):
 		n = event.ctrl() and 1 or 3
-		if event.pressed(4):
-			self.move(relative = -n)
-		elif event.pressed(2) or event.key_invalid():
-			self.move(relative = n)
+		direction = event.mouse_wheel_direction()
+		if direction:
+			self.move(relative=direction)
 		return True
 
 	def _get_line(self, n, attempt_to_read=True):
+		assert isinstance(n, int), n
 		try:
 			return self.lines[n]
 		except (KeyError, IndexError):
@@ -234,3 +213,6 @@ class Pager(Widget):
 			except IndexError:
 				raise StopIteration
 			i += 1
+
+	def _get_max_width(self):
+		return max(len(line) for line in self.lines)
diff --git a/ranger/gui/widgets/statusbar.py b/ranger/gui/widgets/statusbar.py
index 6f52f8ef..75fbbe89 100644
--- a/ranger/gui/widgets/statusbar.py
+++ b/ranger/gui/widgets/statusbar.py
@@ -47,6 +47,11 @@ class StatusBar(Widget):
 	def __init__(self, win, column=None):
 		Widget.__init__(self, win)
 		self.column = column
+		self.settings.signal_bind('setopt.display_size_in_status_bar',
+				self.request_redraw, weak=True)
+	
+	def request_redraw(self):
+		self.need_redraw = True
 
 	def notify(self, text, duration=4, bad=False):
 		self.msg = Message(text, duration, bad)
@@ -157,12 +162,16 @@ class StatusBar(Widget):
 		left.add(self._get_owner(target), 'owner')
 		left.add_space()
 		left.add(self._get_group(target), 'group')
-		left.add_space()
 
 		if target.islink:
 			how = target.exists and 'good' or 'bad'
-			left.add('-> ' + target.readlink, 'link', how)
+			left.add(' -> ' + target.readlink, 'link', how)
 		else:
+			if self.settings.display_size_in_status_bar and target.infostring:
+				left.add(target.infostring)
+
+			left.add_space()
+
 			left.add(strftime(self.timeformat,
 					localtime(target.stat.st_mtime)), 'mtime')
 
diff --git a/ranger/gui/widgets/titlebar.py b/ranger/gui/widgets/titlebar.py
index e1be8e97..62740e2d 100644
--- a/ranger/gui/widgets/titlebar.py
+++ b/ranger/gui/widgets/titlebar.py
@@ -30,18 +30,65 @@ class TitleBar(Widget):
 	old_wid = None
 	result = None
 	throbber = ' '
+	need_redraw = False
+	tab_width = 0
+
+	def __init__(self, *args, **keywords):
+		Widget.__init__(self, *args, **keywords)
+		self.fm.signal_bind('tab.change', self.request_redraw, weak=True)
+
+	def request_redraw(self):
+		self.need_redraw = True
 
 	def draw(self):
-		if self.env.cf != self.old_cf or\
+		if self.need_redraw or \
+				self.env.cf != self.old_cf or\
 				str(self.env.keybuffer) != str(self.old_keybuffer) or\
 				self.wid != self.old_wid:
+			self.need_redraw = False
 			self.old_wid = self.wid
 			self.old_cf = self.env.cf
 			self._calc_bar()
 		self._print_result(self.result)
 		if self.wid > 2:
 			self.color('in_titlebar', 'throbber')
-			self.win.addnstr(self.y, self.wid - 2, self.throbber, 1)
+			self.win.addnstr(self.y, self.wid - 2 - self.tab_width,
+					self.throbber, 1)
+
+	def click(self, event):
+		"""Handle a MouseEvent"""
+		direction = event.mouse_wheel_direction()
+		if direction:
+			self.fm.tab_move(direction)
+			self.need_redraw = True
+			return True
+
+		if not event.pressed(1) or not self.result:
+			return False
+
+		pos = self.wid - 1
+		for tabname in reversed(self.fm._get_tab_list()):
+			pos -= len(str(tabname)) + 1
+			if event.x > pos:
+				self.fm.tab_open(tabname)
+				self.need_redraw = True
+				return True
+
+		pos = 0
+		for i, part in enumerate(self.result):
+			pos += len(part.string)
+			if event.x < pos:
+				if i < 2:
+					self.fm.enter_dir("~")
+				elif i == 2:
+					self.fm.enter_dir("/")
+				else:
+					try:
+						self.fm.env.enter_dir(self.env.pathway[(i-3)/2])
+					except:
+						pass
+				return True
+		return False
 
 	def _calc_bar(self):
 		bar = Bar('in_titlebar')
@@ -80,6 +127,12 @@ class TitleBar(Widget):
 		self.old_keybuffer = kb
 		bar.addright(kb, 'keybuffer', fixedsize=True)
 		bar.addright('  ', 'space', fixedsize=True)
+		self.tab_width = 0
+		if len(self.fm.tabs) > 1:
+			for tabname in self.fm._get_tab_list():
+				self.tab_width += len(str(tabname)) + 1
+				clr = 'good' if tabname == self.fm.current_tab else 'bad'
+				bar.addright(' '+str(tabname), 'tab', clr, fixedsize=True)
 
 	def _print_result(self, result):
 		import _curses
diff --git a/ranger/help/movement.py b/ranger/help/movement.py
index a0407838..4ea2b0c3 100644
--- a/ranger/help/movement.py
+++ b/ranger/help/movement.py
@@ -21,7 +21,8 @@
 1.3. Searching
 1.4. Cycling
 1.5. Bookmarks
-1.6. Mouse usage
+1.6. Tabs
+1.7. Mouse usage
 
 
 ==============================================================================
@@ -72,7 +73,7 @@ These keys work like in vim:
 	^R	clear the cache and reload the view
 	^L	redraw the window
 	:	open the console |3?|
-	b	toggle options
+	z	toggle options
 
 	i	inspect the content of the file
 	E	edit the file
@@ -102,7 +103,7 @@ visible files. Pressing "n" will move you to the next occurance,
 "N" to the previous one.
 
 You can search for more than just strings:
-	TAB	search tagged files
+	ct	search tagged files
 	cc	cycle through all files by their ctime (last modification)
 	cm	cycle by mime type, connecting similar files
 	cs	cycle by size, large items first
@@ -134,7 +135,21 @@ Note: The ' key is equivalent to `.
 
 
 ==============================================================================
-1.6. Mouse usage
+1.6. Tabs
+
+Tabs are used to work in different directories in the same Ranger instance.
+In Ranger, tabs are very simple though and only store the directory path.
+
+	gt	Go to the next tab. (also TAB)
+	gT	Go to the previous tab. (also Shift+TAB)
+	gn, ^N	Create a new tab
+	g<N>	Open a tab. N has to be a number from 0 to 9.
+		If the tab doesn't exist yet, it will be created.
+	gc, ^W	Close the current tab.  The last tab cannot be closed.
+
+
+==============================================================================
+1.7. Mouse usage
 
 The mouse can be used to quickly enter directories which you point at,
 or to scroll around with the mouse wheel. The implementation of the mouse
diff --git a/ranger/shared/settings.py b/ranger/shared/settings.py
index cdddd623..a4a58e6e 100644
--- a/ranger/shared/settings.py
+++ b/ranger/shared/settings.py
@@ -13,22 +13,25 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import os
-import types
-from inspect import isclass, ismodule
 import ranger
+from ranger.ext.signal_dispatcher import SignalDispatcher
 from ranger.ext.openstruct import OpenStruct
-from ranger.gui.colorscheme import ColorScheme
 
 ALLOWED_SETTINGS = {
 	'show_hidden': bool,
 	'show_cursor': bool,
 	'autosave_bookmarks': bool,
+	'save_console_history': bool,
 	'collapse_preview': bool,
+	'column_ratios': (tuple, list, set),
+	'display_size_in_main_column': bool,
+	'display_size_in_status_bar': bool,
 	'draw_borders': bool,
+	'draw_bookmark_borders': bool,
 	'sort': str,
-	'reverse': bool,
-	'directories_first': bool,
+	'sort_reverse': bool,
+	'sort_case_insensitive': bool,
+	'sort_directories_first': bool,
 	'update_title': bool,
 	'shorten_title': int,  # Note: False is an instance of int
 	'max_filesize_for_preview': (int, type(None)),
@@ -38,26 +41,88 @@ ALLOWED_SETTINGS = {
 	'preview_directories': bool,
 	'flushinput': bool,
 	'colorscheme': str,
+	'colorscheme_overlay': (type(None), type(lambda:0)),
 	'hidden_filter': lambda x: isinstance(x, str) or hasattr(x, 'match'),
 }
 
+
+COMPAT_MAP = {
+	'sort_reverse': 'reverse',
+	'sort_directories_first': 'directories_first',
+}
+
+
+class SettingObject(SignalDispatcher):
+	def __init__(self):
+		SignalDispatcher.__init__(self)
+		self.__dict__['_settings'] = dict()
+		self.__dict__['_setting_sources'] = list()
+
+	def __setattr__(self, name, value):
+		if name[0] == '_':
+			self.__dict__[name] = value
+		else:
+			assert name in self._settings, "No such setting: {0}!".format(name)
+			assert self._check_type(name, value)
+			kws = dict(setting=name, value=value,
+					previous=self._settings[name])
+			self.signal_bind('setopt.'+name,
+					self._raw_set_with_signal, priority=0.2)
+			self.signal_emit('setopt', **kws)
+			self.signal_emit('setopt.'+name, **kws)
+
+	def __getattr__(self, name):
+		assert name in ALLOWED_SETTINGS or name in self._settings, \
+				"No such setting: {0}!".format(name)
+		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)
+			self._raw_set(name, value)
+			self.__setattr__(name, value)
+			return self._settings[name]
+
+	def _check_type(self, name, value):
+		from inspect import isfunction
+		typ = ALLOWED_SETTINGS[name]
+		if isfunction(typ):
+			assert typ(value), \
+				"The option `" + name + "' has an incorrect type!"
+		else:
+			assert isinstance(value, typ), \
+				"The option `" + name + "' has an incorrect type!"\
+				" Got " + str(type(value)) + ", expected " + str(typ) + "!"
+		return True
+
+	__getitem__ = __getattr__
+	__setitem__ = __setattr__
+
+	def _raw_set(self, name, value):
+		self._settings[name] = value
+
+	def _raw_set_with_signal(self, signal):
+		self._settings[signal.setting] = signal.value
+
+
 # -- globalize the settings --
 class SettingsAware(object):
 	settings = OpenStruct()
 
 	@staticmethod
 	def _setup():
-		settings = OpenStruct()
+		settings = SettingObject()
 
-		from ranger.defaults import options
-		for setting in ALLOWED_SETTINGS:
-			try:
-				settings[setting] = getattr(options, setting)
-			except AttributeError:
-				raise Exception("The option `{0}' was not defined" \
-						" in the defaults!".format(setting))
+		from ranger.gui.colorscheme import _colorscheme_name_to_class
+		settings.signal_bind('setopt.colorscheme',
+				_colorscheme_name_to_class, priority=1)
 
-		import sys
 		if not ranger.arg.clean:
 			# overwrite single default options with custom options
 			try:
@@ -65,83 +130,34 @@ class SettingsAware(object):
 			except ImportError:
 				pass
 			else:
-				for setting in ALLOWED_SETTINGS:
+				settings._setting_sources.append(my_options)
+
+				# For backward compatibility:
+				for new, old in COMPAT_MAP.items():
 					try:
-						settings[setting] = getattr(my_options, setting)
+						setattr(my_options, new, getattr(my_options, old))
+						print("Warning: the option `{0}'"\
+								" was renamed to `{1}'\nPlease update"\
+								" your configuration file soon." \
+								.format(old, new))
 					except AttributeError:
 						pass
 
-		assert check_option_types(settings)
-
-		# Find the colorscheme.  First look for it at ~/.ranger/colorschemes,
-		# then at RANGERDIR/colorschemes.  If the file contains a class
-		# named Scheme, it is used.  Otherwise, an arbitrary other class
-		# is picked.
-
-		scheme_name = settings.colorscheme
-
-		def exists(colorscheme):
-			return os.path.exists(colorscheme + '.py')
-
-		def is_scheme(x):
-			return isclass(x) and issubclass(x, ColorScheme)
-
-		# create ~/.ranger/colorschemes/__init__.py if it doesn't exist
-		if os.path.exists(ranger.relpath_conf('colorschemes')):
-			initpy = ranger.relpath_conf('colorschemes', '__init__.py')
-			if not os.path.exists(initpy):
-				open(initpy, 'a').close()
-
-		if exists(ranger.relpath_conf('colorschemes', scheme_name)):
-			scheme_supermodule = 'colorschemes'
-		elif exists(ranger.relpath('colorschemes', scheme_name)):
-			scheme_supermodule = 'ranger.colorschemes'
-		else:
-			scheme_supermodule = None  # found no matching file.
-
-		if scheme_supermodule is None:
-			print("ERROR: colorscheme not found, fall back to builtin scheme")
-			if ranger.arg.debug:
-				raise Exception("Cannot locate colorscheme!")
-			settings.colorscheme = ColorScheme()
-		else:
-			scheme_module = getattr(__import__(scheme_supermodule,
-					globals(), locals(), [scheme_name], 0), scheme_name)
-			assert ismodule(scheme_module)
-			if hasattr(scheme_module, 'Scheme') \
-					and is_scheme(scheme_module.Scheme):
-				settings.colorscheme = scheme_module.Scheme()
-			else:
-				for name, var in scheme_module.__dict__.items():
-					if var != ColorScheme and is_scheme(var):
-						settings.colorscheme = var()
-						break
-				else:
-					raise Exception("The module contains no " \
-							"valid colorscheme!")
+		from ranger.defaults 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!"
 
 		try:
 			import apps
 		except ImportError:
 			from ranger.defaults import apps
-		settings.apps = apps
+		settings._raw_set('apps', apps)
 		try:
 			import keys
 		except ImportError:
 			from ranger.defaults import keys
-		settings.keys = keys
+		settings._raw_set('keys', keys)
 
 		SettingsAware.settings = settings
-
-def check_option_types(opt):
-	import inspect
-	for name, typ in ALLOWED_SETTINGS.items():
-		optvalue = getattr(opt, name)
-		if inspect.isfunction(typ):
-			assert typ(optvalue), \
-				"The option `" + name + "' has an incorrect type!"
-		else:
-			assert isinstance(optvalue, typ), \
-				"The option `" + name + "' has an incorrect type!"\
-				" Got " + str(type(optvalue)) + ", expected " + str(typ) + "!"
-	return True
diff --git a/test/tc_direction.py b/test/tc_direction.py
new file mode 100644
index 00000000..f1078b2d
--- /dev/null
+++ b/test/tc_direction.py
@@ -0,0 +1,80 @@
+# Copyright (C) 2009, 2010  Roman Zimbelmann <romanz@lavabit.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if __name__ == '__main__': from __init__ import init; init()
+
+import unittest
+from ranger.ext.direction import Direction
+from ranger.ext.openstruct import OpenStruct
+
+class TestDirections(unittest.TestCase):
+	def test_symmetry(self):
+		d1 = Direction(right=4, down=7, relative=True)
+		d2 = Direction(left=-4, up=-7, absolute=False)
+
+		def subtest(d):
+			self.assertEqual(4, d.right())
+			self.assertEqual(7, d.down())
+			self.assertEqual(-4, d.left())
+			self.assertEqual(-7, d.up())
+			self.assertEqual(True, d.relative())
+			self.assertEqual(False, d.absolute())
+
+			self.assertTrue(d.horizontal())
+			self.assertTrue(d.vertical())
+
+		subtest(d1)
+		subtest(d2)
+
+	def test_conflicts(self):
+		d3 = Direction(right=5, left=2, up=3, down=6,
+				absolute=True, relative=True)
+		self.assertEqual(d3.right(), -d3.left())
+		self.assertEqual(d3.left(), -d3.right())
+		self.assertEqual(d3.up(), -d3.down())
+		self.assertEqual(d3.down(), -d3.up())
+		self.assertEqual(d3.absolute(), not d3.relative())
+		self.assertEqual(d3.relative(), not d3.absolute())
+
+	def test_copy(self):
+		d = Direction(right=5)
+		c = d.copy()
+		self.assertEqual(c.right(), d.right())
+		d['right'] += 3
+		self.assertNotEqual(c.right(), d.right())
+		c['right'] += 3
+		self.assertEqual(c.right(), d.right())
+
+		self.assertFalse(d.vertical())
+		self.assertTrue(d.horizontal())
+
+	def test_duck_typing(self):
+		dct = dict(right=7, down=-3)
+		self.assertEqual(-7, Direction.left(dct))
+		self.assertEqual(3, Direction.up(dct))
+
+	def test_move(self):
+		d = Direction(pages=True)
+		self.assertEqual(3, d.move(direction=3))
+		self.assertEqual(5, d.move(direction=3, current=2))
+		self.assertEqual(15, d.move(direction=3, pagesize=5))
+		self.assertEqual(10, d.move(direction=3, pagesize=5, maximum=10))
+		self.assertEqual(18, d.move(direction=9, override=2))
+		d2 = Direction(absolute=True)
+		self.assertEqual(5, d2.move(direction=9, override=5))
+
+if __name__ == '__main__':
+	unittest.main()
+
diff --git a/test/tc_signal.py b/test/tc_signal.py
new file mode 100644
index 00000000..35b4eebe
--- /dev/null
+++ b/test/tc_signal.py
@@ -0,0 +1,134 @@
+# Copyright (C) 2009, 2010  Roman Zimbelmann <romanz@lavabit.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if __name__ == '__main__': from __init__ import init; init()
+import unittest
+import gc
+from ranger.ext.signal_dispatcher import *
+
+class TestSignal(unittest.TestCase):
+	def setUp(self):
+		self.sd = SignalDispatcher()
+
+	def test_signal_register_emit(self):
+		sd = self.sd
+		def poo(sig):
+			self.assert_('works' in sig)
+			self.assertEqual('yes', sig.works)
+		handler = sd.signal_bind('x', poo)
+
+		sd.signal_emit('x', works='yes')
+		sd.signal_unbind(handler)
+		sd.signal_emit('x')
+
+	def test_signal_order(self):
+		sd = self.sd
+		lst = []
+		def addn(n):
+			return lambda _: lst.append(n)
+
+		sd.signal_bind('x', addn(6))
+		sd.signal_bind('x', addn(3), priority=1)
+		sd.signal_bind('x', addn(2), priority=1)
+		sd.signal_bind('x', addn(9), priority=0)
+		sd.signal_bind('x', addn(1337), priority=0.7)
+		sd.signal_emit('x')
+
+		self.assert_(lst.index(3) < lst.index(6))
+		self.assert_(lst.index(2) < lst.index(6))
+		self.assert_(lst.index(6) < lst.index(9))
+		self.assert_(lst.index(1337) < lst.index(6))
+		self.assert_(lst.index(1337) < lst.index(9))
+		self.assert_(lst.index(1337) > lst.index(2))
+
+	def test_modifying_arguments(self):
+		sd = self.sd
+		lst = []
+		def modify(s):
+			s.number = 5
+		def set_number(s):
+			lst.append(s.number)
+		def stopit(s):
+			s.stop()
+
+		sd.signal_bind('setnumber', set_number)
+		sd.signal_emit('setnumber', number=100)
+		self.assertEqual(100, lst[-1])
+
+		sd.signal_bind('setnumber', modify, priority=1)
+		sd.signal_emit('setnumber', number=100)
+		self.assertEqual(5, lst[-1])
+
+		lst.append(None)
+		sd.signal_bind('setnumber', stopit, priority=1)
+		sd.signal_emit('setnumber', number=100)
+		self.assertEqual(None, lst[-1])
+
+	def test_weak_refs(self):
+		sd = self.sd
+		is_deleted = [False]
+
+		class Foo(object):
+			def __init__(self):
+				self.alphabet = ['a']
+			def calc(self, signal):
+				self.alphabet.append(chr(ord(self.alphabet[-1]) + 1))
+			def __del__(self):
+				is_deleted[0] = True
+
+		foo = Foo()
+		alphabet = foo.alphabet
+		calc = foo.calc
+
+		del foo
+		self.assertEqual('a', ''.join(alphabet))
+		sd.signal_bind('mysignal', calc, weak=True)
+		sd.signal_emit('mysignal')
+		self.assertEqual('ab', ''.join(alphabet))
+		self.assertFalse(is_deleted[0])
+
+		del calc
+		self.assertTrue(is_deleted[0])
+
+	def test_weak_refs_dead_on_arrival(self):
+		sd = self.sd
+		is_deleted = [False]
+
+		class Foo(object):
+			def __init__(self):
+				self.alphabet = ['a']
+			def calc(self, signal):
+				self.alphabet.append(chr(ord(self.alphabet[-1]) + 1))
+			def __del__(self):
+				is_deleted[0] = True
+
+		foo = Foo()
+		alphabet = foo.alphabet
+
+		self.assertEqual('a', ''.join(alphabet))
+		sd.signal_bind('mysignal', foo.calc, weak=True)
+
+		sd.signal_emit('mysignal')
+		self.assertEqual('ab', ''.join(alphabet))
+		self.assertFalse(is_deleted[0])
+
+		del foo
+
+		sd.signal_emit('mysignal')
+		self.assertEqual('ab', ''.join(alphabet))
+		self.assertTrue(is_deleted[0])
+
+if __name__ == '__main__':
+	unittest.main()