summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorhut <hut@lavabit.com>2009-11-27 17:57:29 +0100
committerhut <hut@lavabit.com>2009-11-27 17:57:29 +0100
commitdd7a4f636fcc3c68b061d5af265aeaf38f70e45b (patch)
tree86792251ad3cb4a8580b18600941a1d888a67147
parent3ea48208992acbcd97eaecb23a958d35684b0317 (diff)
downloadranger-dd7a4f636fcc3c68b061d5af265aeaf38f70e45b.tar.gz
scrolling & stuff
-rw-r--r--ranger/command.py3
-rw-r--r--ranger/directory.py42
-rw-r--r--ranger/environment.py22
-rw-r--r--ranger/fm.py18
-rw-r--r--ranger/keys.py19
-rw-r--r--ranger/options.py6
-rw-r--r--ranger/ui.py3
-rw-r--r--ranger/wdisplay.py75
8 files changed, 150 insertions, 38 deletions
diff --git a/ranger/command.py b/ranger/command.py
index bd11dd70..f8c9f146 100644
--- a/ranger/command.py
+++ b/ranger/command.py
@@ -8,6 +8,9 @@ class CommandList():
 		self.dummies_in_paths = False
 		self.dummy_object = CommandDummy
 
+	# We need to know when to clear the keybuffer (when a wrong key is pressed)
+	# and when to wait for the rest of the key combination. For "gg" we
+	# will assign "g" to a dummy which tells the program not to do the latter.
 	def rebuild_paths(self):
 		paths = self.paths
 
diff --git a/ranger/directory.py b/ranger/directory.py
index 6f468b0a..57df2e13 100644
--- a/ranger/directory.py
+++ b/ranger/directory.py
@@ -18,8 +18,9 @@ class Directory(ranger.fsobject.FSObject):
 		self.filter = None
 		self.pointed_index = None
 		self.pointed_file = None
-		self.index = None
+		self.scroll_begin = 0
 		self.show_hidden = False
+		self.old_show_hidden = self.show_hidden
 	
 	def set_filter(self, string):
 		self.filter = string
@@ -34,20 +35,30 @@ class Directory(ranger.fsobject.FSObject):
 		self.content_loaded = True
 
 		if self.exists and self.runnable:
-			basenames = listdir(self.path)
-			mapped = map(lambda name: join(self.path, name), basenames)
-			self.filenames = list(mapped)
+			filenames = []
+			for fname in listdir(self.path):
+				if not self.show_hidden and fname[0] == '.':
+					continue
+				if isinstance(self.filter, str) and self.filter in fname:
+					continue
+				filenames.append(join(self.path, fname))
+#			basenames = listdir(self.path)
+#			mapped = map(lambda name: join(self.path, name), basenames)
+			self.scroll_offset = 0
+			self.filenames = filenames
 			self.infostring = ' %d' % len(self.filenames) # update the infostring
-			self.files = []
+			files = []
 			for name in self.filenames:
-				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)
+				files.append(f)
+
+			files.sort(key = lambda x: x.basename)
+			self.files = files
+
 			if len(self.files) > 0:
 				self.pointed_index = 0
 				self.pointed_file = self.files[0]
@@ -73,6 +84,16 @@ class Directory(ranger.fsobject.FSObject):
 		self.fix_pointer()
 		return self.pointed_file
 
+	def move_pointer_to_file_path(self, path):
+		self.load_content_once()
+		i = 0
+		for f in self.files:
+			if f.path == path:
+				self.move_pointer(absolute = i)
+				return
+			i += 1
+
+
 	def fix_pointer(self):
 		i = self.pointed_index
 		if i >= len(self.files): i = len(self.files) - 1
@@ -91,6 +112,11 @@ class Directory(ranger.fsobject.FSObject):
 		self.stop_if_frozen()
 		if self.load_content_once(): return True
 
+		if self.old_show_hidden != self.show_hidden:
+			self.old_show_hidden = self.show_hidden
+			self.load_content()
+			return True
+
 		import os
 		real_mtime = os.stat(self.path).st_mtime
 		cached_mtime = self.stat.st_mtime
diff --git a/ranger/environment.py b/ranger/environment.py
index faa3b9dc..d5678695 100644
--- a/ranger/environment.py
+++ b/ranger/environment.py
@@ -28,7 +28,10 @@ class Environment():
 			except IndexError:
 				return None
 		else:
-			return self.cf
+			try:
+				return self.directories[self.cf.path]
+			except KeyError:
+				return self.cf
 	
 	def get_directory(self, path):
 		import os
@@ -39,6 +42,20 @@ class Environment():
 			self.directories[path] = Directory(path)
 			return self.directories[path]
 
+	def assign_correct_cursor_positions(self):
+		# Assign correct cursor positions for subdirectories
+		from ranger.debug import log
+
+		last_path = None
+		for path in reversed(self.pathway):
+			if not last_path:
+				last_path = path.path
+				continue
+
+			log(( path.path, last_path ))
+			path.move_pointer_to_file_path(last_path)
+			last_path = path.path
+
 	def enter_dir(self, path):
 		# get the absolute path
 		path = os.path.normpath(os.path.join(self.path, path))
@@ -62,10 +79,11 @@ class Environment():
 			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)
 
+		self.assign_correct_cursor_positions()
+
 		# set the current file.
 		self.cf = self.pwd.pointed_file
 		return True
diff --git a/ranger/fm.py b/ranger/fm.py
index 48541f0c..141414b0 100644
--- a/ranger/fm.py
+++ b/ranger/fm.py
@@ -1,11 +1,3 @@
-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
@@ -19,7 +11,6 @@ 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)
@@ -29,6 +20,9 @@ class FM():
 			except:
 				raise
 
+	def resize(self):
+		self.ui.resize()
+
 	def exit(self):
 		raise SystemExit()
 
@@ -49,9 +43,13 @@ class FM():
 	def move_pointer(self, relative = 0, absolute = None):
 		self.env.cf = self.env.pwd.move_pointer(relative, abso
msize[0])) def redraw(self): self.ui.redraw() + + def toggle_boolean_option(self, string): + if isinstance(self.env.opt[string], bool): + self.env.opt[string] ^= True diff --git a/ranger/keys.py b/ranger/keys.py index fe885278..b120c507 100644 --- a/ranger/keys.py +++ b/ranger/keys.py @@ -1,6 +1,7 @@ def initialize_commands(command_list): from ranger.fm import FM from curses.ascii import ctrl + import curses cl = command_list @@ -12,21 +13,29 @@ def initialize_commands(command_list): # * a tuple of integers def move(relative = 0, absolute = None): - return lambda fm: fm.move_pointer(relative = relative, absolute = absolute) + return lambda fm: fm.move_pointer( + relative = relative, absolute = absolute) - def move_screens(n): - return lambda fm: fm.move_pointer_by_screensize(n) + def move_pages(n): + return lambda fm: fm.move_pointer_by_pages(n) + + def toggle_option(string): + return lambda fm: fm.toggle_boolean_option(string) cl.bind(FM.move_left, 'h', 195, 'back') cl.bind(FM.move_right, 'l', 'forward') cl.bind(move( relative = 1 ), 'j') - cl.bind(move_screens( 0.5 ), 'J') + cl.bind(move_pages( 0.5 ), 'J') cl.bind(move( relative = -1 ), 'k') - cl.bind(move_screens( -0.5 ), 'K') + cl.bind(move_pages( -0.5 ), 'K') cl.bind(move( absolute = 0 ), 'gg') cl.bind(move( absolute = -1 ), 'G') + + cl.bind(toggle_option('show_hidden'), 'th') + cl.bind(FM.exit, 'q', ctrl('D'), 'ZZ') cl.bind(FM.redraw, ctrl('L')) + cl.bind(FM.resize, curses.KEY_RESIZE) cl.rebuild_paths() diff --git a/ranger/options.py b/ranger/options.py index f2a7d1ae..50957c8a 100644 --- a/ranger/options.py +++ b/ranger/options.py @@ -1,5 +1,7 @@ def get(): - return [] + """ to be implemented. read the options from a file. """ + pass def dummy(): - return { 'show hidden': False } + """ provide a way of getting options until get() is implemented """ + return { 'show_hidden': False, 'scroll_offset': 2 } diff --git a/ranger/ui.py b/ranger/ui.py index 308e5e14..9e8acb73 100644 --- a/ranger/ui.py +++ b/ranger/ui.py @@ -38,7 +38,7 @@ class UI(): def press(self, key, fm): self.env.key_append(key) - log(self.env.keybuffer) +# log(self.env.keybuffer) try: cmd = self.commandlist.paths[self.env.keybuffer] @@ -58,7 +58,6 @@ class UI(): curses.endwin() def draw(self): - from ranger.debug import log self.win.erase() for widg in self.widgets: widg.feed_env(self.env) diff --git a/ranger/wdisplay.py b/ranger/wdisplay.py index 3d74ef63..d0962149 100644 --- a/ranger/wdisplay.py +++ b/ranger/wdisplay.py @@ -1,4 +1,5 @@ import ranger.widget +from ranger.debug import log import curses class WDisplay(ranger.widget.Widget): @@ -7,9 +8,12 @@ class WDisplay(ranger.widget.Widget): self.level = level self.main_display = False self.display_infostring = False + self.scroll_begin = 0 def feed_env(self, env): self.target = env.at_level(self.level) + self.show_hidden = env.opt['show_hidden'] + self.scroll_offset = env.opt['scroll_offset'] def draw(self): from ranger.file import File @@ -31,26 +35,79 @@ class WDisplay(ranger.widget.Widget): self.win.addnstr(self.y, self.x, "this is a file.", self.wid) def draw_directory(self): - self.target.load_content_once() + self.target.show_hidden = self.show_hidden + self.target.load_content_if_outdated() main_display = self.main_display + 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 - invert = main_display and i == self.target.pointed_index + + self.set_scroll_begin() + + for line in range(self.hei): + i = line + self.scroll_begin + # last file reached? + try: drawed = self.target[i] + except IndexError: break + + invert = 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.main_display: + self.win.addnstr( + self.y + line, + self.x + 1, + ' ' + drawed.basename + ' ', + self.wid - 2) + else: + self.win.addnstr( + self.y + line, + 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 + line, x, str(info) + ' ') if invert: self.win.attrset(curses.A_NORMAL) + def get_scroll_begin(self): + offset = self.scroll_offset + dirsize = len(self.target) + winsize = self.hei + halfwinsize = winsize // 2 + index = self.target.pointed_index or 0 + original = self.target.scroll_begin + projected = index - original + + upper_limit = winsize - 1 - offset + lower_limit = offset + + if dirsize < winsize: + return 0 + + if halfwinsize < offset: + return min( dirsize - winsize, max( 0, index - halfwinsize )) + + if projected < upper_limit and projected > lower_limit: + return original + + if projected > upper_limit: + return min( dirsize - winsize, + original + (projected - upper_limit)) + + if projected < upper_limit: + return max( 0, + original - (lower_limit - projected)) + + return original + + def set_scroll_begin(self): + self.scroll_begin = self.get_scroll_begin() + self.target.scroll_begin = self.scroll_begin