diff options
-rw-r--r-- | ranger/command.py | 3 | ||||
-rw-r--r-- | ranger/directory.py | 42 | ||||
-rw-r--r-- | ranger/environment.py | 22 | ||||
-rw-r--r-- | ranger/fm.py | 18 | ||||
-rw-r--r-- | ranger/keys.py | 19 | ||||
-rw-r--r-- | ranger/options.py | 6 | ||||
-rw-r--r-- | ranger/ui.py | 3 | ||||
-rw-r--r-- | ranger/wdisplay.py | 75 |
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, absolute) - def move_pointer_by_screensize(self, relative = 0): + def move_pointer_by_pages(self, relative = 0): self.env.cf = self.env.pwd.move_pointer( relative = int(relative * self.env.termsize[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 |