summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--code/__init__.pycbin125 -> 0 bytes
-rw-r--r--code/defaultui.py16
-rw-r--r--code/environment.py38
-rw-r--r--code/fm.py65
-rw-r--r--code/wdisplay.py34
-rwxr-xr-xranger.py (renamed from ranger)16
-rw-r--r--ranger/__init__.py (renamed from code/__init__.py)0
-rw-r--r--ranger/cli.py32
-rw-r--r--ranger/command.py77
-rw-r--r--ranger/debug.py (renamed from code/debug.py)0
-rw-r--r--ranger/defaultui.py39
-rw-r--r--ranger/directory.py (renamed from code/directory.py)18
-rw-r--r--ranger/directory.rb (renamed from code/directory.rb)0
-rw-r--r--ranger/environment.py73
-rw-r--r--ranger/file.py (renamed from code/file.py)4
-rw-r--r--ranger/fm.py42
-rw-r--r--ranger/fsobject.py (renamed from code/fsobject.py)34
-rw-r--r--ranger/fstype.py (renamed from code/fstype.py)0
-rw-r--r--ranger/keys.py15
-rw-r--r--ranger/options.py (renamed from code/options.py)0
-rw-r--r--ranger/ui.py (renamed from code/ui.py)24
-rw-r--r--ranger/wdisplay.py51
-rw-r--r--ranger/widget.py (renamed from code/widget.py)8
-rw-r--r--ranger/wstatusbar.py12
-rw-r--r--test/dirsize_benchmark.py2
-rw-r--r--test/tc_directory.py32
-rw-r--r--test4.py36
27 files changed, 475 insertions, 193 deletions
diff --git a/code/__init__.pyc b/code/__init__.pyc
deleted file mode 100644
index 2479f90e..00000000
--- a/code/__init__.pyc
+++ /dev/null
Binary files differdiff --git a/code/defaultui.py b/code/defaultui.py
deleted file mode 100644
index d46c89c8..00000000
--- a/code/defaultui.py
+++ /dev/null
@@ -1,16 +0,0 @@
-import ui
-import widget, wdisplay
-
-class DefaultUI(ui.UI):
-	def setup(self):
-		self.main_display = wdisplay.WDisplay(self.win, 0)
-		self.add_widget(self.main_display)
-		self.left_display = wdisplay.WDisplay(self.win, -1)
-		self.add_widget(self.left_display)
-	
-	def resize(self):
-		ui.UI.resize(self)
-		y, x = self.win.getmaxyx()
-		self.main_display.setdim(1, 40, 3, 37)
-		self.left_display.setdim(1, 0, 3, 37)
-
diff --git a/code/environment.py b/code/environment.py
deleted file mode 100644
index 515fc8c6..00000000
--- a/code/environment.py
+++ /dev/null
@@ -1,38 +0,0 @@
-import directory
-
-class Vector():
-	def __init__(self, x, y):
-		self.x = x
-		self.y = y
-
-class Environment():
-	# A collection of data which is relevant for more than
-	# one class.
-	def __init__(self, opt):
-		self.opt = opt
-		self.path = None
-		self.pathway = ()
-		self.directories = {}
-		self.pwd = None # current directory
-		self.cf = None # current file
-		self.keybuffer = ''
-		self.copy = None
-		self.termsize = Vector(80, 24)
-	
-	def at_level(self, level):
-		if level <= 0:
-			try:
-				return self.pathway[level - 1]
-			except IndexError:
-				return None
-		else:
-			return self.cf
-
-	def get_directory(self, path):
-		import os
-		path = os.path.abspath(path)
-		try:
-			return self.directories[path]
-		except KeyError:
-			self.directories[path] = directory.Directory(path)
-			return self.directories[path]
diff --git a/code/fm.py b/code/fm.py
deleted file mode 100644
index 924f6efc..00000000
--- a/code/fm.py
+++ /dev/null
@@ -1,65 +0,0 @@
-import sys, os
-import ui, debug, file, directory, fstype
-
-class FM():
-	def __init__(self, environment):
-		self.env = environment
-
-	def feed(self, path, ui):
-		self.ui = ui
-		self.env.path = path
-		self.enter_dir(path)
-
-	def enter_dir(self, path):
-		# get the absolute path
-		path = os.path.normpath(os.path.join(self.env.path, path))
-
-		self.env.path = path
-		self.env.pwd = self.env.get_directory(path)
-
-		self.env.pwd.load_content()
-
-		# build the pathway, a tuple of directory objects which lie
-		# on the path to the current directory.
-		pathway = []
-		currentpath = '/'
-		for dir in path.split('/'):
-			currentpath = os.path.join(currentpath, dir)
-			debug.log(currentpath)
-			pathway.append(self.env.get_directory(currentpath))
-		self.env.pathway = tuple(pathway)
-
-		# set the current file.
-		if len(self.env.pwd) > 0:
-			self.env.cf = self.env.pwd[0]
-		else:
-			self.env.cf = None
-
-	def run(self):
-		while 1:
-			try:
-				self.ui.draw()
-			except KeyboardInterrupt:
-				self.interrupt()
-			except:
-				raise
-
-			try:
-				key = self.ui.get_next_key()
-				self.press(key)
-			except KeyboardInterrupt:
-				self.interrupt()
-
-	def press(self, key):
-		if (key == ord('q')):
-			raise SystemExit()
-		elif (key == ord('h')):
-			self.enter_dir('..')
-		elif (key == ord('l')):
-			self.enter_dir(self.env.cf.path)
-
-	def interrupt(self):
-		import time
-		self.buffer = ""
-		time.sleep(0.2)
-
diff --git a/code/wdisplay.py b/code/wdisplay.py
deleted file mode 100644
index a564a6cb..00000000
--- a/code/wdisplay.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import widget
-import curses
-import file, directory
-
-class WDisplay(widget.Widget):
-	def __init__(self, win, level):
-		widget.Widget.__init__(self,win)
-		self.level = level
-
-	def feed_env(self, env):
-		self.target = env.at_level(self.level)
-
-	def draw(self):
-		if type(self.target) == file.File:
-			self.draw_file()
-		elif type(self.target) == directory.Directory:
-			self.draw_directory()
-		elif self.target is None:
-			self.win.addnstr(self.y, self.x, "---", self.wid)
-		else:
-			self.win.addnstr(self.y, self.x, "unknown type.", self.wid)
-
-	def draw_file(self):
-		self.win.addnstr(self.y, self.x, "this is a file.", self.wid)
-
-	def draw_directory(self):
-		self.target.load_content_once()
-		for i in range(self.hei):
-			try:
-				f = self.target[i]
-			except IndexError:
-				break
-			self.win.addnstr(self.y + i, self.x, self.target[i].path, self.wid)
-
diff --git a/ranger b/ranger.py
index d83e8a3e..65388727 100755
--- a/ranger
+++ b/ranger.py
@@ -3,7 +3,8 @@
 
 # TODO: cd after exit
 
-from code import debug, fm, defaultui, options, environment
+from ranger import debug, fm, options, environment, command, keys
+from ranger.defaultui import DefaultUI as UI
 
 # TODO: find out the real name of this script and include files relative to here
 
@@ -17,18 +18,21 @@ def main():
 	locale.setlocale(locale.LC_ALL, 'en_US.utf8')
 
 	try:
-		path = '/srv/music/compilations/'
+		path = os.path.abspath('.')
 		opt = options.get()
 		env = environment.Environment(opt)
+		commandlist = command.CommandList()
+		keys.initialize_commands(commandlist)
 
-		my_ui = defaultui.DefaultUI(env)
+		my_ui = UI(env, commandlist)
 		my_fm = fm.FM(env)
 		my_fm.feed(path, my_ui)
 		my_fm.run()
 
-	except:
-		my_ui.exit()
-		raise
+	except BaseException as original_error:
+		try: my_ui.exit()
+		except: pass
 
+		raise original_error
 
 if __name__ == "__main__": main()
diff --git a/code/__init__.py b/ranger/__init__.py
index e69de29b..e69de29b 100644
--- a/code/__init__.py
+++ b/ranger/__init__.py
diff --git a/ranger/cli.py b/ranger/cli.py
new file mode 100644
index 00000000..7f8fd77f
--- /dev/null
+++ b/ranger/cli.py
@@ -0,0 +1,32 @@
+import curses
+import _thread
+
+class CLIError(): pass
+
+class CLI():
+	def __init__(self):
+		self.lock = _thread.allocalte_lock()
+		self.running = False
+
+	def start(self):
+		with self.lock:
+			stdscr = curses.initscr()
+			self.running = True
+
+	def exit(self):
+		self.stop_unless_running()
+		with self.lock:
+			self.running = False
+			curses.nocbreak()
+			stdscr.keypad(1)
+			curses.endwin()
+
+	def stop_unless_running(self):
+		if not self.running:
+			raise CLIError("This function needs the cli to be runnig!")
+
+	def print(self, text, x=0, y=0, attr=None):
+		with self.lock:
+
+	
+
diff --git a/ranger/command.py b/ranger/command.py
new file mode 100644
index 00000000..c57edba0
--- /dev/null
+++ b/ranger/command.py
@@ -0,0 +1,77 @@
+class CommandDummy():
+	pass
+
+class CommandList():
+	def __init__(self):
+		self.commandlist = []
+		self.paths = {}
+		self.dummies_in_paths = False
+		self.dummy_object = CommandDummy
+
+	def rebuild_paths(self):
+		paths = self.paths
+
+		if self.dummies_in_paths:
+			self.remove_dummies()
+		
+		for cmd in self.commandlist:
+			for key in cmd.keys:
+				path = []
+				for path in self.keypath(key):
+					try: paths[path]
+					except KeyError:
+						paths[path] = self.dummy_object
+
+		self.dummies_in_paths = True
+
+	def keypath(self, tup):
+		current = []
+		all = []
+		
+		for i in range(len(tup) - 1):
+			current.append(tup[i])
+			all.append(tuple(current))
+
+		return all
+
+	def remove_dummies(self):
+		for k in tuple(paths.keys()):
+			if paths[k] == self.dummy_object: del paths[k]
+		self.dummies_in_paths = False
+
+
+	def str_to_tuple(self, obj):
+		"""splits a string into a tuple of integers"""
+		if type(obj) == tuple:
+			return obj
+		elif type(obj) == str:
+			return tuple(map(ord, list(obj)))
+		else:
+			raise TypeError('need a str or a tuple for str_to_tuple')
+	
+	def bind(self, fnc, *keys):
+		keys = tuple(map(self.str_to_tuple, keys))
+		cmd = Command(fnc, keys)
+		cmd.commandlist = self
+		self.commandlist.append(cmd)
+		for key in keys:
+			self.paths[key] = cmd
+	
+class Command():
+	def __init__(self, fnc, keys):
+		self.fnc = fnc
+		self.keys = keys
+		self.commandlist = None
+
+#	def rebind(keys):
+#		self.keys = keys
+#		self.commandlist.rebuild_paths()
+
+	def execute(self, fm):
+		self.fnc(fm)
+
+if __name__ == '__main__':
+	cl = CommandList()
+	cl.initialize_commands()
+
+	print(cl.paths)
diff --git a/code/debug.py b/ranger/debug.py
index 12d5d654..12d5d654 100644
--- a/code/debug.py
+++ b/ranger/debug.py
diff --git a/ranger/defaultui.py b/ranger/defaultui.py
new file mode 100644
index 00000000..70ce75ff
--- /dev/null
+++ b/ranger/defaultui.py
@@ -0,0 +1,39 @@
+import ranger.ui
+from ranger.wdisplay import WDisplay
+from ranger.wstatusbar import WStatusBar
+
+class DefaultUI(ranger.ui.UI):
+	def setup(self):
+		self.statusbar = WStatusBar(self.win)
+		self.add_widget(self.statusbar)
+
+		self.displays = [
+				WDisplay(self.win, -2),
+				WDisplay(self.win, -1),
+				WDisplay(self.win, 0),
+				WDisplay(self.win, 1) ]
+		self.displays[2].display_infostring = True
+		self.displays[2].main_display = True
+		for disp in self.displays:
+			self.add_widget(disp)
+	
+	RATIO = ( 0.15, 0.15, 0.4, 0.3 )
+	
+	def resize(self):
+		ranger.ui.UI.resize(self)
+		y, x = self.win.getmaxyx()
+
+		leftborder = 0
+
+		i = 0
+		for ratio in DefaultUI.RATIO:
+			wid = int(ratio * x)
+			try:
+				self.displays[i].setdim(1, leftborder, y-1, wid - 1)
+			except KeyError:
+				pass
+			leftborder += wid
+			i += 1
+
+		self.statusbar.setdim(0, 0, 1, x)
+
diff --git a/code/directory.py b/ranger/directory.py
index 4109ae2d..392f67bc 100644
--- a/code/directory.py
+++ b/ranger/directory.py
@@ -1,9 +1,9 @@
-import fsobject
-import file, debug
+import ranger.fsobject
+from ranger import file, debug
 
-class Directory(fsobject.FSObject):
+class Directory(ranger.fsobject.FSObject):
 	def __init__(self, path):
-		fsobject.FSObject.__init__(self, path)
+		ranger.fsobject.FSObject.__init__(self, path)
 		self.content_loaded = False
 		self.scheduled = False
 		self.enterable = False
@@ -20,7 +20,7 @@ class Directory(fsobject.FSObject):
 		self.load_if_outdated()
 		self.content_loaded = True
 		import os
-		if self.exists:
+		if self.exists and self.runnable:
 			basenames = os.listdir(self.path)
 			mapped = map(lambda name: os.path.join(self.path, name), basenames)
 			self.filenames = list(mapped)
@@ -33,6 +33,10 @@ class Directory(fsobject.FSObject):
 					f = file.File(name)
 				f.load()
 				self.files.append(f)
+		else:
+			self.filenames = None
+			self.files = None
+			self.infostring = ranger.fsobject.FSObject.BAD_INFO
 	
 	def load_content_once(self):
 		self.stop_if_frozen()
@@ -55,11 +59,11 @@ class Directory(fsobject.FSObject):
 		return False
 
 	def __len__(self):
-		if not self.accessible: raise fsobject.NotLoadedYet()
+		if not self.accessible: raise ranger.fsobject.NotLoadedYet()
 		return len(self.filenames)
 	
 	def __getitem__(self, key):
-		if not self.accessible: raise fsobject.NotLoadedYet()
+		if not self.accessible: raise ranger.fsobject.NotLoadedYet()
 		return self.files[key]
 
 if __name__ == '__main__':
diff --git a/code/directory.rb b/ranger/directory.rb
index 5c6e84c1..5c6e84c1 100644
--- a/code/directory.rb
+++ b/ranger/directory.rb
diff --git a/ranger/environment.py b/ranger/environment.py
new file mode 100644
index 00000000..b5b3888c
--- /dev/null
+++ b/ranger/environment.py
@@ -0,0 +1,73 @@
+import os
+from ranger.directory import Directory
+
+class Vector():
+	def __init__(self, x, y):
+		self.x = x
+		self.y = y
+
+class Environment():
+	# A collection of data which is relevant for more than
+	# one class.
+	def __init__(self, opt):
+		self.opt = opt
+		self.path = None
+		self.pathway = ()
+		self.directories = {}
+		self.pwd = None # current directory
+		self.cf = None # current file
+		self.keybuffer = ()
+		self.copy = None
+		self.termsize = Vector(80, 24)
+
+	def key_append(self, key):
+		self.keybuffer += (key, )
+
+	def key_clear(self):
+		self.keybuffer = ()
+	
+	def at_level(self, level):
+		if level <= 0:
+			try:
+				return self.pathway[level - 1]
+			except IndexError:
+				return None
+		else:
+			return self.cf
+
+	def get_directory(self, path):
+		import os
+		path = os.path.abspath(path)
+		try:
+			return self.directories[path]
+		except KeyError:
+			self.directories[path] = Directory(path)
+			return self.directories[path]
+
+	def enter_dir(self, path):
+		# get the absolute path
+		path = os.path.normpath(os.path.join(self.path, path))
+
+		self.path = path
+		self.pwd = self.get_directory(path)
+
+		self.pwd.load_content()
+
+		# build the pathway, a tuple of directory objects which lie
+		# on the path to the current directory.
+		if path == '/':
+			self.pathway = (self.get_directory('/'), )
+		else:
+			pathway = []
+			currentpath = '/'
+			for dir in path.split('/'):
+				currentpath = os.path.join(currentpath, dir)
+#			debug.log(currentpath)
+				pathway.append(self.get_directory(currentpath))
+			self.pathway = tuple(pathway)
+
+		# set the current file.
+		if len(self.pwd) > 0:
+			self.cf = self.pwd[0]
+		else:
+			self.cf = None
diff --git a/code/file.py b/ranger/file.py
index 9d813aad..94c62f9a 100644
--- a/code/file.py
+++ b/ranger/file.py
@@ -1,5 +1,5 @@
-import fsobject
-class File(fsobject.FSObject):
+import ranger.fsobject
+class File(ranger.fsobject.FSObject):
 	pass
 #	def __init__(self, path):
 #		fsobject.FSObject.__init__(self, path)
diff --git a/ranger/fm.py b/ranger/fm.py
new file mode 100644
index 00000000..d616523e
--- /dev/null
+++ b/ranger/fm.py
@@ -0,0 +1,42 @@
+import sys
+#LOGFILE = '/tmp/errorlog'
+#f = open(LOGFILE, 'a')
+#f.write(str(tuple(sys.path)) + "\n")
+#f.close()
+#import code.ui, code.debug, code.file, code.directory, code.fstype
+
+
+class FM():
+	def __init__(self, environment):
+		self.env = environment
+
+	def feed(self, path, ui):
+		self.ui = ui
+		self.env.path = path
+		self.env.enter_dir(path)
+
+	def run(self):
+		import time
+		while 1:
+			try:
+				self.ui.draw()
+				key = self.ui.get_next_key()
+				self.ui.press(key, self)
+			except KeyboardInterrupt:
+				self.env.key_clear()
+				time.sleep(0.2)
+			except:
+				raise
+
+	def exit(self):
+		raise SystemExit()
+
+	def move_left(self):
+		self.env.enter_dir('..')
+
+	def move_right(self):
+		self.env.enter_dir(self.env.cf.path)
+
+	def move_relative(self):
+		pass
+
diff --git a/code/fsobject.py b/ranger/fsobject.py
index f4268ef0..a21818c0 100644
--- a/code/fsobject.py
+++ b/ranger/fsobject.py
@@ -1,25 +1,32 @@
-import fstype
+import ranger.fstype
 
 class FrozenException(Exception): pass
 class NotLoadedYet(Exception): pass
 
 class FSObject(object):
+	BAD_INFO = ''
 	def __init__(self, path):
 		if type(self) == FSObject:
 			raise TypeError("FSObject is an abstract class and cannot be initialized.")
+		from os.path import basename
 		self.path = path
+		self.basename = basename(path)
 		self.exists = False
 		self.accessible = False
 		self.marked = False
 		self.tagged = False
 		self.frozen = False
 		self.loaded = False
+		self.runnable = False
 		self.islink = False
 		self.brokenlink = False
 		self.stat = None
 		self.infostring = None
 		self.permissions = None
-		self.type = fstype.Unknown
+		self.type = ranger.fstype.Unknown
+	
+	def __str__(self):
+		return str(self.path)
 
 	# load() reads useful information about the file from the file system
 	# and caches it in instance attributes.
@@ -28,27 +35,36 @@ class FSObject(object):
 		self.loaded = True
 
 		import os
-		try:
+#		try:
+		if os.access(self.path, os.F_OK):
 			self.stat = os.stat(self.path)
 			self.islink = os.path.islink(self.path)
 			self.exists = True
 			self.accessible = True
 
 			if os.path.isdir(self.path):
-				self.type = fstype.Directory
-				self.infostring = ' %d' % len(os.listdir(self.path))
+				self.type = ranger.fstype.Directory
+				try:
+					self.infostring = ' %d' % len(os.listdir(self.path))
+					self.runnable = True
+				except OSError:
+					self.infostring = FSObject.BAD_INFO
+					self.runnable = False
+					self.accessible = False
 			elif os.path.isfile(self.path):
-				self.type = fstype.File
+				self.type = ranger.fstype.File
 				self.infostring = ' %d' % self.stat.st_size
 			else:
-				self.type = fstype.Unknown
+				self.type = ranger.fstype.Unknown
 				self.infostring = None
 
-		except OSError:
+		else:
+#		except OSError:
 			self.islink = False
 			self.infostring = None
-			self.type = fstype.Nonexistent
+			self.type = ranger.fstype.Nonexistent
 			self.exists = False
+			self.runnable = False
 			self.accessible = False
 
 	def load_once(self):
diff --git a/code/fstype.py b/ranger/fstype.py
index 4bd0988d..4bd0988d 100644
--- a/code/fstype.py
+++ b/ranger/fstype.py
diff --git a/ranger/keys.py b/ranger/keys.py
new file mode 100644
index 00000000..b710a2aa
--- /dev/null
+++ b/ranger/keys.py
@@ -0,0 +1,15 @@
+def initialize_commands(command_list):
+	from ranger.fm import FM
+
+	cl = command_list
+	
+	# note: the bound function will be called with one parameter, which
+	# is the FM instance. To use functions with multiple parameters, use:
+	# lambda fm: myfunction(fm, param1, param2, ...) as the function
+
+	cl.bind(FM.move_left, 'h', 'back')
+	cl.bind(FM.move_right, 'l', 'forward')
+	cl.bind(FM.exit, 'q')
+
+	cl.rebuild_paths()
+
diff --git a/code/options.py b/ranger/options.py
index eed79f1e..eed79f1e 100644
--- a/code/options.py
+++ b/ranger/options.py
diff --git a/code/ui.py b/ranger/ui.py
index d9c1de4e..6bc06b19 100644
--- a/code/ui.py
+++ b/ranger/ui.py
@@ -1,7 +1,9 @@
-import curses, debug
+import curses
+from ranger.debug import log
 class UI():
-	def __init__(self, env):
+	def __init__(self, env, commandlist):
 		self.env = env
+		self.commandlist = commandlist
 
 		self.widgets = []
 		self.win = curses.initscr()
@@ -24,17 +26,35 @@ class UI():
 	def feed_env(self, env):
 		self.env = env
 
+	def press(self, key, fm):
+		self.env.key_append(key)
+		log(self.env.keybuffer)
+
+		try:
+			cmd = self.commandlist.paths[self.env.keybuffer]
+		except KeyError:
+			self.env.key_clear()
+			return
+
+		if cmd == self.commandlist.dummy_object:
+			return
+
+		cmd.execute(fm)
+		self.env.key_clear()
+
 	def exit(self):
 		curses.nocbreak()
 		curses.echo()
 		curses.endwin()
 
 	def draw(self):
+		from ranger.debug import log
 		self.win.erase()
 		for widg in self.widgets:
 			widg.feed_env(self.env)
 			widg.draw()
 		self.win.refresh()
+		log(tuple(map(str, self.env.pathway)))
 
 #		for i in range(1, len(self.env.pwd)):
 #			f = self.env.pwd.files[i]
diff --git a/ranger/wdisplay.py b/ranger/wdisplay.py
new file mode 100644
index 00000000..4bd84044
--- /dev/null
+++ b/ranger/wdisplay.py
@@ -0,0 +1,51 @@
+import ranger.widget
+import curses
+
+class WDisplay(ranger.widget.Widget):
+	def __init__(self, win, level):
+		ranger.widget.Widget.__init__(self,win)
+		self.level = level
+		self.main_display = False
+		self.display_infostring = False
+
+	def feed_env(self, env):
+		self.target = env.at_level(self.level)
+
+	def draw(self):
+		from ranger.file import File
+		from ranger.directory import Directory
+
+		if self.target is None:
+			pass
+#			self.win.addnstr(self.y, self.x, "---", self.wid)
+		elif type(self.target) == File:
+			self.draw_file()
+		elif type(self.target) == Directory:
+			self.draw_directory()
+		else:
+			self.win.addnstr(self.y, self.x, "unknown type.", self.wid)
+
+	def draw_file(self):
+		if not self.target.accessible:
+			self.win.addnstr(self.y, self.x, "not accessible", self.wid)
+			return
+		self.win.addnstr(self.y, self.x, "this is a file.", self.wid)
+
+	def draw_directory(self):
+		self.target.load_content_once()
+		if not self.target.accessible:
+			self.win.addnstr(self.y, self.x, "not accessible", self.wid)
+			return
+		for i in range(self.hei):
+			try:
+				drawed = self.target[i]
+			except IndexError:
+				break
+			self.win.addnstr(self.y + i, self.x, drawed.basename, self.wid)
+			if self.display_infostring and drawed.infostring:
+				info = drawed.infostring
+				x = self.x + self.wid - 1 - len(info)
+				if x > self.x:
+					self.win.addstr(self.y + i, x, str(info) + ' ')
+
+
diff --git a/code/widget.py b/ranger/widget.py
index e95e6a9d..725810ec 100644
--- a/code/widget.py
+++ b/ranger/widget.py
@@ -11,8 +11,12 @@ class Widget():
 		maxy, maxx = self.win.getmaxyx()
 		wid = wid or maxx - x
 		hei = hei or maxy - y
-		if x + wid > maxx or y + hei > maxy:
-			raise OutOfBoundsException()
+		if x + wid > maxx and y + hei > maxy:
+			raise OutOfBoundsException("X and Y out of bounds!")
+		if x + wid > maxx:
+			raise OutOfBoundsException("X out of bounds!")
+		if y + hei > maxy:
+			raise OutOfBoundsException("Y out of bounds!")
 
 		self.x = x
 		self.y = y
diff --git a/ranger/wstatusbar.py b/ranger/wstatusbar.py
new file mode 100644
index 00000000..e68fb241
--- /dev/null
+++ b/ranger/wstatusbar.py
@@ -0,0 +1,12 @@
+import curses
+import ranger.widget
+
+class WStatusBar(ranger.widget.Widget):
+	def feed_env(self, env):
+		self.pathway = env.pathway
+
+	def draw(self):
+		self.win.move(self.y, self.x)
+		for path in self.pathway:
+			currentx = self.win.getyx()[1]
+			self.win.addnstr(path.basename + ' / ', (self.wid - currentx))
diff --git a/test/dirsize_benchmark.py b/test/dirsize_benchmark.py
index 38f0bfd7..5784ee80 100644
--- a/test/dirsize_benchmark.py
+++ b/test/dirsize_benchmark.py
@@ -24,3 +24,5 @@ for key in paths.keys():
 		for i in range(4):
 			assert Dirsize.__dict__[algo](key) == paths[key]
 		print("algorithm %s: %20s: %f" % (algo, key, time.time() - t))
+
+# a !!
diff --git a/test/tc_directory.py b/test/tc_directory.py
index 88c7a99e..275e3129 100644
--- a/test/tc_directory.py
+++ b/test/tc_directory.py
@@ -1,17 +1,22 @@
-import unittest
-import sys, os, time
+if __name__ == '__main__':
+	from os.path import abspath, join
+	import sys
+	sys.path.append(abspath(join(sys.path[0], '..')))
 
-sys.path.append(os.path.normpath(os.path.join(os.path.dirname(__file__), '../code')))
-import fsobject, file, directory
+from ranger import fsobject
+from ranger.file import File
+from ranger.directory import Directory
 
-TESTDIR = os.path.realpath(os.path.join(os.path.dirname(__file__), 'testdir'))
-TESTFILE = os.path.join(TESTDIR, 'testfile5234148')
+from os.path import realpath, join, dirname
+TESTDIR = realpath(join(dirname(__file__), 'testdir'))
+TESTFILE = join(TESTDIR, 'testfile5234148')
 NONEXISTANT_DIR = '/this/directory/will/most/certainly/not/exist'
 
+import unittest
 class Test1(unittest.TestCase):
 	def test_initial_condition(self):
 		# Check for the expected initial condition
-		dir = directory.Directory(TESTDIR)
+		dir = Directory(TESTDIR)
 
 		self.assertEqual(dir.path, TESTDIR)
 		self.assertFalse(dir.content_loaded)
@@ -21,8 +26,9 @@ class Test1(unittest.TestCase):
 		self.assertRaises(fsobject.NotLoadedYet, dir.__getitem__, 0)
 
 	def test_after_content_loaded(self):
+		import os
 		# Check whether the directory has the correct list of filenames.
-		dir = directory.Directory(TESTDIR)
+		dir = Directory(TESTDIR)
 		dir.load_content()
 
 		self.assertTrue(dir.exists)
@@ -41,7 +47,7 @@ class Test1(unittest.TestCase):
 		# build a file object for each file in the list assumed_filenames
 		# and find exactly one equivalent in dir.files
 		for name in assumed_filenames:
-			f = file.File(name)
+			f = File(name)
 			f.load()
 			equal = 0
 			for dirfile in dir.files:
@@ -50,7 +56,7 @@ class Test1(unittest.TestCase):
 			self.assertEqual(equal, 1)
 
 	def test_nonexistant_dir(self):
-		dir = directory.Directory(NONEXISTANT_DIR)
+		dir = Directory(NONEXISTANT_DIR)
 		dir.load_content()
 		
 		self.assertTrue(dir.content_loaded)
@@ -61,7 +67,7 @@ class Test1(unittest.TestCase):
 		self.assertRaises(fsobject.NotLoadedYet, dir.__getitem__, 0)
 
 	def test_modify_frozen_clone(self):
-		dir = directory.Directory(TESTDIR)
+		dir = Directory(TESTDIR)
 		clone = dir.frozen_clone()
 
 		# assert that their attributes are equal, except for frozen, which
@@ -79,6 +85,8 @@ class Test1(unittest.TestCase):
 		self.assertRaises(fsobject.FrozenException, clone.load_content)
 
 	def test_load_if_outdated(self):
+		import os
+		import time
 		# modify the directory. If the time between the last modification
 		# was within the filesystems resolution of mtime, we should have a re-load.
 
@@ -89,7 +97,7 @@ class Test1(unittest.TestCase):
 		def mtime():
 			return os.stat(TESTDIR).st_mtime
 
-		dir = directory.Directory(TESTDIR)
+		dir = Directory(TESTDIR)
 		dir.load()
 
 		# If the modification happens to be in the same second as the
diff --git a/test4.py b/test4.py
new file mode 100644
index 00000000..b2390a03
--- /dev/null
+++ b/test4.py
@@ -0,0 +1,36 @@
+import random, time
+
+class DelValue():
+	def a(d):
+		return dict((k, v) for k, v in d.items() if v is not 0)
+
+	def b(d):
+		for k, v in d.copy().items():
+			if v == 0: del d[k]
+		return d
+
+	def c(d):
+		for k in tuple(d.keys()):
+			if d[k] == 0: del d[k]
+		return d
+
+	def d(d):
+		for k, v in tuple(d.items()):
+			if v == 0: del d[k]
+		return d
+
+
+basedict = {}
+for i in range(200):
+	basedict[i] = random.randint(0, 1)
+
+expected = DelValue.a(basedict.copy())
+
+for algo in ['a', 'b', 'c', 'd']:
+	copy = basedict.copy()
+	t = time.time()
+	for i in range(100):
+		assert DelValue.__dict__[algo](copy) == expected
+	print("algorithm %s: %f" % (algo, time.time() - t))
+
+# c it is, although b is faster with smaller dictionaries