summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorhut <hut@lavabit.com>2010-06-09 14:10:06 +0200
committerhut <hut@lavabit.com>2010-06-09 14:10:06 +0200
commita4c9208bb69b09207c017ae88c810ef0ee83a780 (patch)
tree1666c23d6d69481587d26669c790b278123b1f0a
parent1d895690f81f2cb3a308416c29b280e91e681e36 (diff)
parente74222ee48435895a636812f908c862f3fb7acb6 (diff)
downloadranger-a4c9208bb69b09207c017ae88c810ef0ee83a780.tar.gz
Merge branch 'master' into preview
Conflicts:
	ranger/fsobject/file.py
-rw-r--r--HACKING16
-rw-r--r--INSTALL2
-rw-r--r--Makefile6
-rw-r--r--README4
-rw-r--r--TODO4
-rwxr-xr-xall_benchmarks.py58
-rwxr-xr-xdoc/print_colors.py2
-rw-r--r--doc/print_keys.py2
-rw-r--r--doc/pydoc/ranger.colorschemes.html5
-rw-r--r--doc/pydoc/ranger.defaults.apps.html2
-rw-r--r--doc/pydoc/ranger.ext.html14
-rw-r--r--doc/pydoc/ranger.fsobject.directory.html34
-rw-r--r--doc/pydoc/ranger.fsobject.file.html35
-rw-r--r--doc/pydoc/ranger.fsobject.fsobject.html23
-rw-r--r--doc/pydoc/ranger.gui.curses_shortcuts.html12
-rw-r--r--doc/pydoc/ranger.gui.defaultui.html2
-rw-r--r--doc/pydoc/ranger.gui.displayable.html4
-rw-r--r--doc/pydoc/ranger.gui.ui.html2
-rw-r--r--doc/pydoc/ranger.gui.widgets.browsercolumn.html11
-rw-r--r--doc/pydoc/ranger.gui.widgets.browserview.html2
-rw-r--r--doc/pydoc/ranger.gui.widgets.console.html14
-rw-r--r--doc/pydoc/ranger.gui.widgets.html2
-rw-r--r--doc/pydoc/ranger.gui.widgets.pager.html2
-rw-r--r--doc/pydoc/ranger.gui.widgets.statusbar.html2
-rw-r--r--doc/pydoc/ranger.gui.widgets.taskview.html2
-rw-r--r--doc/pydoc/ranger.gui.widgets.titlebar.html2
-rw-r--r--doc/pydoc/ranger.html4
-rw-r--r--doc/ranger.117
-rwxr-xr-xranger.py2
-rw-r--r--ranger/__init__.py2
-rw-r--r--ranger/__main__.py37
-rw-r--r--ranger/core/environment.py4
-rw-r--r--ranger/ext/shell_escape.py2
-rw-r--r--ranger/fsobject/file.py2
-rw-r--r--ranger/fsobject/fsobject.py5
-rw-r--r--ranger/gui/widgets/console.py6
-rw-r--r--ranger/gui/widgets/taskview.py3
-rw-r--r--ranger/help/index.py4
-rw-r--r--ranger/help/invocation.py9
-rw-r--r--test/__init__.py52
-rwxr-xr-xtest/all_benchmarks.py53
-rwxr-xr-xtest/all_tests.py (renamed from all_tests.py)35
-rw-r--r--test/bm_loader.py2
l---------test/ranger1
-rw-r--r--test/tc_bookmarks.py2
-rw-r--r--test/tc_colorscheme.py2
-rw-r--r--test/tc_direction.py2
-rw-r--r--test/tc_directory.py2
-rw-r--r--test/tc_displayable.py4
-rw-r--r--test/tc_ext.py1
-rw-r--r--test/tc_history.py2
-rw-r--r--test/tc_keyapi.py2
-rw-r--r--test/tc_loader.py4
-rw-r--r--test/tc_newkeys.py3
-rw-r--r--test/tc_signal.py1
-rw-r--r--test/tc_ui.py6
-rw-r--r--test/tc_utfwidth.py2
-rw-r--r--test/testlib.py (renamed from test/test.py)33
58 files changed, 296 insertions, 274 deletions
diff --git a/HACKING b/HACKING
index b184150c..3d35190e 100644
--- a/HACKING
+++ b/HACKING
@@ -10,6 +10,7 @@ Coding Style
     http://www.python.org/dev/peps/pep-0008/
 * Although this guide suggests otherwise, tabs are used for indentation
     of code and docstrings.  In other documents (readme, etc), use spaces.
+* Test the code with unit tests where it makes sense
 
 
 Patches
@@ -23,6 +24,20 @@ If you plan to do major changes, or many changes over time, I encourage
 you to create a fork on GitHub, Gitorious or any other site.
 
 
+Starting Points
+---------------
+
+Good places to read about ranger internals are:
+ranger/core/actions.py
+ranger/core/environment.py
+ranger/fsobject/fsobject.py
+
+About the UI:
+ranger/gui/widgets/browsercolumn.py
+ranger/gui/widgets/browserview.py
+ranger/gui/defaultui.py
+
+
 Common Changes
 --------------
 
@@ -41,6 +56,7 @@ assuming <self> is a "SettingsAware" object.
 
 * Changing commands, adding aliases:
 ranger/defaults/commands.py
+or ~/.ranger/commands.py
 
 * Adding colorschemes:
 Copy ranger/colorschemes/default.py to ranger/colorschemes/myscheme.py
diff --git a/INSTALL b/INSTALL
index 5fc5ca6b..9939c11b 100644
--- a/INSTALL
+++ b/INSTALL
@@ -21,7 +21,7 @@ though you might want to read the Makefile first)
 
 0. Make sure you have a recent version of python, including the
    curses module, which is the case if this shell command prints no errors:
-   python -c 'import curses'
+   python -c 'import curses, sys; assert sys.version >= "2.6"'
 
 
 1. Copy the file "ranger.py" into any of the directories in the PATH
diff --git a/Makefile b/Makefile
index 6a103a02..dc030b5a 100644
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 NAME = ranger
-VERSION = 1.0.4
+VERSION = $(shell cat README | grep -m 1 -o '[0-9][0-9.]\+')
 PYTHON ?= python
 DOCDIR ?= doc/pydoc
 PREFIX ?= /usr
@@ -100,10 +100,10 @@ cleandoc:
 	test -d $(DOCDIR) && rm -f -- $(DOCDIR)/*.html
 
 test:
-	@$(PYTHON) all_tests.py 1
+	@$(PYTHON) test/all_tests.py 1
 
 bm:
-	@$(PYTHON) all_benchmarks.py $(BMCOUNT)
+	@$(PYTHON) test/all_benchmarks.py $(BMCOUNT)
 
 snapshot:
 	git archive HEAD | gzip > $(NAME)-$(VERSION)-$(shell git rev-parse HEAD | cut -b 1-8).tar.gz
diff --git a/README b/README
index ea9eb521..fb1f4d8b 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-Ranger v.1.0.4
+Ranger v.1.1.0
 ==============
 
 Ranger is a free console file manager that gives you greater flexibility
@@ -19,7 +19,7 @@ About
 * Author:          Roman Zimbelmann  <romanz@lavabit.com>
 * Website:         http://savannah.nongnu.org/projects/ranger
 * License:         GNU General Public License Version 3
-* Version:         1.0.4
+* Version:         1.1.0
 
 * Download URL of the newest stable version:
 http://git.savannah.gnu.org/cgit/ranger.git/snapshot/ranger-stable.tar.gz
diff --git a/TODO b/TODO
index 1e02251c..1577f97a 100644
--- a/TODO
+++ b/TODO
@@ -51,7 +51,7 @@ General
    (X) #71  10/03/21  previews: black/whitelist + read file
    (X) #79  10/04/08  tab number zero
    ( ) #80  10/04/08  when closing tabs, avoid gaps?
-   ( ) #81  10/04/15  system crash when previewing /proc/kcore with root permissions
+   (X) #81  10/04/15  system crash when previewing /proc/kcore with root permissions
    (X) #83  10/04/19  better ways to mark files. eg by regexp, filetype,..
    ( ) #86  10/04/21  narg for move_parent
    ( ) #60  10/02/05  utf support improvable
@@ -115,5 +115,5 @@ Ideas
 Blocking
 
    ( ) #60  10/02/05  utf support improvable
-   ( ) #81  10/04/15  system crash when previewing /proc/kcore with root permissions
+   (X) #81  10/04/15  system crash when previewing /proc/kcore with root permissions
 
diff --git a/all_benchmarks.py b/all_benchmarks.py
deleted file mode 100755
index 73316658..00000000
--- a/all_benchmarks.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/python
-# 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/>.
-
-"""Run all the tests inside the test/ directory as a test suite."""
-if __name__ == '__main__':
-	from re import compile
-	from test import *
-	from time import time
-	from types import FunctionType as function
-	from sys import argv
-	bms = []
-	try:
-		n = int(argv[1])
-	except IndexError:
-		n = 10
-	if len(argv) > 2:
-		args = [compile(re) for re in argv[2:]]
-		def allow(name):
-			for re in args:
-				if re.search(name):
-					return True
-			else:
-				return False
-	else:
-		allow = lambda name: True
-	for key, val in vars().copy().items():
-		if key.startswith('bm_'):
-			bms.extend(v for k,v in vars(val).items() if type(v) == type)
-	for bmclass in bms:
-		for attrname in vars(bmclass):
-			if not attrname.startswith('bm_'):
-				continue
-			bmobj = bmclass()
-			t1 = time()
-			method = getattr(bmobj, attrname)
-			methodname = "{0}.{1}".format(bmobj.__class__.__name__, method.__name__)
-			if allow(methodname):
-				try:
-					method(n)
-				except:
-					print("{0} failed!".format(methodname))
-					raise
-				else:
-					t2 = time()
-					print("{0:60}: {1:10}s".format(methodname, t2 - t1))
diff --git a/doc/print_colors.py b/doc/print_colors.py
index 7ffd6500..c3508fa6 100755
--- a/doc/print_colors.py
+++ b/doc/print_colors.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 """
 You can use this tool to display all supported colors and their color number.
 It will exit after a keypress.
diff --git a/doc/print_keys.py b/doc/print_keys.py
index 0790acab..f87a2a40 100644
--- a/doc/print_keys.py
+++ b/doc/print_keys.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 """
 You can use this tool to find out values of keypresses
 """
diff --git a/doc/pydoc/ranger.colorschemes.html b/doc/pydoc/ranger.colorschemes.html
index 966e9978..05a3017d 100644
--- a/doc/pydoc/ranger.colorschemes.html
+++ b/doc/pydoc/ranger.colorschemes.html
@@ -20,8 +20,7 @@
 <td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="ranger.colorschemes.default.html">default</a><br>
 <a href="ranger.colorschemes.default88.html">default88</a><br>
 </td><td width="25%" valign=top><a href="ranger.colorschemes.jungle.html">jungle</a><br>
-<a href="ranger.colorschemes.plain.html">plain</a><br>
-</td><td width="25%" valign=top><a href="ranger.colorschemes.snow.html">snow</a><br>
-<a href="ranger.colorschemes.texas.html">texas</a><br>
+<a href="ranger.colorschemes.snow.html">snow</a><br>
+</td><td width="25%" valign=top><a href="ranger.colorschemes.texas.html">texas</a><br>
 </td><td width="25%" valign=top></td></tr></table></td></tr></table>
 </body></html>
\ No newline at end of file
diff --git a/doc/pydoc/ranger.defaults.apps.html b/doc/pydoc/ranger.defaults.apps.html
index fb820921..e6f07ec6 100644
--- a/doc/pydoc/ranger.defaults.apps.html
+++ b/doc/pydoc/ranger.defaults.apps.html
@@ -100,6 +100,8 @@ Methods defined here:<br>
 
 <dl><dt><a name="CustomApplications-app_feh"><strong>app_feh</strong></a>(self, c)</dt></dl>
 
+<dl><dt><a name="CustomApplications-app_file_roller"><strong>app_file_roller</strong></a>(self, c)</dt></dl>
+
 <dl><dt><strong>app_firefox</strong> <em>lambda</em> self, context</dt></dl>
 
 <dl><dt><strong>app_gimp</strong> <em>lambda</em> self, context</dt></dl>
diff --git a/doc/pydoc/ranger.ext.html b/doc/pydoc/ranger.ext.html
index afd5aeb2..80d894b8 100644
--- a/doc/pydoc/ranger.ext.html
+++ b/doc/pydoc/ranger.ext.html
@@ -21,17 +21,19 @@
 <a href="ranger.ext.command_parser.html">command_parser</a><br>
 <a href="ranger.ext.curses_interrupt_handler.html">curses_interrupt_handler</a><br>
 <a href="ranger.ext.direction.html">direction</a><br>
-</td><td width="25%" valign=top><a href="ranger.ext.get_executables.html">get_executables</a><br>
-<a href="ranger.ext.human_readable.html">human_readable</a><br>
+<a href="ranger.ext.get_executables.html">get_executables</a><br>
+</td><td width="25%" valign=top><a href="ranger.ext.human_readable.html">human_readable</a><br>
 <a href="ranger.ext.iter_tools.html">iter_tools</a><br>
 <a href="ranger.ext.keybinding_parser.html">keybinding_parser</a><br>
-</td><td width="25%" valign=top><a href="ranger.ext.mount_path.html">mount_path</a><br>
-<a href="ranger.ext.openstruct.html">openstruct</a><br>
+<a href="ranger.ext.lazy_property.html">lazy_property</a><br>
+<a href="ranger.ext.mount_path.html">mount_path</a><br>
+</td><td width="25%" valign=top><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.signal_dispatcher.html">signal_dispatcher</a><br>
+<a href="ranger.ext.signal_dispatcher.html">signal_dispatcher</a><br>
 <a href="ranger.ext.spawn.html">spawn</a><br>
-<a href="ranger.ext.tree.html">tree</a><br>
+</td><td width="25%" valign=top><a href="ranger.ext.tree.html">tree</a><br>
+<a href="ranger.ext.utfwidth.html">utfwidth</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 77790809..56306bb0 100644
--- a/doc/pydoc/ranger.fsobject.directory.html
+++ b/doc/pydoc/ranger.fsobject.directory.html
@@ -99,10 +99,16 @@ Methods defined here:<br>
 
 <dl><dt><a name="Directory-empty"><strong>empty</strong></a>(self)</dt><dd><tt>Is&nbsp;the&nbsp;directory&nbsp;empty?</tt></dd></dl>
 
+<dl><dt><a name="Directory-get_description"><strong>get_description</strong></a>(self)</dt></dl>
+
 <dl><dt><a name="Directory-get_list"><strong>get_list</strong></a>(self)</dt></dl>
 
 <dl><dt><a name="Directory-get_selection"><strong>get_selection</strong></a>(self)</dt><dd><tt>READ&nbsp;ONLY</tt></dd></dl>
 
+<dl><dt><a name="Directory-go"><strong>go</strong></a>(self)</dt><dd><tt>enter&nbsp;the&nbsp;directory&nbsp;if&nbsp;the&nbsp;filemanager&nbsp;is&nbsp;running</tt></dd></dl>
+
+<dl><dt><a name="Directory-is_older_than"><strong>is_older_than</strong></a>(self, seconds)</dt><dd><tt>returns&nbsp;whether&nbsp;this&nbsp;object&nbsp;wasn't&nbsp;<a href="#Directory-use">use</a>()d&nbsp;in&nbsp;the&nbsp;last&nbsp;n&nbsp;seconds</tt></dd></dl>
+
 <dl><dt><a name="Directory-load_bit_by_bit"><strong>load_bit_by_bit</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;generator&nbsp;which&nbsp;load&nbsp;a&nbsp;part&nbsp;of&nbsp;the&nbsp;directory<br>
 in&nbsp;each&nbsp;iteration.</tt></dd></dl>
 
@@ -138,6 +144,8 @@ outdated&nbsp;or&nbsp;not&nbsp;done&nbsp;yet</tt></dd></dl>
 
 <dl><dt><a name="Directory-unload"><strong>unload</strong></a>(self)</dt></dl>
 
+<dl><dt><a name="Directory-use"><strong>use</strong></a>(self)</dt><dd><tt>mark&nbsp;the&nbsp;filesystem-object&nbsp;as&nbsp;used&nbsp;at&nbsp;the&nbsp;current&nbsp;time</tt></dd></dl>
+
 <hr>
 Data and other attributes defined here:<br>
 <dl><dt><strong>content_loaded</strong> = False</dl>
@@ -184,14 +192,8 @@ Methods inherited from <a href="ranger.fsobject.fsobject.html#FileSystemObject">
 
 <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>
-
 <dl><dt><a name="Directory-get_permission_string"><strong>get_permission_string</strong></a>(self)</dt></dl>
 
-<dl><dt><a name="Directory-go"><strong>go</strong></a>(self)</dt><dd><tt>enter&nbsp;the&nbsp;directory&nbsp;if&nbsp;the&nbsp;filemanager&nbsp;is&nbsp;running</tt></dd></dl>
-
-<dl><dt><a name="Directory-is_older_than"><strong>is_older_than</strong></a>(self, seconds)</dt><dd><tt>returns&nbsp;whether&nbsp;this&nbsp;object&nbsp;wasn't&nbsp;<a href="#Directory-use">use</a>()d&nbsp;in&nbsp;the&nbsp;last&nbsp;n&nbsp;seconds</tt></dd></dl>
-
 <dl><dt><a name="Directory-load"><strong>load</strong></a>(self)</dt><dd><tt>reads&nbsp;useful&nbsp;information&nbsp;about&nbsp;the&nbsp;filesystem-object&nbsp;from&nbsp;the<br>
 filesystem&nbsp;and&nbsp;caches&nbsp;it&nbsp;for&nbsp;later&nbsp;use</tt></dd></dl>
 
@@ -202,18 +204,12 @@ or&nbsp;nonexistant.</tt></dd></dl>
 
 <dl><dt><a name="Directory-set_mimetype"><strong>set_mimetype</strong></a>(self)</dt><dd><tt>assign&nbsp;attributes&nbsp;such&nbsp;as&nbsp;self.<strong>video</strong>&nbsp;according&nbsp;to&nbsp;the&nbsp;mimetype</tt></dd></dl>
 
-<dl><dt><a name="Directory-use"><strong>use</strong></a>(self)</dt><dd><tt>mark&nbsp;the&nbsp;filesystem-object&nbsp;as&nbsp;used&nbsp;at&nbsp;the&nbsp;current&nbsp;time</tt></dd></dl>
-
 <hr>
 Data descriptors inherited from <a href="ranger.fsobject.fsobject.html#FileSystemObject">ranger.fsobject.fsobject.FileSystemObject</a>:<br>
-<dl><dt><strong>filetype</strong></dt>
-</dl>
 <dl><dt><strong>mimetype</strong></dt>
 </dl>
 <dl><dt><strong>mimetype_tuple</strong></dt>
 </dl>
-<dl><dt><strong>shell_escaped_basename</strong></dt>
-</dl>
 <hr>
 Data and other attributes inherited from <a href="ranger.fsobject.fsobject.html#FileSystemObject">ranger.fsobject.fsobject.FileSystemObject</a>:<br>
 <dl><dt><strong>accessible</strong> = False</dl>
@@ -234,6 +230,8 @@ Data and other attributes inherited from <a href="ranger.fsobject.fsobject.html#
 
 <dl><dt><strong>extension</strong> = None</dl>
 
+<dl><dt><strong>filetype</strong> = None</dl>
+
 <dl><dt><strong>force_load</strong> = False</dl>
 
 <dl><dt><strong>image</strong> = False</dl>
@@ -250,8 +248,6 @@ Data and other attributes inherited from <a href="ranger.fsobject.fsobject.html#
 
 <dl><dt><strong>is_socket</strong> = False</dl>
 
-<dl><dt><strong>last_used</strong> = None</dl>
-
 <dl><dt><strong>loaded</strong> = False</dl>
 
 <dl><dt><strong>marked</strong> = False</dl>
@@ -262,8 +258,12 @@ Data and other attributes inherited from <a href="ranger.fsobject.fsobject.html#
 
 <dl><dt><strong>permissions</strong> = None</dl>
 
+<dl><dt><strong>realpath</strong> = None</dl>
+
 <dl><dt><strong>runnable</strong> = False</dl>
 
+<dl><dt><strong>shell_escaped_basename</strong> = None</dl>
+
 <dl><dt><strong>size</strong> = 0</dl>
 
 <dl><dt><strong>stat</strong> = None</dl>
@@ -312,6 +312,12 @@ Data and other attributes inherited from <a href="ranger.shared.settings.html#Se
     
 <tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
 <td width="100%"><dl><dt><a name="-accept_file"><strong>accept_file</strong></a>(fname, hidden_filter, name_filter)</dt></dl>
+ <dl><dt><a name="-os_lstat"><strong>os_lstat</strong></a> = lstat(...)</dt><dd><tt>lstat(path)&nbsp;-&gt;&nbsp;stat&nbsp;result<br>
+&nbsp;<br>
+Like&nbsp;stat(path),&nbsp;but&nbsp;do&nbsp;not&nbsp;follow&nbsp;symbolic&nbsp;links.</tt></dd></dl>
+ <dl><dt><a name="-os_stat"><strong>os_stat</strong></a> = stat(...)</dt><dd><tt>stat(path)&nbsp;-&gt;&nbsp;stat&nbsp;result<br>
+&nbsp;<br>
+Perform&nbsp;a&nbsp;stat&nbsp;system&nbsp;call&nbsp;on&nbsp;the&nbsp;given&nbsp;path.</tt></dd></dl>
  <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>
diff --git a/doc/pydoc/ranger.fsobject.file.html b/doc/pydoc/ranger.fsobject.file.html
index 948be90d..fb945388 100644
--- a/doc/pydoc/ranger.fsobject.file.html
+++ b/doc/pydoc/ranger.fsobject.file.html
@@ -25,6 +25,15 @@
 #&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="re.html">re</a><br>
+</td><td width="25%" valign=top><a href="zipfile.html">zipfile</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>
@@ -55,6 +64,10 @@
 </dl>
 <hr>
 Methods defined here:<br>
+<dl><dt><a name="File-get_preview_source"><strong>get_preview_source</strong></a>(self)</dt></dl>
+
+<dl><dt><a name="File-has_preview"><strong>has_preview</strong></a>(self)</dt></dl>
+
 <dl><dt><a name="File-is_binary"><strong>is_binary</strong></a>(self)</dt></dl>
 
 <hr>
@@ -73,14 +86,8 @@ Methods inherited from <a href="ranger.fsobject.fsobject.html#FileSystemObject">
 
 <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>
-
 <dl><dt><a name="File-get_permission_string"><strong>get_permission_string</strong></a>(self)</dt></dl>
 
-<dl><dt><a name="File-go"><strong>go</strong></a>(self)</dt><dd><tt>enter&nbsp;the&nbsp;directory&nbsp;if&nbsp;the&nbsp;filemanager&nbsp;is&nbsp;running</tt></dd></dl>
-
-<dl><dt><a name="File-is_older_than"><strong>is_older_than</strong></a>(self, seconds)</dt><dd><tt>returns&nbsp;whether&nbsp;this&nbsp;object&nbsp;wasn't&nbsp;<a href="#File-use">use</a>()d&nbsp;in&nbsp;the&nbsp;last&nbsp;n&nbsp;seconds</tt></dd></dl>
-
 <dl><dt><a name="File-load"><strong>load</strong></a>(self)</dt><dd><tt>reads&nbsp;useful&nbsp;information&nbsp;about&nbsp;the&nbsp;filesystem-object&nbsp;from&nbsp;the<br>
 filesystem&nbsp;and&nbsp;caches&nbsp;it&nbsp;for&nbsp;later&nbsp;use</tt></dd></dl>
 
@@ -91,18 +98,14 @@ or&nbsp;nonexistant.</tt></dd></dl>
 
 <dl><dt><a name="File-set_mimetype"><strong>set_mimetype</strong></a>(self)</dt><dd><tt>assign&nbsp;attributes&nbsp;such&nbsp;as&nbsp;self.<strong>video</strong>&nbsp;according&nbsp;to&nbsp;the&nbsp;mimetype</tt></dd></dl>
 
-<dl><dt><a name="File-use"><strong>use</strong></a>(self)</dt><dd><tt>mark&nbsp;the&nbsp;filesystem-object&nbsp;as&nbsp;used&nbsp;at&nbsp;the&nbsp;current&nbsp;time</tt></dd></dl>
+<dl><dt><a name="File-use"><strong>use</strong></a>(self)</dt><dd><tt>Used&nbsp;in&nbsp;garbage-collecting.&nbsp;&nbsp;Override&nbsp;in&nbsp;Directory</tt></dd></dl>
 
 <hr>
 Data descriptors inherited from <a href="ranger.fsobject.fsobject.html#FileSystemObject">ranger.fsobject.fsobject.FileSystemObject</a>:<br>
-<dl><dt><strong>filetype</strong></dt>
-</dl>
 <dl><dt><strong>mimetype</strong></dt>
 </dl>
 <dl><dt><strong>mimetype_tuple</strong></dt>
 </dl>
-<dl><dt><strong>shell_escaped_basename</strong></dt>
-</dl>
 <hr>
 Data and other attributes inherited from <a href="ranger.fsobject.fsobject.html#FileSystemObject">ranger.fsobject.fsobject.FileSystemObject</a>:<br>
 <dl><dt><strong>accessible</strong> = False</dl>
@@ -125,6 +128,8 @@ Data and other attributes inherited from <a href="ranger.fsobject.fsobject.html#
 
 <dl><dt><strong>extension</strong> = None</dl>
 
+<dl><dt><strong>filetype</strong> = None</dl>
+
 <dl><dt><strong>force_load</strong> = False</dl>
 
 <dl><dt><strong>image</strong> = False</dl>
@@ -141,8 +146,6 @@ Data and other attributes inherited from <a href="ranger.fsobject.fsobject.html#
 
 <dl><dt><strong>is_socket</strong> = False</dl>
 
-<dl><dt><strong>last_used</strong> = None</dl>
-
 <dl><dt><strong>loaded</strong> = False</dl>
 
 <dl><dt><strong>marked</strong> = False</dl>
@@ -153,8 +156,12 @@ Data and other attributes inherited from <a href="ranger.fsobject.fsobject.html#
 
 <dl><dt><strong>permissions</strong> = None</dl>
 
+<dl><dt><strong>realpath</strong> = None</dl>
+
 <dl><dt><strong>runnable</strong> = False</dl>
 
+<dl><dt><strong>shell_escaped_basename</strong> = None</dl>
+
 <dl><dt><strong>size</strong> = 0</dl>
 
 <dl><dt><strong>stat</strong> = None</dl>
@@ -189,5 +196,7 @@ Data and other attributes inherited from <a href="ranger.shared.html#FileManager
     
 <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>PREVIEW_BLACKLIST</strong> = &lt;_sre.SRE_Pattern object&gt;<br>
+<strong>PREVIEW_WHITELIST</strong> = &lt;_sre.SRE_Pattern object&gt;<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 869ecfbe..ce0b983f 100644
--- a/doc/pydoc/ranger.fsobject.fsobject.html
+++ b/doc/pydoc/ranger.fsobject.fsobject.html
@@ -66,14 +66,8 @@ Methods defined here:<br>
 
 <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>
-
 <dl><dt><a name="FileSystemObject-get_permission_string"><strong>get_permission_string</strong></a>(self)</dt></dl>
 
-<dl><dt><a name="FileSystemObject-go"><strong>go</strong></a>(self)</dt><dd><tt>enter&nbsp;the&nbsp;directory&nbsp;if&nbsp;the&nbsp;filemanager&nbsp;is&nbsp;running</tt></dd></dl>
-
-<dl><dt><a name="FileSystemObject-is_older_than"><strong>is_older_than</strong></a>(self, seconds)</dt><dd><tt>returns&nbsp;whether&nbsp;this&nbsp;object&nbsp;wasn't&nbsp;<a href="#FileSystemObject-use">use</a>()d&nbsp;in&nbsp;the&nbsp;last&nbsp;n&nbsp;seconds</tt></dd></dl>
-
 <dl><dt><a name="FileSystemObject-load"><strong>load</strong></a>(self)</dt><dd><tt>reads&nbsp;useful&nbsp;information&nbsp;about&nbsp;the&nbsp;filesystem-object&nbsp;from&nbsp;the<br>
 filesystem&nbsp;and&nbsp;caches&nbsp;it&nbsp;for&nbsp;later&nbsp;use</tt></dd></dl>
 
@@ -84,18 +78,14 @@ or&nbsp;nonexistant.</tt></dd></dl>
 
 <dl><dt><a name="FileSystemObject-set_mimetype"><strong>set_mimetype</strong></a>(self)</dt><dd><tt>assign&nbsp;attributes&nbsp;such&nbsp;as&nbsp;self.<strong>video</strong>&nbsp;according&nbsp;to&nbsp;the&nbsp;mimetype</tt></dd></dl>
 
-<dl><dt><a name="FileSystemObject-use"><strong>use</strong></a>(self)</dt><dd><tt>mark&nbsp;the&nbsp;filesystem-object&nbsp;as&nbsp;used&nbsp;at&nbsp;the&nbsp;current&nbsp;time</tt></dd></dl>
+<dl><dt><a name="FileSystemObject-use"><strong>use</strong></a>(self)</dt><dd><tt>Used&nbsp;in&nbsp;garbage-collecting.&nbsp;&nbsp;Override&nbsp;in&nbsp;Directory</tt></dd></dl>
 
 <hr>
 Data descriptors defined here:<br>
-<dl><dt><strong>filetype</strong></dt>
-</dl>
 <dl><dt><strong>mimetype</strong></dt>
 </dl>
 <dl><dt><strong>mimetype_tuple</strong></dt>
 </dl>
-<dl><dt><strong>shell_escaped_basename</strong></dt>
-</dl>
 <hr>
 Data and other attributes defined here:<br>
 <dl><dt><strong>accessible</strong> = False</dl>
@@ -118,6 +108,8 @@ Data and other attributes defined here:<br>
 
 <dl><dt><strong>extension</strong> = None</dl>
 
+<dl><dt><strong>filetype</strong> = None</dl>
+
 <dl><dt><strong>force_load</strong> = False</dl>
 
 <dl><dt><strong>image</strong> = False</dl>
@@ -136,8 +128,6 @@ Data and other attributes defined here:<br>
 
 <dl><dt><strong>is_socket</strong> = False</dl>
 
-<dl><dt><strong>last_used</strong> = None</dl>
-
 <dl><dt><strong>loaded</strong> = False</dl>
 
 <dl><dt><strong>marked</strong> = False</dl>
@@ -148,8 +138,12 @@ Data and other attributes defined here:<br>
 
 <dl><dt><strong>permissions</strong> = None</dl>
 
+<dl><dt><strong>realpath</strong> = None</dl>
+
 <dl><dt><strong>runnable</strong> = False</dl>
 
+<dl><dt><strong>shell_escaped_basename</strong> = None</dl>
+
 <dl><dt><strong>size</strong> = 0</dl>
 
 <dl><dt><strong>stat</strong> = None</dl>
@@ -219,5 +213,6 @@ Fractions&nbsp;of&nbsp;a&nbsp;second&nbsp;may&nbsp;be&nbsp;present&nbsp;if&nbsp;
     
 <tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
 <td width="100%"><strong>BAD_INFO</strong> = '?'<br>
-<strong>CONTAINER_EXTENSIONS</strong> = ('7z', 'ace', 'ar', 'arc', 'bz', 'bz2', 'cab', 'cpio', 'cpt', 'dgc', 'dmg', 'gz', 'iso', 'jar', 'msi', 'pkg', 'rar', 'shar', 'tar', 'tbz', ...)</td></tr></table>
+<strong>CONTAINER_EXTENSIONS</strong> = ('7z', 'ace', 'ar', 'arc', 'bz', 'bz2', 'cab', 'cpio', 'cpt', 'dgc', 'dmg', 'gz', 'iso', 'jar', 'msi', 'pkg', 'rar', 'shar', 'tar', 'tbz', ...)<br>
+<strong>extsep</strong> = '.'</td></tr></table>
 </body></html>
\ No newline at end of file
diff --git a/doc/pydoc/ranger.gui.curses_shortcuts.html b/doc/pydoc/ranger.gui.curses_shortcuts.html
index 56fb8618..0063e437 100644
--- a/doc/pydoc/ranger.gui.curses_shortcuts.html
+++ b/doc/pydoc/ranger.gui.curses_shortcuts.html
@@ -67,6 +67,8 @@
 </dl>
 <hr>
 Methods defined here:<br>
+<dl><dt><a name="CursesShortcuts-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="CursesShortcuts-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="CursesShortcuts-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
@@ -89,5 +91,13 @@ Data descriptors inherited from <a href="ranger.shared.settings.html#SettingsAwa
 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>
+</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="-ascii_only"><strong>ascii_only</strong></a>(string)</dt></dl>
+</td></tr></table>
 </body></html>
\ No newline at end of file
diff --git a/doc/pydoc/ranger.gui.defaultui.html b/doc/pydoc/ranger.gui.defaultui.html
index 93496aed..64316851 100644
--- a/doc/pydoc/ranger.gui.defaultui.html
+++ b/doc/pydoc/ranger.gui.defaultui.html
@@ -169,6 +169,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="DefaultUI-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="DefaultUI-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="DefaultUI-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
diff --git a/doc/pydoc/ranger.gui.displayable.html b/doc/pydoc/ranger.gui.displayable.html
index 2e0cf7b6..276395ac 100644
--- a/doc/pydoc/ranger.gui.displayable.html
+++ b/doc/pydoc/ranger.gui.displayable.html
@@ -176,6 +176,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="Displayable-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="Displayable-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="Displayable-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
@@ -276,6 +278,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="DisplayableContainer-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="DisplayableContainer-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="DisplayableContainer-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
diff --git a/doc/pydoc/ranger.gui.ui.html b/doc/pydoc/ranger.gui.ui.html
index 8216ae1b..a8a59091 100644
--- a/doc/pydoc/ranger.gui.ui.html
+++ b/doc/pydoc/ranger.gui.ui.html
@@ -153,6 +153,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="UI-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="UI-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="UI-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
diff --git a/doc/pydoc/ranger.gui.widgets.browsercolumn.html b/doc/pydoc/ranger.gui.widgets.browsercolumn.html
index 42407c57..b997cbef 100644
--- a/doc/pydoc/ranger.gui.widgets.browsercolumn.html
+++ b/doc/pydoc/ranger.gui.widgets.browsercolumn.html
@@ -17,9 +17,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="re.html">re</a><br>
-</td><td width="25%" valign=top><a href="stat.html">stat</a><br>
-</td><td width="25%" valign=top></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="stat.html">stat</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>
@@ -155,6 +154,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="BrowserColumn-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="BrowserColumn-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="BrowserColumn-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
@@ -187,7 +188,5 @@ 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>BAD_INFO</strong> = '?'<br>
-<strong>PREVIEW_BLACKLIST</strong> = &lt;_sre.SRE_Pattern object&gt;<br>
-<strong>PREVIEW_WHITELIST</strong> = &lt;_sre.SRE_Pattern object&gt;</td></tr></table>
+<td width="100%"><strong>BAD_INFO</strong> = '?'</td></tr></table>
 </body></html>
\ No newline at end of file
diff --git a/doc/pydoc/ranger.gui.widgets.browserview.html b/doc/pydoc/ranger.gui.widgets.browserview.html
index c07ea3d6..3827106c 100644
--- a/doc/pydoc/ranger.gui.widgets.browserview.html
+++ b/doc/pydoc/ranger.gui.widgets.browserview.html
@@ -136,6 +136,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="BrowserView-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="BrowserView-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="BrowserView-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
diff --git a/doc/pydoc/ranger.gui.widgets.console.html b/doc/pydoc/ranger.gui.widgets.console.html
index 4c72eae7..107ed09b 100644
--- a/doc/pydoc/ranger.gui.widgets.console.html
+++ b/doc/pydoc/ranger.gui.widgets.console.html
@@ -187,6 +187,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="CommandConsole-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="CommandConsole-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="CommandConsole-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
@@ -326,6 +328,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="Console-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="Console-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="Console-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
@@ -468,6 +472,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="ConsoleWithTab-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="ConsoleWithTab-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="ConsoleWithTab-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
@@ -634,6 +640,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="OpenConsole-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="OpenConsole-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="OpenConsole-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
@@ -795,6 +803,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="QuickCommandConsole-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="QuickCommandConsole-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="QuickCommandConsole-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
@@ -966,6 +976,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="QuickOpenConsole-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="QuickOpenConsole-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="QuickOpenConsole-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
@@ -1110,6 +1122,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="SearchConsole-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="SearchConsole-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="SearchConsole-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
diff --git a/doc/pydoc/ranger.gui.widgets.html b/doc/pydoc/ranger.gui.widgets.html
index d08b2136..b20d3c9f 100644
--- a/doc/pydoc/ranger.gui.widgets.html
+++ b/doc/pydoc/ranger.gui.widgets.html
@@ -127,6 +127,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="Widget-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="Widget-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="Widget-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
diff --git a/doc/pydoc/ranger.gui.widgets.pager.html b/doc/pydoc/ranger.gui.widgets.pager.html
index fff55482..290f348f 100644
--- a/doc/pydoc/ranger.gui.widgets.pager.html
+++ b/doc/pydoc/ranger.gui.widgets.pager.html
@@ -122,6 +122,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="Pager-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="Pager-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="Pager-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
diff --git a/doc/pydoc/ranger.gui.widgets.statusbar.html b/doc/pydoc/ranger.gui.widgets.statusbar.html
index 7fd7cb4b..65087ba2 100644
--- a/doc/pydoc/ranger.gui.widgets.statusbar.html
+++ b/doc/pydoc/ranger.gui.widgets.statusbar.html
@@ -167,6 +167,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="StatusBar-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="StatusBar-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="StatusBar-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
diff --git a/doc/pydoc/ranger.gui.widgets.taskview.html b/doc/pydoc/ranger.gui.widgets.taskview.html
index da7bfb62..7c59fee1 100644
--- a/doc/pydoc/ranger.gui.widgets.taskview.html
+++ b/doc/pydoc/ranger.gui.widgets.taskview.html
@@ -120,6 +120,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="TaskView-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="TaskView-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="TaskView-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
diff --git a/doc/pydoc/ranger.gui.widgets.titlebar.html b/doc/pydoc/ranger.gui.widgets.titlebar.html
index db129e45..8823b03a 100644
--- a/doc/pydoc/ranger.gui.widgets.titlebar.html
+++ b/doc/pydoc/ranger.gui.widgets.titlebar.html
@@ -116,6 +116,8 @@ Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.sh
 </dl>
 <hr>
 Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br>
+<dl><dt><a name="TitleBar-addch"><strong>addch</strong></a>(self, *args)</dt></dl>
+
 <dl><dt><a name="TitleBar-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl>
 
 <dl><dt><a name="TitleBar-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl>
diff --git a/doc/pydoc/ranger.html b/doc/pydoc/ranger.html
index b8e4e198..a0bc2cc6 100644
--- a/doc/pydoc/ranger.html
+++ b/doc/pydoc/ranger.html
@@ -6,7 +6,7 @@
 <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
 <tr bgcolor="#7799ee">
 <td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong>ranger</strong></big></big> (version 1.0.4)</font></td
+<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong>ranger</strong></big></big> (version 1.1.0)</font></td
 ><td align=right valign=bottom
 ><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/hut/code/ranger/ranger/__init__.py">/home/hut/code/ranger/ranger/__init__.py</a></font></td></tr></table>
     <p><tt>Ranger&nbsp;-&nbsp;file&nbsp;browser&nbsp;for&nbsp;the&nbsp;unix&nbsp;terminal</tt></p>
@@ -56,7 +56,7 @@ Has&nbsp;the&nbsp;same&nbsp;arguments&nbsp;as&nbsp;print()&nbsp;in&nbsp;python3.
 <strong>__email__</strong> = 'romanz@lavabit.com'<br>
 <strong>__license__</strong> = 'GPL3'<br>
 <strong>__maintainer__</strong> = 'Roman Zimbelmann'<br>
-<strong>__version__</strong> = '1.0.4'<br>
+<strong>__version__</strong> = '1.1.0'<br>
 <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">
diff --git a/doc/ranger.1 b/doc/ranger.1
index b197d774..ee94e1fd 100644
--- a/doc/ranger.1
+++ b/doc/ranger.1
@@ -1,4 +1,4 @@
-.TH RANGER 1 ranger-1.0.4
+.TH RANGER 1 ranger-1.1.0
 .SH NAME
 ranger - visual file manager
 .\"-----------------------------------------
@@ -33,9 +33,9 @@ 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
---fail-if-run
+--fail-unless-cd
 Return the exit code 1 if ranger is used to run a file, for example with
-`ranger --fail-if-run filename`.  This can be useful for scripts.
+`ranger --fail-unless-cd filename`.  This can be useful for scripts.
 .TP
 -r \fIdir\fR, --confdir=\fIdir\fR
 Define a different configuration directory.  The default is $HOME/.ranger.
@@ -176,7 +176,7 @@ of your parent shell after exiting ranger:
 .nf
 
 ranger() {
-    command ranger --fail-if-run $@ &&
+    command ranger --fail-unless-cd $@ &&
     cd "$(grep \\^\\' ~/.ranger/bookmarks | cut -b3-)"
 }
 .\"-----------------------------------------
@@ -185,9 +185,8 @@ 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.
+Most files don't have to be copied completely though: Just define those
+settings you want to add or change and they will override the defauls.
 Colorschemes can be placed in $HOME/.ranger/colorschemes.
 .P
 All configuration is done in Python.
@@ -214,7 +213,7 @@ 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:
+Please report them here and include as much relevant information
+as possible:
 .P
 .RB < http://savannah.nongnu.org/bugs/?group=ranger >
diff --git a/ranger.py b/ranger.py
index aca1b557..ccc9f0d6 100755
--- a/ranger.py
+++ b/ranger.py
@@ -23,7 +23,7 @@
 # after you exit ranger by starting it with: source ranger ranger
 """":
 if [ $1 ]; then
-	$@ --fail-if-run && cd "$(grep \^\' ~/.ranger/bookmarks | cut -b3-)"
+	$@ --fail-unless-cd && cd "$(grep \^\' ~/.ranger/bookmarks | cut -b3-)"
 else
 	echo "usage: source path/to/ranger.py path/to/ranger.py"
 fi
diff --git a/ranger/__init__.py b/ranger/__init__.py
index f46a1e76..2f8b2572 100644
--- a/ranger/__init__.py
+++ b/ranger/__init__.py
@@ -20,7 +20,7 @@ import sys
 from ranger.ext.openstruct import OpenStruct
 
 __license__ = 'GPL3'
-__version__ = '1.0.4'
+__version__ = '1.1.0'
 __credits__ = 'Roman Zimbelmann'
 __author__ = 'Roman Zimbelmann'
 __maintainer__ = 'Roman Zimbelmann'
diff --git a/ranger/__main__.py b/ranger/__main__.py
index 5f525582..a03509cf 100644
--- a/ranger/__main__.py
+++ b/ranger/__main__.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 # coding=utf-8
 #
 # Copyright (C) 2009, 2010  Roman Zimbelmann <romanz@lavabit.com>
@@ -26,7 +26,7 @@ import sys
 
 def parse_arguments():
 	"""Parse the program arguments"""
-	from optparse import OptionParser
+	from optparse import OptionParser, SUPPRESS_HELP
 	from ranger import __version__, USAGE, DEFAULT_CONFDIR
 	from ranger.ext.openstruct import OpenStruct
 	parser = OptionParser(usage=USAGE, version='ranger ' + __version__)
@@ -35,7 +35,9 @@ def parse_arguments():
 			help="activate debug mode")
 	parser.add_option('-c', '--clean', action='store_true',
 			help="don't touch/require any config files. ")
-	parser.add_option('--fail-if-run', action='store_true',
+	parser.add_option('--fail-if-run', action='store_true', # COMPAT
+			help=SUPPRESS_HELP)
+	parser.add_option('--fail-unless-cd', action='store_true',
 			help="experimental: return the exit code 1 if ranger is" \
 					"used to run a file (with `ranger filename`)")
 	parser.add_option('-r', '--confdir', type='string',
@@ -50,6 +52,9 @@ def parse_arguments():
 	options, positional = parser.parse_args()
 	arg = OpenStruct(options.__dict__, targets=positional)
 	arg.confdir = os.path.expanduser(arg.confdir)
+	if arg.fail_if_run:
+		arg.fail_unless_cd = arg.fail_if_run
+		del arg['fail_if_run']
 
 	return arg
 
@@ -185,13 +190,13 @@ def main():
 			runner = Runner(logfunc=print_function)
 			load_apps(runner, ranger.arg.clean)
 			runner(files=[File(target)], mode=arg.mode, flags=arg.flags)
-			sys.exit(1 if arg.fail_if_run else 0)
+			sys.exit(1 if arg.fail_unless_cd else 0)
 		else:
 			path = target
 	else:
 		path = '.'
 
-	crash_exception = None
+	crash_traceback = None
 	try:
 		# Initialize objects
 		EnvironmentAware._assign(Environment(path))
@@ -204,25 +209,19 @@ def main():
 		fm.initialize()
 		fm.ui.initialize()
 		fm.loop()
-	except Exception as e:
-		crash_exception = e
-		if not (arg.debug or arg.clean):
-			import traceback
-			dumpname = ranger.relpath_conf('traceback')
-			traceback.print_exc(file=open(dumpname, 'w'))
+	except Exception:
+		import traceback
+		crash_traceback = traceback.format_exc()
 	finally:
-		# Finish, clean up
 		try:
 			fm.ui.destroy()
 		except (AttributeError, NameError):
 			pass
-		if crash_exception:
-			print("Fatal: " + str(crash_exception))
-			if arg.debug or arg.clean:
-				raise crash_exception
-			else:
-				print("A traceback has been saved to " + dumpname)
-				print("Please include it in a bugreport.")
+		if crash_traceback:
+			print(crash_traceback)
+			print("Ranger crashed.  " \
+					"Please report this (including the traceback) at:")
+			print("http://savannah.nongnu.org/bugs/?group=ranger&func=additem")
 
 
 if __name__ == '__main__':
diff --git a/ranger/core/environment.py b/ranger/core/environment.py
index bb6abb36..fca2168b 100644
--- a/ranger/core/environment.py
+++ b/ranger/core/environment.py
@@ -28,8 +28,8 @@ ALLOWED_CONTEXTS = ('browser', 'pager', 'embedded_pager', 'taskview',
 		'console')
 
 class Environment(SettingsAware, SignalDispatcher):
-	"""A collection of data which is relevant for more than
-	one class.
+	"""
+	A collection of data which is relevant for more than one class.
 	"""
 
 	cwd = None  # current directory
diff --git a/ranger/ext/shell_escape.py b/ranger/ext/shell_escape.py
index f8393f2a..ec9e4b12 100644
--- a/ranger/ext/shell_escape.py
+++ b/ranger/ext/shell_escape.py
@@ -14,7 +14,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 """
-A function to escape metacharacters of arguments for shell commands.
+Functions to escape metacharacters of arguments for shell commands.
 """
 
 META_CHARS = (' ', "'", '"', '`', '&', '|', ';',
diff --git a/ranger/fsobject/file.py b/ranger/fsobject/file.py
index cd5b37ff..216b4754 100644
--- a/ranger/fsobject/file.py
+++ b/ranger/fsobject/file.py
@@ -87,6 +87,8 @@ class File(FileSystemObject):
 			return True
 		if PREVIEW_BLACKLIST.search(self.basename):
 			return False
+		if self.path == '/dev/core' or self.path == '/proc/kcore':
+			return False
 		if self.is_binary():
 			return False
 		return True
diff --git a/ranger/fsobject/fsobject.py b/ranger/fsobject/fsobject.py
index 865698b3..4ca5a6c8 100644
--- a/ranger/fsobject/fsobject.py
+++ b/ranger/fsobject/fsobject.py
@@ -107,7 +107,10 @@ class FileSystemObject(MimeTypeAware, FileManagerAware):
 
 	def set_mimetype(self):
 		"""assign attributes such as self.video according to the mimetype"""
-		self._mimetype = self.mimetypes.guess_type(self.basename, False)[0]
+		basename = self.basename
+		if self.extension == 'part':
+			basename = basename[0:-5]
+		self._mimetype = self.mimetypes.guess_type(basename, False)[0]
 		if self._mimetype is None:
 			self._mimetype = ''
 
diff --git a/ranger/gui/widgets/console.py b/ranger/gui/widgets/console.py
index 3bb41482..1ee7ebc0 100644
--- a/ranger/gui/widgets/console.py
+++ b/ranger/gui/widgets/console.py
@@ -66,7 +66,11 @@ class Console(Widget):
 		self.clear()
 		self.histories = []
 		# load histories from files
-		if not ranger.arg.clean:
+		if ranger.arg.clean:
+			for i in range(4):
+				self.histories.append(
+						History(self.settings.max_console_history_size))
+		else:
 			self.historypaths = [relpath_conf(x) for x in \
 				('history', 'history_search', 'history_qopen', 'history_open')]
 			for i, path in enumerate(self.historypaths):
diff --git a/ranger/gui/widgets/taskview.py b/ranger/gui/widgets/taskview.py
index 475b903c..e988b08c 100644
--- a/ranger/gui/widgets/taskview.py
+++ b/ranger/gui/widgets/taskview.py
@@ -86,7 +86,8 @@ class TaskView(Widget, Accumulator):
 		if i is None:
 			i = self.pointer
 
-		self.fm.loader.remove(index=i)
+		if self.fm.loader.queue:
+			self.fm.loader.remove(index=i)
 
 	def task_move(self, to, i=None):
 		if i is None:
diff --git a/ranger/help/index.py b/ranger/help/index.py
index 316e975f..1245da64 100644
--- a/ranger/help/index.py
+++ b/ranger/help/index.py
@@ -18,8 +18,8 @@
                                                                      k
     Move around:  Use the cursor keys, or "h" to go left,          h   l
                   "j" to go down, "k" to go up, "l" to go right.     j
-   Close Ranger:  Use ":q<Enter>" or "Q".
-  Specific help:  Type the help key "?" prepended with a number:
+   Close Ranger:  Type "Q"
+  Specific help:  Type "?", prepended with a number:
 
 	|0?|	This index
 	|1?|	Basic movement and browsing
diff --git a/ranger/help/invocation.py b/ranger/help/invocation.py
index 3de574cc..26cffd4a 100644
--- a/ranger/help/invocation.py
+++ b/ranger/help/invocation.py
@@ -43,9 +43,10 @@ command line.
       This is useful when your configuration is broken, when you want
       to avoid clutter, etc.
 
---fail-if-run
+--fail-unless-cd
       Return the exit code 1 if ranger is used to run a file, for example
-      with `ranger --fail-if-run filename`.  This can be useful for scripts.
+      with `ranger --fail-unless-cd filename`.  This can be useful for scripts.
+      (This option used to be called --fail-if-run)
 
 -r <dir>, --confdir=<dir>
       Define a different configuration directory.  The default is
@@ -69,7 +70,7 @@ command line.
 Examples:
       ranger episode1.avi
       ranger --debug /usr/bin
-      ranger --confdir=~/.config/ranger --fail-if-run
+      ranger --confdir=~/.config/ranger --fail-unless-cd
 
 
 ==============================================================================
@@ -95,7 +96,7 @@ docstrings.  Use this option if you don't need the documentation.
 Examples:
       PYTHONOPTIMIZE=1 ranger episode1.avi
       PYTHONOPTIMIZE=2 ranger --debug /usr/bin
-      python -OO `which ranger` --confdir=~/.config/ranger --fail-if-run
+      python -OO `which ranger` --confdir=~/.config/ranger --fail-unless-cd
 
 Note: The author expected "-OO" to reduce the memory usage, but that
 doesn't seem to happen.
diff --git a/test/__init__.py b/test/__init__.py
index d87d1fc2..e69de29b 100644
--- a/test/__init__.py
+++ b/test/__init__.py
@@ -1,52 +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/>.
-
-import os, sys
-
-__all__ = [ x[0:x.index('.')] \
-		for x in os.listdir(os.path.dirname(__file__)) \
-		if x.startswith('tc_') or x.startswith('bm_')]
-
-def TODO(fnc):
-	def result(*arg, **kw):
-		try:
-			fnc(*arg, **kw)
-		except:
-			pass # failure expected
-	return result
-
-def init():
-	sys.path.append(os.path.abspath(os.path.join(sys.path[0], '..')))
-
-class Fake(object):
-	def __getattr__(self, attrname):
-		val = Fake()
-		self.__dict__[attrname] = val
-		return val
-
-	def __call__(self, *_, **__):
-		return Fake()
-
-	def __clear__(self):
-		self.__dict__.clear()
-
-	def __iter__(self):
-		return iter(())
-
-class OK(Exception):
-	pass
-
-def raise_ok(*_, **__):
-	raise OK()
diff --git a/test/all_benchmarks.py b/test/all_benchmarks.py
new file mode 100755
index 00000000..e1b47142
--- /dev/null
+++ b/test/all_benchmarks.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+# 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/>.
+
+"""
+Run all the benchmarks inside this directory.
+Usage: ./all_benchmarks.py [count] [regexp-filters...]
+"""
+
+import os
+import re
+import sys
+import time
+
+if __name__ == '__main__':
+	count   = int(sys.argv[1]) if len(sys.argv) > 1 else 10
+	regexes = [re.compile(fltr) for fltr in sys.argv[2:]]
+	modules = (fname[:-3] for fname in os.listdir(sys.path[0]) \
+			if fname[:3] == 'bm_' and fname[-3:] == '.py')
+
+	benchmarks = []  # find all benchmark (class, methodname) pairs
+	for val in [__import__(module) for module in modules]:
+		for cls in vars(val).values():
+			if type(cls) == type:
+				for methodname in vars(cls):
+					if methodname.startswith('bm_'):
+						benchmarks.append((cls, methodname))
+
+	for cls, methodname in benchmarks:
+		full_method_name = "{0}.{1}".format(cls.__name__, methodname)
+		if all(re.search(full_method_name) for re in regexes):
+			method = getattr(cls(), methodname)
+			t1 = time.time()
+			try:
+				method(count)
+			except:
+				print("{0} failed!".format(full_method_name))
+				raise
+			else:
+				t2 = time.time()
+				print("{0:60}: {1:10}s".format(full_method_name, t2 - t1))
diff --git a/all_tests.py b/test/all_tests.py
index 90926918..7cfc855f 100755
--- a/all_tests.py
+++ b/test/all_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 # Copyright (C) 2009, 2010  Roman Zimbelmann <romanz@lavabit.com>
 #
 # This program is free software: you can redistribute it and/or modify
@@ -14,23 +14,20 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-"""Run all the tests inside the test/ directory as a test suite."""
-if __name__ == '__main__':
-	import unittest
-	from test import *
-	from sys import exit, argv
-
-	try:
-		verbosity = int(argv[1])
-	except IndexError:
-		verbosity = 2
+"""
+Run all the tests inside this directory as a test suite.
+Usage: ./all_tests.py [verbosity]
+"""
 
-	tests = []
-	for key, val in vars().copy().items():
-		if key.startswith('tc_'):
-			tests.extend(v for k,v in vars(val).items() if type(v) == type)
+import os
+import sys
+import unittest
 
-	suite = unittest.TestSuite(map(unittest.makeSuite, tests))
-	result = unittest.TextTestRunner(verbosity=verbosity).run(suite)
-	if len(result.errors) + len(result.failures) > 0:
-		exit(1)
+if __name__ == '__main__':
+	verbosity = int(sys.argv[1]) if len(sys.argv) > 1 else 1
+	tests     = (fname[:-3] for fname in os.listdir(sys.path[0]) \
+	             if fname[:3] == 'tc_' and fname[-3:] == '.py')
+	suite     = unittest.TestLoader().loadTestsFromNames(tests)
+	result    = unittest.TextTestRunner(verbosity=verbosity).run(suite)
+	if len(result.errors + result.failures) > 0:
+		sys.exit(1)
diff --git a/test/bm_loader.py b/test/bm_loader.py
index 745e6f3b..968640a5 100644
--- a/test/bm_loader.py
+++ b/test/bm_loader.py
@@ -18,7 +18,7 @@ from ranger.fsobject import Directory, File
 from ranger.ext.openstruct import OpenStruct
 import os.path
 from ranger.shared import FileManagerAware, SettingsAware
-from test import Fake
+from testlib import Fake
 from os.path import realpath, join, dirname
 from subprocess import Popen, PIPE
 TESTDIR = realpath(join(dirname(__file__), '/usr/include'))
diff --git a/test/ranger b/test/ranger
new file mode 120000
index 00000000..5459458c
--- /dev/null
+++ b/test/ranger
@@ -0,0 +1 @@
+../ranger
\ No newline at end of file
diff --git a/test/tc_bookmarks.py b/test/tc_bookmarks.py
index f45ba061..9b41f1c6 100644
--- a/test/tc_bookmarks.py
+++ b/test/tc_bookmarks.py
@@ -13,8 +13,6 @@
 # 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()
-
 from os.path import realpath, join, dirname
 import unittest
 import os
diff --git a/test/tc_colorscheme.py b/test/tc_colorscheme.py
index dbaac1f9..8d6adee6 100644
--- a/test/tc_colorscheme.py
+++ b/test/tc_colorscheme.py
@@ -13,8 +13,6 @@
 # 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()
-
 from unittest import TestCase, main
 import random
 import ranger.colorschemes
diff --git a/test/tc_direction.py b/test/tc_direction.py
index f45b4b36..5c1776cf 100644
--- a/test/tc_direction.py
+++ b/test/tc_direction.py
@@ -13,8 +13,6 @@
 # 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
diff --git a/test/tc_directory.py b/test/tc_directory.py
index 024ebc9d..a702c4db 100644
--- a/test/tc_directory.py
+++ b/test/tc_directory.py
@@ -13,8 +13,6 @@
 # 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 sys
 from os.path import realpath, join, dirname
 
diff --git a/test/tc_displayable.py b/test/tc_displayable.py
index 50f37845..1c66a40e 100644
--- a/test/tc_displayable.py
+++ b/test/tc_displayable.py
@@ -13,14 +13,12 @@
 # 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 curses
 from random import randint
 
 from ranger.gui.displayable import Displayable, DisplayableContainer
-from test import Fake, OK, raise_ok, TODO
+from testlib import Fake, OK, raise_ok, TODO
 
 class TestWithFakeCurses(unittest.TestCase):
 	def setUp(self):
diff --git a/test/tc_ext.py b/test/tc_ext.py
index b8094233..919f35a2 100644
--- a/test/tc_ext.py
+++ b/test/tc_ext.py
@@ -13,7 +13,6 @@
 # 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 collections import deque
 
diff --git a/test/tc_history.py b/test/tc_history.py
index d027231a..33784e14 100644
--- a/test/tc_history.py
+++ b/test/tc_history.py
@@ -13,8 +13,6 @@
 # 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()
-
 from ranger.container import History
 from unittest import TestCase, main
 import unittest
diff --git a/test/tc_keyapi.py b/test/tc_keyapi.py
index 2f522173..48282a7d 100644
--- a/test/tc_keyapi.py
+++ b/test/tc_keyapi.py
@@ -13,8 +13,6 @@
 # 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()
-
 from unittest import TestCase, main
 
 class Test(TestCase):
diff --git a/test/tc_loader.py b/test/tc_loader.py
index 53ac5617..9f7f7322 100644
--- a/test/tc_loader.py
+++ b/test/tc_loader.py
@@ -13,13 +13,11 @@
 # 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 os
 from os.path import realpath, join, dirname
 
-from test import Fake
+from testlib import Fake
 from ranger.shared import FileManagerAware, SettingsAware
 from ranger.core.loader import Loader
 from ranger.fsobject import Directory, File
diff --git a/test/tc_newkeys.py b/test/tc_newkeys.py
index c7a33025..fd856f17 100644
--- a/test/tc_newkeys.py
+++ b/test/tc_newkeys.py
@@ -14,10 +14,9 @@
 # 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()
 from unittest import TestCase, main
 
-from test import TODO
+from testlib import TODO
 from ranger.ext.tree import Tree
 from ranger.container.keymap import *
 from ranger.container.keybuffer import KeyBuffer
diff --git a/test/tc_signal.py b/test/tc_signal.py
index 35b4eebe..f31681f4 100644
--- a/test/tc_signal.py
+++ b/test/tc_signal.py
@@ -13,7 +13,6 @@
 # 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 *
diff --git a/test/tc_ui.py b/test/tc_ui.py
index 3c659459..dc8d669d 100644
--- a/test/tc_ui.py
+++ b/test/tc_ui.py
@@ -13,14 +13,12 @@
 # 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 curses
 
 from ranger.gui import ui
 
-from test import Fake, OK, raise_ok
+from testlib import Fake, OK, raise_ok
 
 ui.curses = Fake()
 
@@ -39,7 +37,7 @@ class Test(unittest.TestCase):
 
 	def tearDown(self):
 		self.ui.destroy()
-	
+
 	def test_passing(self):
 		# Test whether certain method calls are passed to widgets
 		widget = self.ui.widget
diff --git a/test/tc_utfwidth.py b/test/tc_utfwidth.py
index d8ffbe1d..2aa5fa6d 100644
--- a/test/tc_utfwidth.py
+++ b/test/tc_utfwidth.py
@@ -14,8 +14,6 @@
 # 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()
-
 from unittest import TestCase, main
 from ranger.ext.utfwidth import *
 
diff --git a/test/test.py b/test/testlib.py
index d0a69e5a..29dd9e07 100644
--- a/test/test.py
+++ b/test/testlib.py
@@ -13,8 +13,31 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-"""Workaround to allow running single test cases directly"""
-try:
-	from __init__ import init, Fake, OK, raise_ok, TODO
-except:
-	from test import init, Fake, OK, raise_ok, TODO
+def TODO(fnc):
+	def result(*arg, **kw):
+		try:
+			fnc(*arg, **kw)
+		except:
+			pass # failure expected
+	return result
+
+class Fake(object):
+	def __getattr__(self, attrname):
+		val = Fake()
+		self.__dict__[attrname] = val
+		return val
+
+	def __call__(self, *_, **__):
+		return Fake()
+
+	def __clear__(self):
+		self.__dict__.clear()
+
+	def __iter__(self):
+		return iter(())
+
+class OK(Exception):
+	pass
+
+def raise_ok(*_, **__):
+	raise OK()