diff options
-rwxr-xr-x | ranger.py | 2 | ||||
-rw-r--r-- | ranger/command.py | 7 | ||||
-rw-r--r-- | ranger/directory.py | 50 | ||||
-rw-r--r-- | ranger/environment.py | 26 | ||||
-rw-r--r-- | ranger/fm.py | 21 | ||||
-rw-r--r-- | ranger/fsobject.py | 4 | ||||
-rw-r--r-- | ranger/keys.py | 27 | ||||
-rw-r--r-- | ranger/options.py | 2 | ||||
-rw-r--r-- | ranger/ui.py | 20 | ||||
-rw-r--r-- | ranger/wdisplay.py | 9 |
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) |