about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xranger.py2
-rw-r--r--ranger/command.py7
-rw-r--r--ranger/directory.py50
-rw-r--r--ranger/environment.py26
-rw-r--r--ranger/fm.py21
-rw-r--r--ranger/fsobject.py4
-rw-r--r--ranger/keys.py27
-rw-r--r--ranger/options.py2
-rw-r--r--ranger/ui.py20
-rw-r--r--ranger/wdisplay.py9
10 files changed, 125 insertions, 43 deletions
diff --git a/ranger.py b/ranger.py
index 65388727..cfac83c3 100755
--- a/ranger.py
+++ b/ranger.py
@@ -19,7 +19,7 @@ def main():
 
 	try:
 		path = os.path.abspath('.')
-		opt = options.get()
+		opt = options.dummy()
 		env = environment.Environment(opt)
 		commandlist = command.CommandList()
 		keys.initialize_commands(commandlist)
diff --git a/ranger/command.py b/ranger/command.py
index c57edba0..bd11dd70 100644
--- a/ranger/command.py
+++ b/ranger/command.py
@@ -42,14 +42,17 @@ class CommandList():
 
 	def str_to_tuple(self, obj):
 		"""splits a string into a tuple of integers"""
-		if type(obj) == tuple:
+		if isinstance(obj, tuple):
 			return obj
-		elif type(obj) == str:
+		elif isinstance(obj, str):
 			return tuple(map(ord, list(obj)))
+		elif isinstance(obj, int):
+			return (obj, )
 		else:
 			raise TypeError('need a str or a tuple for str_to_tuple')
 	
 	def bind(self, fnc, *keys):
+		if len(keys) == 0: return
 		keys = tuple(map(self.str_to_tuple, keys))
 		cmd = Command(fnc, keys)
 		cmd.commandlist = self
diff --git a/ranger/directory.py b/ranger/directory.py
index 392f67bc..6f468b0a 100644
--- a/ranger/directory.py
+++ b/ranger/directory.py
@@ -1,8 +1,13 @@
 import ranger.fsobject
 from ranger import file, debug
 
+class NoDirectoryGiven(Exception):
+	pass
+
 class Directory(ranger.fsobject.FSObject):
 	def __init__(self, path):
+		from os.path import isdir
+		if not isdir(path): raise NoDirectoryGiven()
 		ranger.fsobject.FSObject.__init__(self, path)
 		self.content_loaded = False
 		self.scheduled = False
@@ -14,30 +19,67 @@ class Directory(ranger.fsobject.FSObject):
 		self.pointed_index = None
 		self.pointed_file = None
 		self.index = None
+		self.show_hidden = False
+	
+	def set_filter(self, string):
+		self.filter = string
+		self.load_content()
 	
 	def load_content(self):
+		from os.path import join, isdir, basename
+		from os import listdir
+
 		self.stop_if_frozen()
 		self.load_if_outdated()
 		self.content_loaded = True
-		import os
+
 		if self.exists and self.runnable:
-			basenames = os.listdir(self.path)
-			mapped = map(lambda name: os.path.join(self.path, name), basenames)
+			basenames = listdir(self.path)
+			mapped = map(lambda name: join(self.path, name), basenames)
 			self.filenames = list(mapped)
 			self.infostring = ' %d' % len(self.filenames) # update the infostring
 			self.files = []
 			for name in self.filenames:
-				if os.path.isdir(name):
+				if isinstance(self.filter, str) and self.filter in name: continue
+				if basename(name)[0] == '.': continue
+				if isdir(name):
 					f = Directory(name)
 				else:
 					f = file.File(name)
 				f.load()
 				self.files.append(f)
+			if len(self.files) > 0:
+				self.pointed_index = 0
+				self.pointed_file = self.files[0]
 		else:
 			self.filenames = None
 			self.files = None
 			self.infostring = ranger.fsobject.FSObject.BAD_INFO
 	
+	# Notice: fm.env.cf should always point to the current file. If you
+	# modify the current directory with this function, make sure
+	# to update fm.env.cf aswell.
+	def move_pointer(self, relative=0, absolute=None):
+		i = self.pointed_index
+		if isinstance(absolute, int):
+			if absolute < 0:
+				absolute = len(self.files) + absolute
+			i = absolute
+
+		if isinstance(relative, int):
+			i += relative
+
+		self.pointed_index = i
+		self.fix_pointer()
+		return self.pointed_file
+
+	def fix_pointer(self):
+		i = self.pointed_index
+		if i >= len(self.files): i = len(self.files) - 1
+		if i < 0: i = 0
+		self.pointed_index = i
+		self.pointed_file = self[i]
+		
 	def load_content_once(self):
 		self.stop_if_frozen()
 		if not self.content_loaded:
diff --git a/ranger/environment.py b/ranger/environment.py
index b5b3888c..faa3b9dc 100644
--- a/ranger/environment.py
+++ b/ranger/environment.py
@@ -1,10 +1,5 @@
 import os
-from ranger.directory import Directory
-
-class Vector():
-	def __init__(self, x, y):
-		self.x = x
-		self.y = y
+from ranger.directory import Directory, NoDirectoryGiven
 
 class Environment():
 	# A collection of data which is relevant for more than
@@ -18,7 +13,7 @@ class Environment():
 		self.cf = None # current file
 		self.keybuffer = ()
 		self.copy = None
-		self.termsize = Vector(80, 24)
+		self.termsize = (24, 80)
 
 	def key_append(self, key):
 		self.keybuffer += (key, )
@@ -34,7 +29,7 @@ class Environment():
 				return None
 		else:
 			return self.cf
-
+	
 	def get_directory(self, path):
 		import os
 		path = os.path.abspath(path)
@@ -48,10 +43,15 @@ class Environment():
 		# get the absolute path
 		path = os.path.normpath(os.path.join(self.path, path))
 
+		try:
+			new_pwd = self.get_directory(path)
+		except NoDirectoryGiven:
+			return False
+
 		self.path = path
-		self.pwd = self.get_directory(path)
+		self.pwd = new_pwd
 
-		self.pwd.load_content()
+		self.pwd.load_content_if_outdated()
 
 		# build the pathway, a tuple of directory objects which lie
 		# on the path to the current directory.
@@ -67,7 +67,5 @@ class Environment():
 			self.pathway = tuple(pathway)
 
 		# set the current file.
-		if len(self.pwd) > 0:
-			self.cf = self.pwd[0]
-		else:
-			self.cf = None
+		self.cf = self.pwd.pointed_file
+		return True
diff --git a/ranger/fm.py b/ranger/fm.py
index d616523e..48541f0c 100644
--- a/ranger/fm.py
+++ b/ranger/fm.py
@@ -19,6 +19,7 @@ class FM():
 		import time
 		while 1:
 			try:
+				self.env.pwd.load_content_if_outdated()
 				self.ui.draw()
 				key = self.ui.get_next_key()
 				self.ui.press(key, self)
@@ -35,8 +36,22 @@ class FM():
 		self.env.enter_dir('..')
 
 	def move_right(self):
-		self.env.enter_dir(self.env.cf.path)
+		path = self.env.cf.path
+		if not self.env.enter_dir(path):
+			self.execute_file(path)
 
-	def move_relative(self):
-		pass
+	def execute_file(self, path):
+		import os
+		self.ui.exit()
+		os.system("mplayer '" + path + "'")
+		self.ui.initialize()
 
+	def move_pointer(self, relative = 0, absolute = None):
+		self.env.cf = self.env.pwd.move_pointer(relative, absolute)
+
+	def move_pointer_by_screensize(self, relative = 0):
+		self.env.cf = self.env.pwd.move_pointer(
+				relative = int(relative * self.env.termsize[0]))
+
+	def redraw(self):
+		self.ui.redraw()
diff --git a/ranger/fsobject.py b/ranger/fsobject.py
index a21818c0..7a131891 100644
--- a/ranger/fsobject.py
+++ b/ranger/fsobject.py
@@ -4,7 +4,7 @@ class FrozenException(Exception): pass
 class NotLoadedYet(Exception): pass
 
 class FSObject(object):
-	BAD_INFO = ''
+	BAD_INFO = None
 	def __init__(self, path):
 		if type(self) == FSObject:
 			raise TypeError("FSObject is an abstract class and cannot be initialized.")
@@ -35,7 +35,6 @@ class FSObject(object):
 		self.loaded = True
 
 		import os
-#		try:
 		if os.access(self.path, os.F_OK):
 			self.stat = os.stat(self.path)
 			self.islink = os.path.islink(self.path)
@@ -59,7 +58,6 @@ class FSObject(object):
 				self.infostring = None
 
 		else:
-#		except OSError:
 			self.islink = False
 			self.infostring = None
 			self.type = ranger.fstype.Nonexistent
diff --git a/ranger/keys.py b/ranger/keys.py
index b710a2aa..fe885278 100644
--- a/ranger/keys.py
+++ b/ranger/keys.py
@@ -1,15 +1,32 @@
 def initialize_commands(command_list):
 	from ranger.fm import FM
+	from curses.ascii import ctrl
 
 	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
+	# syntax for binding keys: cl.bind(fnc, *keys)
+	# fnc is a function which is called with the FM instance,
+	# keys are one or more key-combinations which are either:
+	# * a string
+	# * an integer which represents an ascii value
+	# * a tuple of integers
 
-	cl.bind(FM.move_left, 'h', 'back')
+	def move(relative = 0, absolute = None):
+		return lambda fm: fm.move_pointer(relative = relative, absolute = absolute)
+
+	def move_screens(n):
+		return lambda fm: fm.move_pointer_by_screensize(n)
+
+	cl.bind(FM.move_left, 'h', 195, 'back')
 	cl.bind(FM.move_right, 'l', 'forward')
-	cl.bind(FM.exit, 'q')
+	cl.bind(move( relative = 1 ), 'j')
+	cl.bind(move_screens( 0.5 ), 'J')
+	cl.bind(move( relative = -1 ), 'k')
+	cl.bind(move_screens( -0.5 ), 'K')
+	cl.bind(move( absolute = 0 ), 'gg')
+	cl.bind(move( absolute = -1 ), 'G')
+	cl.bind(FM.exit, 'q', ctrl('D'), 'ZZ')
+	cl.bind(FM.redraw, ctrl('L'))
 
 	cl.rebuild_paths()
 
diff --git a/ranger/options.py b/ranger/options.py
index eed79f1e..f2a7d1ae 100644
--- a/ranger/options.py
+++ b/ranger/options.py
@@ -2,4 +2,4 @@ def get():
 	return []
 
 def dummy():
-	return []
+	return { 'show hidden': False }
diff --git a/ranger/ui.py b/ranger/ui.py
index 6bc06b19..308e5e14 100644
--- a/ranger/ui.py
+++ b/ranger/ui.py
@@ -8,18 +8,28 @@ class UI():
 		self.widgets = []
 		self.win = curses.initscr()
 		self.win.leaveok(1)
-		curses.noecho()
-		curses.halfdelay(3)
+
+		self.initialize()
 
 		self.setup()
 		self.resize()
 
+	def initialize(self):
+		curses.noecho()
+		curses.halfdelay(10)
+		curses.curs_set(0)
+
 	def setup(self):
 		pass
 
 	def resize(self):
 		self.env.termsize = self.win.getmaxyx()
 
+	def redraw(self):
+		self.win.redrawwin()
+		self.win.refresh()
+		self.win.redrawwin()
+
 	def add_widget(self, widg):
 		self.widgets.append(widg)
 
@@ -54,12 +64,6 @@ class UI():
 			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]
-#			self.win.addstr(i, 0, f.path)
-#			if f.infostring: self.win.addstr(i, 50, f.infostring)
 
 	def get_next_key(self):
 		key = self.win.getch()
diff --git a/ranger/wdisplay.py b/ranger/wdisplay.py
index 4bd84044..3d74ef63 100644
--- a/ranger/wdisplay.py
+++ b/ranger/wdisplay.py
@@ -17,7 +17,6 @@ class WDisplay(ranger.widget.Widget):
 
 		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:
@@ -33,6 +32,7 @@ class WDisplay(ranger.widget.Widget):
 
 	def draw_directory(self):
 		self.target.load_content_once()
+		main_display = self.main_display
 		if not self.target.accessible:
 			self.win.addnstr(self.y, self.x, "not accessible", self.wid)
 			return
@@ -41,11 +41,16 @@ class WDisplay(ranger.widget.Widget):
 				drawed = self.target[i]
 			except IndexError:
 				break
+			invert = main_display and i == self.target.pointed_index
+			if invert:
+				self.win.attrset(curses.A_REVERSE)
 			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) + ' ')
+					self.win.addstr(self.y + i, x, str(info) + '')
+			if invert:
+				self.win.attrset(curses.A_NORMAL)