summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--doc/HACKING2
-rw-r--r--doc/examples/vim_file_chooser.vim37
-rw-r--r--doc/ranger.pod10
-rwxr-xr-xdoc/tools/print_colors.py16
-rwxr-xr-xranger.py2
-rw-r--r--ranger/__init__.py4
-rw-r--r--ranger/api/commands.py35
-rw-r--r--ranger/api/options.py2
-rw-r--r--ranger/colorschemes/default.py2
-rw-r--r--ranger/colorschemes/jungle.py2
-rw-r--r--ranger/colorschemes/snow.py2
-rw-r--r--ranger/config/commands.py5
-rw-r--r--ranger/config/rc.conf10
-rw-r--r--ranger/config/rifle.conf4
-rw-r--r--ranger/container/bookmarks.py2
-rw-r--r--ranger/container/directory.py2
-rw-r--r--ranger/container/file.py5
-rw-r--r--ranger/container/fsobject.py2
-rw-r--r--ranger/container/history.py2
-rw-r--r--ranger/container/settings.py8
-rw-r--r--ranger/container/tags.py2
-rw-r--r--ranger/core/actions.py15
-rw-r--r--ranger/core/environment.py4
-rw-r--r--ranger/core/fm.py7
-rw-r--r--ranger/core/loader.py2
-rw-r--r--ranger/core/main.py2
-rw-r--r--ranger/core/runner.py2
-rw-r--r--ranger/core/shared.py2
-rw-r--r--ranger/core/tab.py2
-rwxr-xr-xranger/data/scope.sh4
-rw-r--r--ranger/ext/accumulator.py2
-rw-r--r--ranger/ext/cached_function.py2
-rw-r--r--ranger/ext/curses_interrupt_handler.py2
-rw-r--r--ranger/ext/direction.py4
-rw-r--r--ranger/ext/get_executables.py2
-rw-r--r--ranger/ext/human_readable.py2
-rw-r--r--ranger/ext/img_display.py176
-rw-r--r--ranger/ext/iter_tools.py2
-rw-r--r--ranger/ext/keybinding_parser.py34
-rw-r--r--ranger/ext/mount_path.py2
-rw-r--r--ranger/ext/next_available_filename.py2
-rw-r--r--ranger/ext/openstruct.py2
-rw-r--r--ranger/ext/popen_forked.py2
-rw-r--r--ranger/ext/relative_symlink.py2
-rwxr-xr-xranger/ext/rifle.py2
-rw-r--r--ranger/ext/shell_escape.py2
-rw-r--r--ranger/ext/signals.py2
-rw-r--r--ranger/ext/spawn.py2
-rw-r--r--ranger/ext/widestring.py2
-rw-r--r--ranger/gui/ansi.py2
-rw-r--r--ranger/gui/bar.py2
-rw-r--r--ranger/gui/color.py16
-rw-r--r--ranger/gui/colorscheme.py2
-rw-r--r--ranger/gui/context.py2
-rw-r--r--ranger/gui/curses_shortcuts.py2
-rw-r--r--ranger/gui/displayable.py2
-rw-r--r--ranger/gui/mouse_event.py2
-rw-r--r--ranger/gui/ui.py13
-rw-r--r--ranger/gui/widgets/browsercolumn.py2
-rw-r--r--ranger/gui/widgets/browserview.py4
-rw-r--r--ranger/gui/widgets/console.py2
-rw-r--r--ranger/gui/widgets/pager.py20
-rw-r--r--ranger/gui/widgets/statusbar.py2
-rw-r--r--ranger/gui/widgets/taskview.py4
-rw-r--r--ranger/gui/widgets/titlebar.py2
-rwxr-xr-xsetup.py2
67 files changed, 337 insertions, 191 deletions
diff --git a/Makefile b/Makefile
index 358493dc..0a79142e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 NAME = ranger
@@ -14,6 +14,7 @@ SETUPOPTS ?= '--record=install_log.txt'
 DOCDIR ?= doc/pydoc
 DESTDIR ?= /
 PYOPTIMIZE ?= 1
+FILTER ?= .
 
 CWD = $(shell pwd)
 
@@ -60,7 +61,7 @@ doc: cleandoc
 	find . -name \*.html -exec sed -i 's|'$(CWD)'|../..|g' -- {} \;
 
 test:
-	@for FILE in $(shell grep -IHm 1 doctest -r ranger | cut -d: -f1); do \
+	@for FILE in $(shell grep -IHm 1 doctest -r ranger | grep $(FILTER) | cut -d: -f1); do \
 		echo "Testing $$FILE..."; \
 		RANGER_DOCTEST=1 PYTHONPATH=".:"$$PYTHONPATH ${PYTHON} $$FILE; \
 	done
diff --git a/doc/HACKING b/doc/HACKING
index c9e458ea..68a1a942 100644
--- a/doc/HACKING
+++ b/doc/HACKING
@@ -16,7 +16,7 @@ Patches
 
 Send patches, created with "git format-patch", to the email adress
 
-    hut@lavabit.com
+    hut@lepus.uberspace.de
 
 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.
diff --git a/doc/examples/vim_file_chooser.vim b/doc/examples/vim_file_chooser.vim
index 4f5fa3f2..68947d2d 100644
--- a/doc/examples/vim_file_chooser.vim
+++ b/doc/examples/vim_file_chooser.vim
@@ -2,16 +2,33 @@
 "
 " Add ranger as a file chooser in vim
 "
-" If you add this function and the key binding to the .vimrc, ranger can be
-" started using the keybinding ",r".  Once you select a file by pressing
-" enter, ranger will quit again and vim will open the selected file.
+" If you add this code to the .vimrc, ranger can be started using the command
+" ":RagerChooser" or the keybinding "<leader>r".  Once you select one or more
+" files, press enter and ranger will quit again and vim will open the selected
+" files.
 
-fun! RangerChooser()
-    exec "silent !ranger --choosefile=/tmp/chosenfile " . expand("%:p:h")
-    if filereadable('/tmp/chosenfile')
-        exec 'edit ' . system('cat /tmp/chosenfile')
-        call system('rm /tmp/chosenfile')
+function! RangeChooser()
+    let temp = tempname()
+    " The option "--choosefiles" was added in ranger 1.5.1. Use the next line
+    " with ranger 1.4.2 through 1.5.0 instead.
+    "exec 'silent !ranger --choosefile=' . shellescape(temp)
+    exec 'silent !ranger --choosefiles=' . shellescape(temp)
+    if !filereadable(temp)
+        " Nothing to read.
+        return
     endif
+    let names = readfile(temp)
+    if empty(names)
+        " Nothing to open.
+        return
+    endif
+    " Edit the first item.
+    exec 'edit ' . fnameescape(names[0])
+    " Add any remaning items to the arg list/buffer list.
+    for name in names[1:]
+        exec 'argadd ' . fnameescape(name)
+    endfor
     redraw!
-endfun
-map ,r :call RangerChooser()<CR>
+endfunction
+command! -bar RangerChooser call RangeChooser()
+nnoremap <leader>r :<C-U>RangerChooser<CR>
diff --git a/doc/ranger.pod b/doc/ranger.pod
index 713878f6..b48cdcf7 100644
--- a/doc/ranger.pod
+++ b/doc/ranger.pod
@@ -530,6 +530,11 @@ You can display the "real" cumulative size of directories by using the command
 will not be updated automatically.  You can choose to update it automatically
 though by turning on this option.
 
+=item cd_bookmarks [bool]
+
+Specify whether bookmarks should be included in the tab completion of the "cd"
+command.
+
 =item collapse_preview [bool] <zc>
 
 When no preview is visible, should the last column be squeezed to make use of
@@ -622,6 +627,11 @@ Preview files in the preview column?
 
 Draw images inside the console with the external program w3mimgpreview?
 
+=item preview_max_size [int]
+
+Avoid previewing files that exceed a certain size, in bytes.  Use a value of 0
+to disable this feature.
+
 =item preview_script [string, none]
 
 Which script should handle generating previews?  If the file doesn't exist, or
diff --git a/doc/tools/print_colors.py b/doc/tools/print_colors.py
index ce040b33..b3eba749 100755
--- a/doc/tools/print_colors.py
+++ b/doc/tools/print_colors.py
@@ -10,10 +10,18 @@ from curses import *
 @wrapper
 def main(win):
     def print_all_colors(attr):
-        for c in range(0, curses.COLORS):
-            init_pair(c, c, -1)
-            win.addstr(str(c) + ' ', color_pair(c) | attr)
-    use_default_colors()
+        for c in range(-1, curses.COLORS):
+            try:
+                init_pair(c, c, 0)
+            except:
+                pass
+            else:
+                win.addstr(str(c) + ' ', color_pair(c) | attr)
+    start_color()
+    try:
+        use_default_colors()
+    except:
+        pass
     win.addstr("available colors: %d\n\n" % curses.COLORS)
     print_all_colors(0)
     win.addstr("\n\n")
diff --git a/ranger.py b/ranger.py
index 49a3f36d..cd0c4305 100755
--- a/ranger.py
+++ b/ranger.py
@@ -1,6 +1,6 @@
 #!/usr/bin/python -O
 # ranger - a vim-inspired file manager for the console  (coding: utf-8)
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 # =====================
diff --git a/ranger/__init__.py b/ranger/__init__.py
index 05d2f623..f6b17b10 100644
--- a/ranger/__init__.py
+++ b/ranger/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """A console file manager with VI key bindings.
@@ -15,7 +15,7 @@ import os
 __license__ = 'GPL3'
 __version__ = '1.6.1'
 __author__ = __maintainer__ = 'Roman Zimbelmann'
-__email__ = 'hut@lavabit.com'
+__email__ = 'hut@lepus.uberspace.de'
 
 # Constants
 RANGERDIR = os.path.dirname(__file__)
diff --git a/ranger/api/commands.py b/ranger/api/commands.py
index abe40be6..98b0a23a 100644
--- a/ranger/api/commands.py
+++ b/ranger/api/commands.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 # TODO: Add an optional "!" to all commands and set a flag if it's there
@@ -273,22 +273,41 @@ class Command(FileManagerAware):
         rel_dirname = dirname(rel_dest)
 
         try:
+            directory = self.fm.get_directory(abs_dest)
+
             # are we at the end of a directory?
             if rel_dest.endswith('/') or rel_dest == '':
-                _, dirnames, filenames = next(os.walk(abs_dest))
-                names = dirnames + filenames
+                if directory.content_loaded:
+                    # Take the order from the directory object
+                    names = [f.basename for f in directory.files]
+                    if self.fm.thisfile.basename in names:
+                        i = names.index(self.fm.thisfile.basename)
+                        names = names[i:] + names[:i]
+                else:
+                    # Fall back to old method with "os.walk"
+                    _, dirnames, filenames = next(os.walk(abs_dest))
+                    names = dirnames + filenames
+                    names.sort()
 
             # are we in the middle of the filename?
             else:
-                _, dirnames, filenames = next(os.walk(abs_dirname))
-                names = [name for name in (dirnames + filenames) \
-                        if name.startswith(rel_basename)]
+                if directory.content_loaded:
+                    # Take the order from the directory object
+                    names = [f.basename for f in directory.files \
+                            if f.basename.startswith(rel_basename)]
+                    if self.fm.thisfile.basename in names:
+                        i = names.index(self.fm.thisfile.basename)
+                        names = names[i:] + names[:i]
+                else:
+                    # Fall back to old method with "os.walk"
+                    _, dirnames, filenames = next(os.walk(abs_dirname))
+                    names = [name for name in (dirnames + filenames) \
+                            if name.startswith(rel_basename)]
+                    names.sort()
         except (OSError, StopIteration):
             # os.walk found nothing
             pass
         else:
-            names.sort()
-
             # no results, return None
             if len(names) == 0:
                 return
diff --git a/ranger/api/options.py b/ranger/api/options.py
index 1d90f228..3fbd3d47 100644
--- a/ranger/api/options.py
+++ b/ranger/api/options.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 # THIS WHOLE FILE IS OBSOLETE AND EXISTS FOR BACKWARDS COMPATIBILITIY
diff --git a/ranger/colorschemes/default.py b/ranger/colorschemes/default.py
index 767d370d..c32fbf1c 100644
--- a/ranger/colorschemes/default.py
+++ b/ranger/colorschemes/default.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 from ranger.gui.colorscheme import ColorScheme
diff --git a/ranger/colorschemes/jungle.py b/ranger/colorschemes/jungle.py
index 42a8465c..2b20281c 100644
--- a/ranger/colorschemes/jungle.py
+++ b/ranger/colorschemes/jungle.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 from ranger.gui.color import *
diff --git a/ranger/colorschemes/snow.py b/ranger/colorschemes/snow.py
index b2da0a39..1507c20f 100644
--- a/ranger/colorschemes/snow.py
+++ b/ranger/colorschemes/snow.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 from ranger.gui.colorscheme import ColorScheme
diff --git a/ranger/config/commands.py b/ranger/config/commands.py
index e4415b64..68714009 100644
--- a/ranger/config/commands.py
+++ b/ranger/config/commands.py
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This configuration file is licensed under the same terms as ranger.
 # ===================================================================
 # This file contains ranger's commands.
@@ -154,7 +154,8 @@ class cd(Command):
             pass
         else:
             dirnames.sort()
-            dirnames = bookmarks + dirnames
+            if self.fm.settings.cd_bookmarks:
+                dirnames = bookmarks + dirnames
 
             # no results, return None
             if len(dirnames) == 0:
diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf
index e7b19cf6..e5d68926 100644
--- a/ranger/config/rc.conf
+++ b/ranger/config/rc.conf
@@ -156,6 +156,13 @@ set sort_directories_first true
 # (Especially on xterm)
 set xterm_alt_key false
 
+# Whether to include bookmarks in cd command
+set cd_bookmarks true
+
+# Avoid previewing files larger than this size, in bytes.  Use a value of 0 to
+# disable this feature.
+set preview_max_size 0
+
 # ===================================================================
 # == Local Options
 # ===================================================================
@@ -171,11 +178,12 @@ set xterm_alt_key false
 alias e    edit
 alias q    quit
 alias q!   quitall
+alias qa   quitall
 alias qall quitall
 alias setl setlocal
 
 alias filter     scout -prt
-alias find       scout -aet
+alias find       scout -aeit
 alias mark       scout -mr
 alias unmark     scout -Mr
 alias search     scout -rs
diff --git a/ranger/config/rifle.conf b/ranger/config/rifle.conf
index 9e29062a..364d7c28 100644
--- a/ranger/config/rifle.conf
+++ b/ranger/config/rifle.conf
@@ -104,6 +104,7 @@ ext php = php -- "$1"
 #-------------------------------------------
 mime ^audio|ogg$, terminal, has mplayer  = mplayer -- "$@"
 mime ^audio|ogg$, terminal, has mplayer2 = mplayer2 -- "$@"
+mime ^audio|ogg$, terminal, has mpv      = mpv -- "$@"
 ext midi?,        terminal, has wildmidi = wildmidi -- "$@"
 
 #--------------------------------------------
@@ -111,6 +112,8 @@ ext midi?,        terminal, has wildmidi = wildmidi -- "$@"
 #-------------------------------------------
 mime ^video|audio, has gmplayer, X, flag f = gmplayer -- "$@"
 mime ^video|audio, has smplayer, X, flag f = smplayer "$@"
+mime ^video,       has mpv,      X, flag f = mpv -- "$@"
+mime ^video,       has mpv,      X, flag f = mpv --fs -- "$@"
 mime ^video,       has mplayer2, X, flag f = mplayer2 -- "$@"
 mime ^video,       has mplayer2, X, flag f = mplayer2 -fs -- "$@"
 mime ^video,       has mplayer,  X, flag f = mplayer -- "$@"
@@ -122,6 +125,7 @@ mime ^video|audio, has totem,    X, flag f = totem --fullscreen -- "$@"
 #--------------------------------------------
 # Video without X:
 #-------------------------------------------
+mime ^video, terminal, !X, has mpv       = mpv -- "$@"
 mime ^video, terminal, !X, has mplayer2  = mplayer2 -- "$@"
 mime ^video, terminal, !X, has mplayer   = mplayer -- "$@"
 
diff --git a/ranger/container/bookmarks.py b/ranger/container/bookmarks.py
index 8fcda0b1..912f3f3a 100644
--- a/ranger/container/bookmarks.py
+++ b/ranger/container/bookmarks.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 import string
diff --git a/ranger/container/directory.py b/ranger/container/directory.py
index 21234186..b63907db 100644
--- a/ranger/container/directory.py
+++ b/ranger/container/directory.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 import os.path
diff --git a/ranger/container/file.py b/ranger/container/file.py
index a404ef91..b1245647 100644
--- a/ranger/container/file.py
+++ b/ranger/container/file.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 import re
@@ -68,6 +68,9 @@ class File(FileSystemObject):
             return False
         if not self.accessible:
             return False
+        if self.fm.settings.preview_max_size and \
+                self.size > self.fm.settings.preview_max_size:
+            return False
         if self.fm.settings.preview_script and \
                 self.fm.settings.use_preview_script:
             return True
diff --git a/ranger/container/fsobject.py b/ranger/container/fsobject.py
index 01f9348b..86730fae 100644
--- a/ranger/container/fsobject.py
+++ b/ranger/container/fsobject.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 CONTAINER_EXTENSIONS = ('7z', 'ace', 'ar', 'arc', 'bz', 'bz2', 'cab', 'cpio',
diff --git a/ranger/container/history.py b/ranger/container/history.py
index 1bc15a53..432ee827 100644
--- a/ranger/container/history.py
+++ b/ranger/container/history.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 # TODO: rewrite to use deque instead of list
diff --git a/ranger/container/settings.py b/ranger/container/settings.py
index 75d74fd6..44bd60e0 100644
--- a/ranger/container/settings.py
+++ b/ranger/container/settings.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 from inspect import isfunction
@@ -11,6 +11,7 @@ import os.path
 ALLOWED_SETTINGS = {
     'autosave_bookmarks': bool,
     'autoupdate_cumulative_size': bool,
+    'cd_bookmarks': bool,
     'collapse_preview': bool,
     'colorscheme': str,
     'column_ratios': (tuple, list),
@@ -26,10 +27,12 @@ ALLOWED_SETTINGS = {
     'max_console_history_size': (int, type(None)),
     'max_history_size': (int, type(None)),
     'mouse_enabled': bool,
+    'open_all_images': bool,
     'padding_right': bool,
     'preview_directories': bool,
     'preview_files': bool,
     'preview_images': bool,
+    'preview_max_size': int,
     'preview_script': (str, type(None)),
     'save_console_history': bool,
     'scroll_offset': int,
@@ -42,16 +45,15 @@ ALLOWED_SETTINGS = {
     'sort_reverse': bool,
     'sort': str,
     'status_bar_on_top': bool,
-    'open_all_images': bool,
     'tilde_in_titlebar': bool,
     'unicode_ellipsis': bool,
     'update_title': bool,
     'update_tmux_title': bool,
     'use_preview_script': bool,
     'vcs_aware': bool,
+    'vcs_backend_bzr': str,
     'vcs_backend_git': str,
     'vcs_backend_hg': str,
-    'vcs_backend_bzr': str,
     'xterm_alt_key': bool,
 }
 
diff --git a/ranger/container/tags.py b/ranger/container/tags.py
index b9362611..c63c61a0 100644
--- a/ranger/container/tags.py
+++ b/ranger/container/tags.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 # TODO: add a __getitem__ method to get the tag of a file
diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index 2dfb116e..08b998eb 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 import codecs
@@ -99,9 +99,11 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
             return value.split(',')
         raise ValueError("Invalid value `%s' for option `%s'!" % (name, value))
 
-    def toggle_visual_mode(self, reverse=False):
+    def toggle_visual_mode(self, reverse=False, narg=None):
         if self.mode == 'normal':
             self._visual_reverse = reverse
+            if narg != None:
+                self.mark_files(val=not reverse, narg=narg)
             self.change_mode('visual')
         else:
             self.change_mode('normal')
@@ -287,7 +289,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
     def source(self, filename):
         filename = os.path.expanduser(filename)
         for line in open(filename, 'r'):
-            line = line.rstrip("\r\n")
+            line = line.lstrip().rstrip("\r\n")
             if line.startswith("#") or not line.strip():
                 continue
             try:
@@ -540,7 +542,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
         except:
             pass
 
-    def mark_files(self, all=False, toggle=False, val=None, movedown=None, narg=1):
+    def mark_files(self, all=False, toggle=False, val=None, movedown=None, narg=None):
         """A wrapper for the directory.mark_xyz functions.
 
         Arguments:
@@ -563,6 +565,11 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware):
         if val is None and toggle is False:
             return
 
+        if narg == None:
+            narg = 1
+        else:
+            all = False
+
         if all:
             if toggle:
                 cwd.toggle_all_marks()
diff --git a/ranger/core/environment.py b/ranger/core/environment.py
index 56bed156..562212d4 100644
--- a/ranger/core/environment.py
+++ b/ranger/core/environment.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 # THIS WHOLE FILE IS OBSOLETE AND EXISTS FOR BACKWARDS COMPATIBILITIY
@@ -108,4 +108,4 @@ class Environment(SettingsAware, FileManagerAware, SignalDispatcher):
 
     def get_free_space(self, path):
         stat = os.statvfs(path)
-        return stat.f_bavail * stat.f_bsize
+        return stat.f_bavail * stat.f_frsize
diff --git a/ranger/core/fm.py b/ranger/core/fm.py
index 452a9d42..2a9ce315 100644
--- a/ranger/core/fm.py
+++ b/ranger/core/fm.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """The File Manager, putting the pieces together"""
@@ -19,6 +19,7 @@ from ranger.container.tags import Tags
 from ranger.gui.ui import UI
 from ranger.container.bookmarks import Bookmarks
 from ranger.core.runner import Runner
+from ranger.ext.img_display import ImageDisplayer
 from ranger.ext.rifle import Rifle
 from ranger.container.directory import Directory
 from ranger.ext.signals import SignalDispatcher
@@ -47,6 +48,7 @@ class FM(Actions, SignalDispatcher):
         self.start_paths = paths
         self.directories = dict()
         self.log = deque(maxlen=20)
+        self.image_displayer = ImageDisplayer()
         self.bookmarks = bookmarks
         self.current_tab = 1
         self.tabs = {}
@@ -311,6 +313,8 @@ class FM(Actions, SignalDispatcher):
 
                 ui.set_load_mode(not loader.paused and loader.has_work())
 
+                ui.draw_images()
+
                 ui.handle_input()
 
                 if zombies:
@@ -329,6 +333,7 @@ class FM(Actions, SignalDispatcher):
             raise SystemExit
 
         finally:
+            self.image_displayer.quit()
             if ranger.arg.choosedir and self.thisdir and self.thisdir.path:
                 # XXX: UnicodeEncodeError: 'utf-8' codec can't encode character
                 # '\udcf6' in position 42: surrogates not allowed
diff --git a/ranger/core/loader.py b/ranger/core/loader.py
index 73b3fb5a..ac63dcc9 100644
--- a/ranger/core/loader.py
+++ b/ranger/core/loader.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 from collections import deque
diff --git a/ranger/core/main.py b/ranger/core/main.py
index 631209cd..b0ae4a26 100644
--- a/ranger/core/main.py
+++ b/ranger/core/main.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """The main function responsible to initialize the FM object and stuff."""
diff --git a/ranger/core/runner.py b/ranger/core/runner.py
index d449f540..9066f234 100644
--- a/ranger/core/runner.py
+++ b/ranger/core/runner.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """This module is an abstract layer over subprocess.Popen
diff --git a/ranger/core/shared.py b/ranger/core/shared.py
index 23f1cc24..759d062b 100644
--- a/ranger/core/shared.py
+++ b/ranger/core/shared.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """Shared objects contain singletons for shared use."""
diff --git a/ranger/core/tab.py b/ranger/core/tab.py
index 248694fb..2bb85733 100644
--- a/ranger/core/tab.py
+++ b/ranger/core/tab.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 import os
diff --git a/ranger/data/scope.sh b/ranger/data/scope.sh
index 6659b76e..ce9ee574 100755
--- a/ranger/data/scope.sh
+++ b/ranger/data/scope.sh
@@ -28,7 +28,7 @@ maxln=200    # Stop after $maxln lines.  Can be used like ls | head -n $maxln
 
 # Find out something about the file:
 mimetype=$(file --mime-type -Lb "$path")
-extension=$(echo "${path##*.}" | tr "[:upper:]" "[:lower:]")
+extension=$(/bin/echo -E "${path##*.}" | tr "[:upper:]" "[:lower:]")
 
 # Functions:
 # runs a command and saves its output into $output.  Useful if you need
@@ -36,7 +36,7 @@ extension=$(echo "${path##*.}" | tr "[:upper:]" "[:lower:]")
 try() { output=$(eval '"$@"'); }
 
 # writes the output of the previously used "try" command
-dump() { echo "$output"; }
+dump() { /bin/echo -E "$output"; }
 
 # a common post-processing function used after most commands
 trim() { head -n "$maxln"; }
diff --git a/ranger/ext/accumulator.py b/ranger/ext/accumulator.py
index 75fec352..a4e342aa 100644
--- a/ranger/ext/accumulator.py
+++ b/ranger/ext/accumulator.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 from ranger.ext.direction import Direction
diff --git a/ranger/ext/cached_function.py b/ranger/ext/cached_function.py
index daee6397..4ee95ac0 100644
--- a/ranger/ext/cached_function.py
+++ b/ranger/ext/cached_function.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2012-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 def cached_function(fnc):
diff --git a/ranger/ext/curses_interrupt_handler.py b/ranger/ext/curses_interrupt_handler.py
index 2d453f4a..e880a6c1 100644
--- a/ranger/ext/curses_interrupt_handler.py
+++ b/ranger/ext/curses_interrupt_handler.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """Interrupt Signal handler for curses
diff --git a/ranger/ext/direction.py b/ranger/ext/direction.py
index 6630ca63..d6b465cd 100644
--- a/ranger/ext/direction.py
+++ b/ranger/ext/direction.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """This class provides convenient methods for movement operations.
@@ -130,7 +130,7 @@ class Direction(dict):
 
     def select(self, lst, current, pagesize, override=None, offset=1):
         dest = self.move(direction=self.down(), override=override,
-            current=current, pagesize=pagesize, minimum=0, maximum=len(lst))
+            current=current, pagesize=pagesize, minimum=0, maximum=len(lst)+1)
         selection = lst[min(current, dest):max(current, dest) + offset]
         return dest + offset - 1, selection
 
diff --git a/ranger/ext/get_executables.py b/ranger/ext/get_executables.py
index 76b5140e..bd87607e 100644
--- a/ranger/ext/get_executables.py
+++ b/ranger/ext/get_executables.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 from stat import S_IXOTH, S_IFREG
diff --git a/ranger/ext/human_readable.py b/ranger/ext/human_readable.py
index 96f8bda4..975aa28a 100644
--- a/ranger/ext/human_readable.py
+++ b/ranger/ext/human_readable.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 def human_readable(byte, separator=' '):
diff --git a/ranger/ext/img_display.py b/ranger/ext/img_display.py
index b6f59f4f..d470fb24 100644
--- a/ranger/ext/img_display.py
+++ b/ranger/ext/img_display.py
@@ -10,7 +10,12 @@ framebuffer) or in a Xorg session.
 w3m need to be installed for this to work.
 """
 
-import termios, fcntl, struct, sys, os
+import fcntl
+import os
+import select
+import struct
+import sys
+import termios
 from subprocess import Popen, PIPE
 
 W3MIMGDISPLAY_PATH = '/usr/lib/w3m/w3mimgdisplay'
@@ -19,6 +24,91 @@ W3MIMGDISPLAY_OPTIONS = []
 class ImgDisplayUnsupportedException(Exception):
     pass
 
+
+class ImageDisplayer(object):
+    is_initialized = False
+
+    def initialize(self):
+        """start w3mimgdisplay"""
+        self.is_initialized = True
+        self.binary_path = os.environ.get("W3MIMGDISPLAY_PATH", None)
+        if not self.binary_path:
+            self.binary_path = W3MIMGDISPLAY_PATH
+        self.process = Popen([self.binary_path] + W3MIMGDISPLAY_OPTIONS,
+                stdin=PIPE, stdout=PIPE, universal_newlines=True)
+
+    def draw(self, path, start_x, start_y, width, height):
+        """Draw an image at the given coordinates."""
+        if not self.is_initialized or self.process.poll() is not None:
+            self.initialize()
+        self.process.stdin.write(self._generate_w3m_input(path, start_x,
+            start_y, width, height))
+        self.process.stdin.flush()
+        self.process.stdout.readline()
+
+    def clear(self, start_x, start_y, width, height):
+        """Clear a part of terminal display."""
+        if not self.is_initialized or self.process.poll() is not None:
+            self.initialize()
+
+        fontw, fonth = _get_font_dimensions()
+
+        cmd = "6;{x};{y};{w};{h}\n4;\n3;\n".format(
+                x = start_x * fontw,
+                y = start_y * fonth,
+                w = (width + 1) * fontw,
+                h = height * fonth)
+
+        self.process.stdin.write(cmd)
+        self.process.stdin.flush()
+        self.process.stdout.readline()
+
+    def _generate_w3m_input(self, path, start_x, start_y, max_width, max_height):
+        """Prepare the input string for w3mimgpreview
+
+        start_x, start_y, max_height and max_width specify the drawing area.
+        They are expressed in number of characters.
+        """
+        fontw, fonth = _get_font_dimensions()
+        if fontw == 0 or fonth == 0:
+            raise ImgDisplayUnsupportedException()
+
+        max_width_pixels = max_width * fontw
+        max_height_pixels = max_height * fonth
+
+        # get image size
+        cmd = "5;{}\n".format(path)
+
+        self.process.stdin.write(cmd)
+        self.process.stdin.flush()
+        output = self.process.stdout.readline().split()
+
+        if len(output) != 2:
+            raise Exception('Failed to execute w3mimgdisplay', output)
+
+        width = int(output[0])
+        height = int(output[1])
+
+        # get the maximum image size preserving ratio
+        if width > max_width_pixels:
+            height = (height * max_width_pixels) // width
+            width = max_width_pixels
+        if height > max_height_pixels:
+            width = (width * max_height_pixels) // height
+            height = max_height_pixels
+
+        return "0;1;{x};{y};{w};{h};;;;;{filename}\n4;\n3;\n".format(
+                x = start_x * fontw,
+                y = start_y * fonth,
+                w = width,
+                h = height,
+                filename = path)
+
+    def quit(self):
+        if self.is_initialized:
+            self.process.kill()
+
+
 def _get_font_dimensions():
     # Get the height and width of a character displayed in the terminal in
     # pixels.
@@ -26,77 +116,17 @@ def _get_font_dimensions():
     fd_stdout = sys.stdout.fileno()
     x = fcntl.ioctl(fd_stdout, termios.TIOCGWINSZ, s)
     rows, cols, xpixels, ypixels = struct.unpack("HHHH", x)
-
-    return (xpixels // cols), (ypixels // rows)
-
-
-def _w3mimgdisplay(commands):
-    """Invoke w3mimgdisplay and send commands on its standard input."""
-    path = os.environ.get("W3MIMGDISPLAY_PATH", None)
-    if not path:
-        path = W3MIMGDISPLAY_PATH
-    process = Popen([path] + W3MIMGDISPLAY_OPTIONS, stdin=PIPE,
+    if xpixels == 0 and ypixels == 0:
+        binary_path = os.environ.get("W3MIMGDISPLAY_PATH", None)
+        if not binary_path:
+            binary_path = W3MIMGDISPLAY_PATH
+        process = Popen([binary_path, "-test"],
             stdout=PIPE, universal_newlines=True)
+        output, _ = process.communicate()
+        output = output.split()
+        xpixels, ypixels = int(output[0]), int(output[1])
+        # adjust for misplacement
+        xpixels += 2
+        ypixels += 2
 
-    # wait for the external program to finish
-    output, _ = process.communicate(input=commands)
-
-    return output
-
-def generate_w3m_input(path, start_x, start_y, max_width, max_height):
-    """Prepare the input string for w3mimgpreview
-
-    start_x, start_y, max_height and max_width specify the drawing area.
-    They are expressed in number of characters.
-    """
-    fontw, fonth = _get_font_dimensions()
-    if fontw == 0 or fonth == 0:
-        raise ImgDisplayUnsupportedException()
-
-    max_width_pixels = max_width * fontw
-    max_height_pixels = max_height * fonth
-
-    # get image size
-    cmd = "5;{}".format(path)
-    output = _w3mimgdisplay(cmd).split()
-
-    if len(output) != 2:
-        raise Exception('Failed to execute w3mimgdisplay')
-
-    width = int(output[0])
-    height = int(output[1])
-
-    # get the maximum image size preserving ratio
-    if width > max_width_pixels:
-        height = (height * max_width_pixels) // width
-        width = max_width_pixels
-    if height > max_height_pixels:
-        width = (width * max_height_pixels) // height
-        height = max_height_pixels
-
-    return "0;1;{x};{y};{w};{h};;;;;{filename}\n4;\n3;".format(
-            x = start_x * fontw,
-            y = start_y * fonth,
-            w = width,
-            h = height,
-            filename = path)
-
-def draw(path, start_x, start_y, max_width, max_height):
-    """Draw an image file in the terminal.
-
-    start_x, start_y, max_height and max_width specify the drawing area.
-    They are expressed in number of characters.
-    """
-    _w3mimgdisplay(generate_w3m_input(path, start_x, start_y, max_width, max_height))
-
-def clear(start_x, start_y, width, height):
-    """Clear a part of terminal display."""
-    fontw, fonth = _get_font_dimensions()
-
-    cmd = "6;{x};{y};{w};{h}\n4;\n3;".format(
-            x = start_x * fontw,
-            y = start_y * fonth,
-            w = (width + 1) * fontw,
-            h = height * fonth)
-
-    _w3mimgdisplay(cmd)
+    return (xpixels // cols), (ypixels // rows)
diff --git a/ranger/ext/iter_tools.py b/ranger/ext/iter_tools.py
index eef943fd..0b0af8db 100644
--- a/ranger/ext/iter_tools.py
+++ b/ranger/ext/iter_tools.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 from collections import deque
diff --git a/ranger/ext/keybinding_parser.py b/ranger/ext/keybinding_parser.py
index 8023759b..d7b24be3 100644
--- a/ranger/ext/keybinding_parser.py
+++ b/ranger/ext/keybinding_parser.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 import sys
@@ -16,6 +16,7 @@ special_keys = {
     'backspace': curses.KEY_BACKSPACE,
     'backspace2': curses.ascii.DEL,
     'delete': curses.KEY_DC,
+    's-delete': curses.KEY_SDC,
     'insert': curses.KEY_IC,
     'cr': ord("\n"),
     'enter': ord("\n"),
@@ -62,10 +63,18 @@ reversed_special_keys = dict((v, k) for k, v in special_keys.items())
 def parse_keybinding(obj):
     """Translate a keybinding to a sequence of integers
 
-    Example:
-    lol<CR>   =>   (ord('l'), ord('o'), ord('l'), ord('\\n'))
-              =>   (108, 111, 108, 10)
-    x<A-Left> =>   (120, (27, curses.KEY_LEFT))
+    >>> tuple(parse_keybinding("lol<CR>"))
+    (108, 111, 108, 10)
+
+    >>> out = tuple(parse_keybinding("x<A-Left>"))
+    >>> out  # it's kind of dumb that you cant test for constants...
+    (120, 9003, 260)
+    >>> out[0] == ord('x')
+    True
+    >>> out[1] == ALT_KEY
+    True
+    >>> out[2] == curses.KEY_LEFT
+    True
     """
     assert isinstance(obj, (tuple, int, str))
     if isinstance(obj, tuple):
@@ -86,10 +95,13 @@ def parse_keybinding(obj):
                         for key in keys:
                             yield key
                     except KeyError:
-                        yield ord('<')
-                        for c in bracket_content:
-                            yield ord(c)
-                        yield ord('>')
+                        if string.isdigit():
+                            yield int(string)
+                        else:
+                            yield ord('<')
+                            for c in bracket_content:
+                                yield ord(c)
+                            yield ord('>')
                     except TypeError:
                         yield keys  # it was no tuple, just an int
                 else:
@@ -245,3 +257,7 @@ class KeyBuffer(object):
 
     def __str__(self):
         return "".join(key_to_string(c) for c in self.keys)
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
diff --git a/ranger/ext/mount_path.py b/ranger/ext/mount_path.py
index 9697884f..1c11139d 100644
--- a/ranger/ext/mount_path.py
+++ b/ranger/ext/mount_path.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 from os.path import realpath, abspath, dirname, ismount
diff --git a/ranger/ext/next_available_filename.py b/ranger/ext/next_available_filename.py
index 38d13e16..65c51d09 100644
--- a/ranger/ext/next_available_filename.py
+++ b/ranger/ext/next_available_filename.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2011-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2011-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 import os.path
diff --git a/ranger/ext/openstruct.py b/ranger/ext/openstruct.py
index 710a8263..aea44630 100644
--- a/ranger/ext/openstruct.py
+++ b/ranger/ext/openstruct.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 # prepend __ to arguments because one might use "args"
diff --git a/ranger/ext/popen_forked.py b/ranger/ext/popen_forked.py
index 3b13ec69..6cc931c6 100644
--- a/ranger/ext/popen_forked.py
+++ b/ranger/ext/popen_forked.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2012-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 import os
diff --git a/ranger/ext/relative_symlink.py b/ranger/ext/relative_symlink.py
index a8029880..419c044a 100644
--- a/ranger/ext/relative_symlink.py
+++ b/ranger/ext/relative_symlink.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 from os import symlink, sep
diff --git a/ranger/ext/rifle.py b/ranger/ext/rifle.py
index 054491ac..1cc2dcf8 100755
--- a/ranger/ext/rifle.py
+++ b/ranger/ext/rifle.py
@@ -1,5 +1,5 @@
 #!/usr/bin/python
-# Copyright (C) 2012-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2012-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """rifle, the file executor/opener of ranger
diff --git a/ranger/ext/shell_escape.py b/ranger/ext/shell_escape.py
index eeb3adf1..85656c4c 100644
--- a/ranger/ext/shell_escape.py
+++ b/ranger/ext/shell_escape.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """Functions to escape metacharacters of arguments for shell commands."""
diff --git a/ranger/ext/signals.py b/ranger/ext/signals.py
index 7f9d9b21..07ffc899 100644
--- a/ranger/ext/signals.py
+++ b/ranger/ext/signals.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """An efficient and minimalistic signaling/hook module.
diff --git a/ranger/ext/spawn.py b/ranger/ext/spawn.py
index 240fa94a..29ecf40e 100644
--- a/ranger/ext/spawn.py
+++ b/ranger/ext/spawn.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 from subprocess import Popen, PIPE
diff --git a/ranger/ext/widestring.py b/ranger/ext/widestring.py
index c5b26a18..e9f36fbe 100644
--- a/ranger/ext/widestring.py
+++ b/ranger/ext/widestring.py
@@ -1,5 +1,5 @@
 # -*- encoding: utf8 -*-
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 import sys
diff --git a/ranger/gui/ansi.py b/ranger/gui/ansi.py
index d2616323..fa0ed914 100644
--- a/ranger/gui/ansi.py
+++ b/ranger/gui/ansi.py
@@ -1,5 +1,5 @@
 # Copyright (C) 2010 David Barnett <davidbarnett2@gmail.com>
-# Copyright (C) 2010-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2010-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """A library to help to convert ANSI codes to curses instructions."""
diff --git a/ranger/gui/bar.py b/ranger/gui/bar.py
index 6bba85c4..7c5b834f 100644
--- a/ranger/gui/bar.py
+++ b/ranger/gui/bar.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 from ranger.ext.widestring import WideString, utf_char_width
diff --git a/ranger/gui/color.py b/ranger/gui/color.py
index b118a0af..d64b5b40 100644
--- a/ranger/gui/color.py
+++ b/ranger/gui/color.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """Contains abbreviations to curses color/attribute constants.
@@ -15,6 +15,8 @@ bool(attr & reverse) # => False
 
 import curses
 
+DEFAULT_FOREGROUND = curses.COLOR_WHITE
+DEFAULT_BACKGROUND = curses.COLOR_BLACK
 COLOR_PAIRS = {10: 0}
 
 def get_color(fg, bg):
@@ -23,7 +25,17 @@ def get_color(fg, bg):
     key = (fg, bg)
     if key not in COLOR_PAIRS:
         size = len(COLOR_PAIRS)
-        curses.init_pair(size, fg, bg)
+        try:
+            curses.init_pair(size, fg, bg)
+        except:
+            # If curses.use_default_colors() failed during the initialization
+            # of curses, then using -1 as fg or bg will fail as well, which
+            # we need to handle with fallback-defaults:
+            if fg == -1:  # -1 is the "default" color
+                fg = DEFAULT_FOREGROUND
+            if bg == -1:  # -1 is the "default" color
+                bg = DEFAULT_BACKGROUND
+            curses.init_pair(size, fg, bg)
         COLOR_PAIRS[key] = size
 
     return COLOR_PAIRS[key]
diff --git a/ranger/gui/colorscheme.py b/ranger/gui/colorscheme.py
index 0d5efc2d..f7eb22b6 100644
--- a/ranger/gui/colorscheme.py
+++ b/ranger/gui/colorscheme.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """Colorschemes define colors for specific contexts.
diff --git a/ranger/gui/context.py b/ranger/gui/context.py
index 878b7680..c335bd23 100644
--- a/ranger/gui/context.py
+++ b/ranger/gui/context.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 CONTEXT_KEYS = ['reset', 'error', 'badinfo',
diff --git a/ranger/gui/curses_shortcuts.py b/ranger/gui/curses_shortcuts.py
index 3fce7fcd..bc07f837 100644
--- a/ranger/gui/curses_shortcuts.py
+++ b/ranger/gui/curses_shortcuts.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # Copyright (C) 2010 David Barnett <davidbarnett2@gmail.com>
 # This software is distributed under the terms of the GNU GPL version 3.
 
diff --git a/ranger/gui/displayable.py b/ranger/gui/displayable.py
index 621ca9cc..6920cf92 100644
--- a/ranger/gui/displayable.py
+++ b/ranger/gui/displayable.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 from ranger.core.shared import FileManagerAware, EnvironmentAware
diff --git a/ranger/gui/mouse_event.py b/ranger/gui/mouse_event.py
index 2533cc4d..12e53477 100644
--- a/ranger/gui/mouse_event.py
+++ b/ranger/gui/mouse_event.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 import curses
diff --git a/ranger/gui/ui.py b/ranger/gui/ui.py
index 83b324e3..1f95ac59 100644
--- a/ranger/gui/ui.py
+++ b/ranger/gui/ui.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 import os
@@ -71,7 +71,10 @@ class UI(DisplayableContainer):
         except:
             pass
         curses.start_color()
-        curses.use_default_colors()
+        try:
+            curses.use_default_colors()
+        except:
+            pass
 
         self.settings.signal_bind('setopt.mouse_enabled', _setup_mouse)
         _setup_mouse(dict(value=self.settings.mouse_enabled))
@@ -310,8 +313,14 @@ class UI(DisplayableContainer):
         """Finalize every object in container and refresh the window"""
         DisplayableContainer.finalize(self)
         self.win.refresh()
+
+    def draw_images(self):
         if self.pager.visible:
             self.pager.draw_image()
+        elif self.browser.pager.visible:
+            self.browser.pager.draw_image()
+        else:
+            self.browser.columns[-1].draw_image()
 
     def close_pager(self):
         if self.console.visible:
diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py
index 14900e8b..0edb9c8d 100644
--- a/ranger/gui/widgets/browsercolumn.py
+++ b/ranger/gui/widgets/browsercolumn.py
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """The BrowserColumn widget displays the contents of a directory or file."""
diff --git a/ranger/gui/widgets/browserview.py b/ranger/gui/widgets/browserview.py
index ee846f30..1f2dd457 100644
--- a/ranger/gui/widgets/browserview.py
+++ b/ranger/gui/widgets/browserview.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """The BrowserView manages a set of BrowserColumns."""
@@ -111,7 +111,6 @@ class BrowserView(Widget, DisplayableContainer):
                 self.fm.ui.win.move(self.main_column.y, self.main_column.x)
             except:
                 pass
-            self.pager.draw_image()
         else:
             try:
                 x = self.main_column.x
@@ -120,7 +119,6 @@ class BrowserView(Widget, DisplayableContainer):
                 self.fm.ui.win.move(y, x)
             except:
                 pass
-            self.columns[-1].draw_image()
 
     def _draw_borders(self):
         win = self.win
diff --git a/ranger/gui/widgets/console.py b/ranger/gui/widgets/console.py
index 1977993c..91366e7c 100644
--- a/ranger/gui/widgets/console.py
+++ b/ranger/gui/widgets/console.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """The Console widget implements a vim-like console"""
diff --git a/ranger/gui/widgets/pager.py b/ranger/gui/widgets/pager.py
index 4a98e083..a1417cc2 100644
--- a/ranger/gui/widgets/pager.py
+++ b/ranger/gui/widgets/pager.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # Copyright (C) 2010 David Barnett <davidbarnett2@gmail.com>
 # This software is distributed under the terms of the GNU GPL version 3.
 
@@ -8,7 +8,7 @@ from . import Widget
 from ranger.core.loader import CommandLoader
 from ranger.gui import ansi
 from ranger.ext.direction import Direction
-import ranger.ext.img_display as img_display
+from ranger.ext.img_display import ImgDisplayUnsupportedException
 
 # TODO: Scrolling in embedded pager
 class Pager(Widget):
@@ -40,7 +40,7 @@ class Pager(Widget):
 
     def clear_image(self, force=False):
         if (force or self.need_clear_image) and self.image_drawn:
-            img_display.clear(self.x, self.y, self.wid, self.hei)
+            self.fm.image_displayer.clear(self.x, self.y, self.wid, self.hei)
             self.need_clear_image = False
             self.image_drawn = False
 
@@ -90,18 +90,14 @@ class Pager(Widget):
             self.source = None
             self.need_redraw_image = False
             try:
-                cmd = CommandLoader([img_display.W3MIMGDISPLAY_PATH] +
-                            img_display.W3MIMGDISPLAY_OPTIONS,
-                        input=img_display.generate_w3m_input(self.image,
-                            self.x, self.y, self.wid, self.hei),
-                        descr="loading preview image",
-                        silent=True, kill_on_pause=True)
-                self.fm.loader.add(cmd)
-                self.image_drawn = True
-            except img_display.ImgDisplayUnsupportedException:
+                self.fm.image_displayer.draw(self.image, self.x, self.y,
+                        self.wid, self.hei)
+            except ImgDisplayUnsupportedException:
                 self.fm.settings.preview_images = False
             except Exception as e:
                 self.fm.notify(e, bad=True)
+            else:
+                self.image_drawn = True
 
     def _draw_line(self, i, line):
         if self.markup is None:
diff --git a/ranger/gui/widgets/statusbar.py b/ranger/gui/widgets/statusbar.py
index ae54cf42..0b7f2d9b 100644
--- a/ranger/gui/widgets/statusbar.py
+++ b/ranger/gui/widgets/statusbar.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """The statusbar displays information about the current file and directory.
diff --git a/ranger/gui/widgets/taskview.py b/ranger/gui/widgets/taskview.py
index 9b5104ce..5d2aa475 100644
--- a/ranger/gui/widgets/taskview.py
+++ b/ranger/gui/widgets/taskview.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """The TaskView allows you to modify what the loader is doing."""
@@ -51,7 +51,7 @@ class TaskView(Widget, Accumulator):
                     descr = obj.get_description()
                     if obj.progressbar_supported and obj.percent >= 0 \
                             and obj.percent <= 100:
-                        self.addstr(y, 0, "%3d%% - %s" % \
+                        self.addstr(y, 0, "%3.2f%% - %s" % \
                                 (obj.percent, descr), self.wid)
                         wid = int(self.wid / 100.0 * obj.percent)
                         self.color_at(y, 0, self.wid, tuple(clr))
diff --git a/ranger/gui/widgets/titlebar.py b/ranger/gui/widgets/titlebar.py
index aacf0be8..38a99a92 100644
--- a/ranger/gui/widgets/titlebar.py
+++ b/ranger/gui/widgets/titlebar.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 """The titlebar is the widget at the top, giving you broad overview.
diff --git a/setup.py b/setup.py
index b9a9bd6a..84325cd9 100755
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,5 @@
 #!/usr/bin/env python
-# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lavabit.com>
+# Copyright (C) 2009-2013  Roman Zimbelmann <hut@lepus.uberspace.de>
 # This software is distributed under the terms of the GNU GPL version 3.
 
 import distutils.core