From efdc7b16e9f422f2d95271e6d4bf64dd9a03ea33 Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 10 Mar 2010 17:53:14 +0100 Subject: added documentation on how colorschemes work --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'TODO') diff --git a/TODO b/TODO index 44de45aa..11d23a22 100644 --- a/TODO +++ b/TODO @@ -46,7 +46,7 @@ General (X) #61 10/02/09 show sum of size of marked files (X) #63 10/02/15 limit filesize in previews ( ) #64 10/02/25 scroll in previews - ( ) #66 10/02/28 explain how colorschemes work + (X) #66 10/02/28 explain how colorschemes work Bugs -- cgit 1.4.1-2-gfad0 From 01c89bb5319c218f094911e832a87a8a94eded42 Mon Sep 17 00:00:00 2001 From: hut Date: Thu, 11 Mar 2010 00:54:11 +0100 Subject: misc changes --- TODO | 1 + ranger/__init__.py | 8 ++++++++ ranger/colorschemes/__init__.py | 5 ++--- ranger/ext/relpath.py | 26 -------------------------- ranger/fm.py | 2 +- ranger/shared/mimetype.py | 2 +- 6 files changed, 13 insertions(+), 31 deletions(-) delete mode 100644 ranger/ext/relpath.py (limited to 'TODO') diff --git a/TODO b/TODO index 11d23a22..41b5497e 100644 --- a/TODO +++ b/TODO @@ -80,4 +80,5 @@ Ideas ( ) #33 10/01/08 accelerate mousewheel speed ( ) #45 10/01/18 hooks for events like setting changes ( ) #53 10/01/23 merge fm and environment + ( ) #68 10/03/10 threads, to seperate ui and loading diff --git a/ranger/__init__.py b/ranger/__init__.py index 61df678d..5ffbf998 100644 --- a/ranger/__init__.py +++ b/ranger/__init__.py @@ -41,4 +41,12 @@ sys.path.append(CONFDIR) USAGE = '%prog [options] [path/filename]' +def relpath(*paths): + """returns the path relative to rangers library directory""" + return os.path.join(RANGERDIR, *paths) + +def relpath_conf(*paths): + """returns the path relative to rangers configuration directory""" + return os.path.join(CONFDIR, *paths) + from ranger.__main__ import main diff --git a/ranger/colorschemes/__init__.py b/ranger/colorschemes/__init__.py index ab3a7da0..ed5413d8 100644 --- a/ranger/colorschemes/__init__.py +++ b/ranger/colorschemes/__init__.py @@ -23,10 +23,10 @@ from os.path import expanduser, dirname, exists, join __all__ = get_all_modules(dirname(__file__)) from ranger.colorschemes import * -from ranger.ext.relpath import relpath_conf +from ranger import relpath_conf if exists(relpath_conf('colorschemes')): - initpy = relpath_conf('colorschemes/__init__.py') + initpy = relpath_conf('colorschemes', '__init__.py') if not exists(initpy): open(initpy, 'w').write("""# Automatically generated: from ranger.ext.get_all_modules import get_all_modules @@ -41,4 +41,3 @@ __all__ = get_all_modules(dirname(__file__)) from colorschemes import * except ImportError: pass - diff --git a/ranger/ext/relpath.py b/ranger/ext/relpath.py deleted file mode 100644 index ddca89a3..00000000 --- a/ranger/ext/relpath.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2009, 2010 Roman Zimbelmann -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -import os -import ranger - -def relpath(*paths): - """returns the path relative to rangers library directory""" - return os.path.join(ranger.RANGERDIR, *paths) - -def relpath_conf(*paths): - """returns the path relative to rangers configuration directory""" - return os.path.join(ranger.CONFDIR, *paths) - diff --git a/ranger/fm.py b/ranger/fm.py index aa1f0493..d2250347 100644 --- a/ranger/fm.py +++ b/ranger/fm.py @@ -19,7 +19,7 @@ from collections import deque from ranger.actions import Actions from ranger.container import Bookmarks from ranger.runner import Runner -from ranger.ext.relpath import relpath_conf +from ranger import relpath_conf from ranger.ext.get_executables import get_executables from ranger import __version__ from ranger.fsobject import Loader diff --git a/ranger/shared/mimetype.py b/ranger/shared/mimetype.py index 93015a73..49af9632 100644 --- a/ranger/shared/mimetype.py +++ b/ranger/shared/mimetype.py @@ -13,7 +13,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from ranger.ext.relpath import relpath +from ranger import relpath class MimeTypeAware(object): mimetypes = {} __initialized = False -- cgit 1.4.1-2-gfad0 From 0128bee71f734138d3f49f56092688bb0623c6a2 Mon Sep 17 00:00:00 2001 From: hut Date: Thu, 11 Mar 2010 20:27:25 +0100 Subject: working on the configuration system / main method --- INSTALL | 2 +- TODO | 1 + ranger/__init__.py | 37 +++---- ranger/__main__.py | 106 +++++++++++++------- ranger/api/apps.py | 4 +- ranger/colorschemes/__init__.py | 19 ++-- ranger/container/bookmarks.py | 8 ++ ranger/container/tags.py | 4 + ranger/core/__init__.py | 0 ranger/core/fm.py | 135 +++++++++++++++++++++++++ ranger/core/runner.py | 191 ++++++++++++++++++++++++++++++++++++ ranger/defaults/apps.py | 3 +- ranger/defaults/options.py | 41 +++++--- ranger/ext/openstruct.py | 7 +- ranger/fm.py | 130 ------------------------ ranger/gui/widgets/browsercolumn.py | 2 +- ranger/gui/widgets/console.py | 2 +- ranger/help/starting.py | 4 +- ranger/runner.py | 191 ------------------------------------ ranger/shared/settings.py | 84 ++++++++-------- 20 files changed, 520 insertions(+), 451 deletions(-) create mode 100644 ranger/core/__init__.py create mode 100644 ranger/core/fm.py create mode 100644 ranger/core/runner.py delete mode 100644 ranger/fm.py delete mode 100644 ranger/runner.py (limited to 'TODO') diff --git a/INSTALL b/INSTALL index 4635478b..269140c6 100644 --- a/INSTALL +++ b/INSTALL @@ -27,4 +27,4 @@ To install ranger, follow this instructions: alias rng="source ranger ranger" (Unfortunately this feature is shell dependent. It has been - successfully tested with BASH only.) + successfully tested with BASH and ZSH only.) diff --git a/TODO b/TODO index 41b5497e..81af21db 100644 --- a/TODO +++ b/TODO @@ -69,6 +69,7 @@ Bugs (X) #62 10/02/15 curs_set can raise an exception (X) #65 10/02/16 "source ranger ranger some/file.txt" shouldn't cd after exit ( ) #67 10/03/08 terminal title in tty + ( ) #69 10/03/11 tab-completion breaks with Apps subclass Ideas diff --git a/ranger/__init__.py b/ranger/__init__.py index f6913bb5..8bd978d7 100644 --- a/ranger/__init__.py +++ b/ranger/__init__.py @@ -18,12 +18,6 @@ import os import sys -LOGFILE = '/tmp/errorlog' - -__copyright__ = """ -Copyright (C) 2009, 2010 Roman Zimbelmann -""" - __license__ = 'GPL3' __version__ = '1.0.3' __credits__ = 'Roman Zimbelmann' @@ -31,34 +25,41 @@ __author__ = 'Roman Zimbelmann' __maintainer__ = 'Roman Zimbelmann' __email__ = 'romanz@lavabit.com' -debug = False - -CONFDIR = os.path.expanduser(os.path.join('~', '.config', 'ranger')) -RANGERDIR = os.path.dirname(__file__) - -sys.path.append(CONFDIR) +__copyright__ = """ +Copyright (C) 2009, 2010 Roman Zimbelmann +""" USAGE = '%prog [options] [path/filename]' +DEFAULT_CONFDIR = '~/.ranger' +RANGERDIR = os.path.dirname(__file__) +LOGFILE = '/tmp/errorlog' #for python3-only versions, this could be replaced with: -# #def log(*objects, start='ranger:', sep=' ', end='\n'): # print(start, *objects, end=end, sep=sep, file=open(LOGFILE, 'a')) def log(*objects, **keywords): - """Writes objects to a logfile. - Has the same arguments as print() in python3""" + """ + Writes objects to a logfile (for the purpose of debugging only.) + Has the same arguments as print() in python3. + """ + if LOGFILE is None or arg.clean: + return start = 'start' in keywords and keywords['start'] or 'ranger:' sep = 'sep' in keywords and keywords['sep'] or ' ' _file = 'file' in keywords and keywords['file'] or open(LOGFILE, 'a') end = 'end' in keywords and keywords['end'] or '\n' _file.write(sep.join(map(str, (start, ) + objects)) + end) +def relpath_conf(*paths): + """returns the path relative to rangers configuration directory""" + if arg.clean: + assert 0, "Should not access relpath_conf in clean mode!" + else: + return os.path.join(arg.confdir, *paths) + def relpath(*paths): """returns the path relative to rangers library directory""" return os.path.join(RANGERDIR, *paths) -def relpath_conf(*paths): - """returns the path relative to rangers configuration directory""" - return os.path.join(CONFDIR, *paths) from ranger.__main__ import main diff --git a/ranger/__main__.py b/ranger/__main__.py index 72b4adf8..dba229bc 100644 --- a/ranger/__main__.py +++ b/ranger/__main__.py @@ -19,6 +19,65 @@ import os import sys + +def parse_arguments(): + """Parse the program arguments""" + + from optparse import OptionParser, SUPPRESS_HELP + from ranger.ext.openstruct import OpenStruct + from ranger import __version__, USAGE, DEFAULT_CONFDIR + + parser = OptionParser(usage=USAGE, version='ranger ' + __version__) + + # Instead of using this directly, use the embedded + # shell script by running ranger with: + # source /path/to/ranger /path/to/ranger + parser.add_option('--cd-after-exit', + action='store_true', + help=SUPPRESS_HELP) + + parser.add_option('-d', '--debug', action='store_true', + help="activate debug mode") + + parser.add_option('-c', '--clean', action='store_true', + help="don't touch/require any config files. " \ + "This will disable certain features. (tagging, bookmarks)") + + parser.add_option('-r', '--confdir', dest='confdir', type='string', + default=DEFAULT_CONFDIR, + help="the configuration directory. (%default)") + + parser.add_option('-m', '--mode', type='int', dest='mode', default=0, + help="if a filename is supplied, run it with this mode") + + parser.add_option('-f', '--flags', type='string', dest='flags', default='', + help="if a filename is supplied, run it with these flags.") + + options, positional = parser.parse_args() + + arg = OpenStruct(options.__dict__, targets=positional) + + arg.confdir = os.path.expanduser(arg.confdir) + + if arg.cd_after_exit: + sys.stderr = sys.__stdout__ + + try: + os.makedirs(arg.confdir) + except OSError as err: + if err.errno != 17: # 17 means it already exists + print("This configuration directory could not be created:") + print(arg.confdir) + print("To run ranger without the need for configuration files") + print("use the --clean option (not implemented yet)") + raise SystemExit() + + if not arg.clean: +# sys.path[0:0] = (arg.confdir, ) + sys.path.append(arg.confdir) + + return arg + def main(): """initialize objects and run the filemanager""" try: @@ -30,12 +89,10 @@ def main(): from signal import signal, SIGINT from locale import setlocale, LC_ALL - from optparse import OptionParser, SUPPRESS_HELP import ranger from ranger.ext import curses_interrupt_handler - from ranger import __version__, USAGE, CONFDIR - from ranger.fm import FM + from ranger.core.fm import FM from ranger.container.environment import Environment from ranger.shared.settings import SettingsAware from ranger.gui.defaultui import DefaultUI as UI @@ -45,50 +102,23 @@ def main(): setlocale(LC_ALL, 'en_US.utf8') except: pass - os.stat_float_times(True) - curses_interrupt_handler.install_interrupt_handler() - - if not os.path.exists(CONFDIR): - os.mkdir(CONFDIR) + curses_interrupt_handler.install_interrupt_handler() - # Parse options - parser = OptionParser(usage=USAGE, version='ranger ' + __version__) - - # Instead of using this directly, use the embedded - # shell script by running ranger with: - # source /path/to/ranger /path/to/ranger - parser.add_option('--cd-after-exit', - action='store_true', - help=SUPPRESS_HELP) - - parser.add_option('-m', type='int', dest='mode', default=0, - help="if a filename is supplied, run it with this mode") - - parser.add_option('-f', type='string', dest='flags', default='', - help="if a filename is supplied, run it with these flags.") - - parser.add_option('-d', '--debug', action='store_true', - help="activate debug mode") - - args, rest = parser.parse_args() - - if args.cd_after_exit: - sys.stderr = sys.__stdout__ - - ranger.debug = args.debug + arg = parse_arguments() + ranger.arg = arg SettingsAware._setup() # Initialize objects - target = ' '.join(rest) - if target: + if arg.targets: + target = arg.target[0] if not os.access(target, os.F_OK): print("File or directory doesn't exist: %s" % target) sys.exit(1) elif os.path.isfile(target): thefile = File(target) - FM().execute_file(thefile, mode=args.mode, flags=args.flags) + FM().execute_file(thefile, mode=arg.mode, flags=arg.flags) sys.exit(0) else: path = target @@ -100,7 +130,7 @@ def main(): try: my_ui = UI() my_fm = FM(ui=my_ui) - my_fm.stderr_to_out = args.cd_after_exit + my_fm.stderr_to_out = arg.cd_after_exit # Run the file manager my_fm.initialize() @@ -110,7 +140,7 @@ def main(): # Finish, clean up if 'my_ui' in vars(): my_ui.destroy() - if args.cd_after_exit: + if arg.cd_after_exit: try: sys.__stderr__.write(my_fm.env.pwd.path) except: pass diff --git a/ranger/api/apps.py b/ranger/api/apps.py index 743fa248..eadc0839 100644 --- a/ranger/api/apps.py +++ b/ranger/api/apps.py @@ -14,7 +14,7 @@ # along with this program. If not, see . """ -This module provides helper functions/classes for ranger.defaults.apps. +This module provides helper functions/classes for ranger.apps. """ import os, sys, re @@ -26,7 +26,7 @@ from ranger.shared import FileManagerAware class Applications(FileManagerAware): """ This class contains definitions on how to run programs and should - be extended in ranger.defaults.apps + be extended in ranger.apps The user can decide what program to run, and if he uses eg. 'vim', the function app_vim() will be called. However, usually the user diff --git a/ranger/colorschemes/__init__.py b/ranger/colorschemes/__init__.py index ed5413d8..422c6598 100644 --- a/ranger/colorschemes/__init__.py +++ b/ranger/colorschemes/__init__.py @@ -22,22 +22,15 @@ from os.path import expanduser, dirname, exists, join __all__ = get_all_modules(dirname(__file__)) -from ranger.colorschemes import * -from ranger import relpath_conf - -if exists(relpath_conf('colorschemes')): - initpy = relpath_conf('colorschemes', '__init__.py') - if not exists(initpy): - open(initpy, 'w').write("""# Automatically generated: +if not ranger.arg.clean: + if exists(ranger.relpath_conf('colorschemes')): + initpy = ranger.relpath_conf('colorschemes', '__init__.py') + if not exists(initpy): + open(initpy, 'w').write("""# Automatically generated: from ranger.ext.get_all_modules import get_all_modules from os.path import dirname __all__ = get_all_modules(dirname(__file__)) """) - try: - import sys - sys.path[0:0] = [ranger.CONFDIR] - from colorschemes import * - except ImportError: - pass +from ranger.colorschemes import * diff --git a/ranger/container/bookmarks.py b/ranger/container/bookmarks.py index a0c757ca..d4e12f62 100644 --- a/ranger/container/bookmarks.py +++ b/ranger/container/bookmarks.py @@ -150,6 +150,8 @@ class Bookmarks(object): This is done automatically after every modification if autosave is True.""" import os self.update() + if self.path is None: + return if os.access(self.path, os.W_OK): f = open(self.path, 'w') for key, value in self.dct.items(): @@ -163,6 +165,10 @@ class Bookmarks(object): def _load_dict(self): import os dct = {} + + if self.path is None: + return dct + if not os.path.exists(self.path): try: f = open(self.path, 'w') @@ -193,6 +199,8 @@ class Bookmarks(object): def _get_mtime(self): import os + if self.path is None: + return None try: return os.stat(self.path).st_mtime except OSError: diff --git a/ranger/container/tags.py b/ranger/container/tags.py index 70a4aa3d..11ac3a5d 100644 --- a/ranger/container/tags.py +++ b/ranger/container/tags.py @@ -81,3 +81,7 @@ class Tags(object): for line in f: result.add(line.strip()) return result + + def __nonzero__(self): + return True + __bool__ = __nonzero__ diff --git a/ranger/core/__init__.py b/ranger/core/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ranger/core/fm.py b/ranger/core/fm.py new file mode 100644 index 00000000..83426a04 --- /dev/null +++ b/ranger/core/fm.py @@ -0,0 +1,135 @@ +# Copyright (C) 2009, 2010 Roman Zimbelmann +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from time import time +from collections import deque + +import ranger +from ranger.actions import Actions +from ranger.container import Bookmarks +from ranger.core.runner import Runner +from ranger import relpath_conf +from ranger.ext.get_executables import get_executables +from ranger import __version__ +from ranger.fsobject import Loader + +CTRL_C = 3 +TICKS_BEFORE_COLLECTING_GARBAGE = 100 + +class FM(Actions): + input_blocked = False + input_blocked_until = 0 + stderr_to_out = False + def __init__(self, ui=None, bookmarks=None, tags=None): + """Initialize FM.""" + Actions.__init__(self) + self.ui = ui + self.log = deque(maxlen=20) + self.bookmarks = bookmarks + self.tags = tags + self.loader = Loader() + self._executables = None + self.apps = self.settings.apps.CustomApplications() + + def mylogfunc(text): + self.notify(text, bad=True) + self.run = Runner(ui=self.ui, apps=self.apps, + logfunc=mylogfunc) + + from ranger.shared import FileManagerAware + FileManagerAware.fm = self + + @property + def executables(self): + if self._executables is None: + self._executables = sorted(get_executables()) + return self._executables + + def initialize(self): + """If ui/bookmarks are None, they will be initialized here.""" + from ranger.fsobject.directory import Directory + + if self.bookmarks is None: + if ranger.arg.clean: + bookmarkfile = None + else: + bookmarkfile = relpath_conf('bookmarks') + self.bookmarks = Bookmarks( + bookmarkfile=bookmarkfile, + bookmarktype=Directory, + autosave=self.settings.autosave_bookmarks) + self.bookmarks.load() + + else: + self.bookmarks = bookmarks + + from ranger.container.tags import Tags + if not ranger.arg.clean and self.tags is None: + self.tags = Tags(relpath_conf('tagged')) + + if self.ui is None: + from ranger.gui.defaultui import DefaultUI + self.ui = DefaultUI() + self.ui.initialize() + + def block_input(self, sec=0): + self.input_blocked = sec != 0 + self.input_blocked_until = time() + sec + + def loop(self): + """ + The main loop consists of: + 1. reloading bookmarks if outdated + 2. letting the loader work + 3. drawing and finalizing ui + 4. reading and handling user input + 5. after X loops: collecting unused directory objects + """ + + self.env.enter_dir(self.env.path) + + gc_tick = 0 + + try: + while True: + self.bookmarks.update_if_outdated() + self.loader.work() + if hasattr(self.ui, 'throbber'): + if self.loader.has_work(): + self.ui.throbber(self.loader.status) + else: + self.ui.throbber(remove=True) + + self.ui.redraw() + + self.ui.set_load_mode(self.loader.has_work()) + + key = self.ui.get_next_key() + + if key > 0: + if self.input_blocked and \ + time() > self.input_blocked_until: + self.input_blocked = False + if not self.input_blocked: + self.ui.handle_key(key) + + gc_tick += 1 + if gc_tick > TICKS_BEFORE_COLLECTING_GARBAGE: + gc_tick = 0 + self.env.garbage_collect() + + finally: + self.bookmarks.remember(self.env.pwd) + self.bookmarks.save() diff --git a/ranger/core/runner.py b/ranger/core/runner.py new file mode 100644 index 00000000..26424881 --- /dev/null +++ b/ranger/core/runner.py @@ -0,0 +1,191 @@ +# Copyright (C) 2009, 2010 Roman Zimbelmann +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +This module is an abstract layer over subprocess.Popen + +It gives you highlevel control about how processes are run. + +Example: +run = Runner(logfunc=print) +run('sleep 2', wait=True) # waits until the process exists +run(['ls', '--help'], flags='p') # pipes output to pager +run() # prints an error message + +List of allowed flags: +s: silent mode. output will be discarded. +d: detach the process. +p: redirect output to the pager +(An uppercase key ensures that a certain flag will not be used.) +""" + +import os +import sys +from subprocess import Popen, PIPE +from ranger.ext.waitpid_no_intr import waitpid_no_intr + + +ALLOWED_FLAGS = 'sdpSDP' +devnull = open(os.devnull, 'a') + + +class Context(object): + """ + A context object contains data on how to run a process. + + The attributes are: + action -- a string with a command or a list of arguments for + the Popen call. + app -- the name of the app function. ("vim" for app_vim.) + app is used to get an action if the user didn't specify one. + mode -- a number, mainly used in determining the action in app_xyz() + flags -- a string with flags which change the way programs are run + files -- a list containing files, mainly used in app_xyz + file -- an arbitrary file from that list (or None) + fm -- the filemanager instance + wait -- boolean, wait for the end or execute programs in parallel? + popen_kws -- keyword arguments which are directly passed to Popen + """ + + def __init__(self, **keywords): + self.__dict__ = keywords + + @property + def filepaths(self): + try: + return [f.path for f in self.files] + except: + return [] + + def __iter__(self): + """Iterate over file paths""" + for item in self.filepaths: + yield item + + def squash_flags(self): + """Remove duplicates and lowercase counterparts of uppercase flags""" + for flag in self.flags: + if ord(flag) <= 90: + bad = flag + flag.lower() + self.flags = ''.join(c for c in self.flags if c not in bad) + + +class Runner(object): + def __init__(self, ui=None, logfunc=None, apps=None): + self.ui = ui + self.logfunc = logfunc + self.apps = apps + + def _log(self, text): + try: + self.logfunc(text) + except TypeError: + pass + return False + + def _activate_ui(self, boolean): + if self.ui is not None: + if boolean: + try: self.ui.initialize() + except: self._log("Failed to initialize UI") + else: + try: self.ui.suspend() + except: self._log("Failed to suspend UI") + + def __call__(self, action=None, try_app_first=False, + app='default', files=None, mode=0, + flags='', wait=True, **popen_kws): + """ + Run the application in the way specified by the options. + + Returns False if nothing can be done, None if there was an error, + otherwise the process object returned by Popen(). + + This function tries to find an action if none is defined. + """ + + # Find an action if none was supplied by + # creating a Context object and passing it to + # an Application object. + + context = Context(app=app, files=files, mode=mode, + flags=flags, wait=wait, popen_kws=popen_kws, + file=files and files[0] or None) + + if self.apps: + if try_app_first and action is not None: + test = self.apps.apply(app, context) + if test: + action = test + if action is None: + action = self.apps.apply(app, context) + if action is None: + return self._log("No action found!") + + if action is None: + return self._log("No way of determining the action!") + + # Preconditions + + context.squash_flags() + popen_kws = context.popen_kws # shortcut + + toggle_ui = True + pipe_output = False + + popen_kws['args'] = action + if 'shell' not in popen_kws: + popen_kws['shell'] = isinstance(action, str) + if 'stdout' not in popen_kws: + popen_kws['stdout'] = sys.stdout + if 'stderr' not in popen_kws: + popen_kws['stderr'] = sys.stderr + + # Evaluate the flags to determine keywords + # for Popen() and other variables + + if 'p' in context.flags: + popen_kws['stdout'] = PIPE + popen_kws['stderr'] = PIPE + toggle_ui = False + pipe_output = True + context.wait = False + if 's' in context.flags or 'd' in context.flags: + for key in ('stdout', 'stderr', 'stdin'): + popen_kws[key] = devnull + if 'd' in context.flags: + toggle_ui = False + context.wait = False + + # Finally, run it + + if toggle_ui: + self._activate_ui(False) + try: + process = None + try: + process = Popen(**popen_kws) + except: + self._log("Failed to run: " + str(action)) + else: + if context.wait: + waitpid_no_intr(process.pid) + finally: + if toggle_ui: + self._activate_ui(True) + if pipe_output and process: + return self(action='less', app='pager', try_app_first=True, + stdin=process.stdout) + return process diff --git a/ranger/defaults/apps.py b/ranger/defaults/apps.py index a19df7a9..37099d04 100644 --- a/ranger/defaults/apps.py +++ b/ranger/defaults/apps.py @@ -78,7 +78,7 @@ class CustomApplications(Applications): return self.either(c, 'mplayer', 'totem') if f.image: - return self.app_feh(c) + return self.either(c, 'feh', 'mirage') if f.document: return self.app_editor(c) @@ -130,7 +130,6 @@ class CustomApplications(Applications): @depends_on('mirage') def app_mirage(self, c): c.flags += 'd' - return tup('mirage', *c) @depends_on('feh') diff --git a/ranger/defaults/options.py b/ranger/defaults/options.py index 139cda88..8711f737 100644 --- a/ranger/defaults/options.py +++ b/ranger/defaults/options.py @@ -21,26 +21,45 @@ intact and the type of the value stays the same. from ranger.api.options import * -one_kb = 1024 - -colorscheme = colorschemes.default +# Which colorscheme to use? There are these by default: +# colorschemes.texas +# colorschemes.jungle +# colorschemes.default +# colorschemes.snow +# Texas uses 88 colors. If they are not supported, it will fall back +# to the default scheme. +colorscheme = colorschemes.texas max_history_size = 20 -max_filesize_for_preview = 300 * one_kb scroll_offset = 2 -preview_files = True -flushinput = True -sort = 'basename' -reverse = False -directories_first = True +# Flush the input after each key hit? (Noticable when ranger lags) +flushinput = True -show_hidden = False +# Preview files on the rightmost column? +# And collapse the last column if there is nothing to preview? +preview_files = True +max_filesize_for_preview = 300 * 1024 # 300kb collapse_preview = True + +# Save bookmarks (used with mX and `X) instantly? +# this helps to synchronize bookmarks between multiple ranger +# instances but leads to slight performance loss. +# When false, bookmarks are saved when ranger is exited. autosave_bookmarks = True + +# Specify a title for the window? Some terminals don't support this: update_title = False +# Makes sense for screen readers: show_cursor = False +# One of: size, basename, mtime, type +sort = 'basename' +reverse = False +directories_first = True + +# Which files are hidden if show_hidden is False? hidden_filter = regexp( - r'lost\+found|^\.|~$|\.(:?pyc|pyo|bak|swp)$') + r'lost\+found|^\.|~$|\.(:?pyc|pyo|bak|swp)$') +show_hidden = False diff --git a/ranger/ext/openstruct.py b/ranger/ext/openstruct.py index 11363127..a94c3031 100644 --- a/ranger/ext/openstruct.py +++ b/ranger/ext/openstruct.py @@ -13,8 +13,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +# prepend __ to arguments because one might use "args" +# or "keywords" as a keyword argument. + class OpenStruct(dict): """The fusion of dict and struct""" - def __init__(self, *args, **keywords): - dict.__init__(self, *args, **keywords) + def __init__(self, *__args, **__keywords): + dict.__init__(self, *__args, **__keywords) self.__dict__ = self diff --git a/ranger/fm.py b/ranger/fm.py deleted file mode 100644 index a10e9af6..00000000 --- a/ranger/fm.py +++ /dev/null @@ -1,130 +0,0 @@ -# Copyright (C) 2009, 2010 Roman Zimbelmann -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -from time import time -from collections import deque - -from ranger.actions import Actions -from ranger.container import Bookmarks -from ranger.runner import Runner -from ranger import relpath_conf -from ranger.ext.get_executables import get_executables -from ranger import __version__ -from ranger.fsobject import Loader - -CTRL_C = 3 -TICKS_BEFORE_COLLECTING_GARBAGE = 100 - -class FM(Actions): - input_blocked = False - input_blocked_until = 0 - stderr_to_out = False - def __init__(self, ui=None, bookmarks=None, tags=None): - """Initialize FM.""" - Actions.__init__(self) - self.ui = ui - self.log = deque(maxlen=20) - self.bookmarks = bookmarks - self.tags = tags - self.loader = Loader() - self._executables = None - self.apps = self.settings.apps.CustomApplications() - - def mylogfunc(text): - self.notify(text, bad=True) - self.run = Runner(ui=self.ui, apps=self.apps, - logfunc=mylogfunc) - - from ranger.shared import FileManagerAware - FileManagerAware.fm = self - - @property - def executables(self): - if self._executables is None: - self._executables = sorted(get_executables()) - return self._executables - - def initialize(self): - """If ui/bookmarks are None, they will be initialized here.""" - from ranger.fsobject.directory import Directory - - if self.bookmarks is None: - self.bookmarks = Bookmarks( - bookmarkfile=relpath_conf('bookmarks'), - bookmarktype=Directory, - autosave=self.settings.autosave_bookmarks) - self.bookmarks.load() - - else: - self.bookmarks = bookmarks - - from ranger.container.tags import Tags - if self.tags is None: - self.tags = Tags(relpath_conf('tagged')) - - if self.ui is None: - from ranger.gui.defaultui import DefaultUI - self.ui = DefaultUI() - self.ui.initialize() - - def block_input(self, sec=0): - self.input_blocked = sec != 0 - self.input_blocked_until = time() + sec - - def loop(self): - """ - The main loop consists of: - 1. reloading bookmarks if outdated - 2. letting the loader work - 3. drawing and finalizing ui - 4. reading and handling user input - 5. after X loops: collecting unused directory objects - """ - - self.env.enter_dir(self.env.path) - - gc_tick = 0 - - try: - while True: - self.bookmarks.update_if_outdated() - self.loader.work() - if hasattr(self.ui, 'throbber'): - if self.loader.has_work(): - self.ui.throbber(self.loader.status) - else: - self.ui.throbber(remove=True) - - self.ui.redraw() - - self.ui.set_load_mode(self.loader.has_work()) - - key = self.ui.get_next_key() - - if key > 0: - if self.input_blocked and \ - time() > self.input_blocked_until: - self.input_blocked = False - if not self.input_blocked: - self.ui.handle_key(key) - - gc_tick += 1 - if gc_tick > TICKS_BEFORE_COLLECTING_GARBAGE: - gc_tick = 0 - self.env.garbage_collect() - - finally: - self.bookmarks.remember(self.env.pwd) - self.bookmarks.save() diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index 2550062f..b98005b5 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -207,7 +207,7 @@ class BrowserColumn(Pager, Widget): this_color = base_color + list(drawed.mimetype_tuple) text = drawed.basename - tagged = drawed.realpath in self.fm.tags + tagged = self.fm.tags and drawed.realpath in self.fm.tags if i == selected_i: this_color.append('selected') diff --git a/ranger/gui/widgets/console.py b/ranger/gui/widgets/console.py index 87e5a7b5..a331c66d 100644 --- a/ranger/gui/widgets/console.py +++ b/ranger/gui/widgets/console.py @@ -580,7 +580,7 @@ class QuickOpenConsole(ConsoleWithTab): return self.fm.apps.has(arg) def _is_flags(self, arg): - from ranger.runner import ALLOWED_FLAGS + from ranger.core.runner import ALLOWED_FLAGS return all(x in ALLOWED_FLAGS for x in arg) def _is_mode(self, arg): diff --git a/ranger/help/starting.py b/ranger/help/starting.py index 29921ffc..f5517c78 100644 --- a/ranger/help/starting.py +++ b/ranger/help/starting.py @@ -61,7 +61,7 @@ Note: The "open with" console is named QuickOpenConsole in the source code. ============================================================================== 2.3. Programs -Programs have to be defined in ranger/defaults/apps.py. Each function +Programs have to be defined in ranger/apps.py. Each function in the class CustomApplications which starts with "app_" can be used as a program in the "open with" prompt. @@ -83,7 +83,7 @@ start a file in mode 0. "4l" will start the file in mode 4 etc. You can specify a mode in the "open with" console by simply adding the number. Eg: "open with: mplayer 1" or "open with: 1" -For a list of all programs and modes, see ranger/defaults/apps.py +For a list of all programs and modes, see ranger/apps.py ============================================================================== diff --git a/ranger/runner.py b/ranger/runner.py deleted file mode 100644 index 26424881..00000000 --- a/ranger/runner.py +++ /dev/null @@ -1,191 +0,0 @@ -# Copyright (C) 2009, 2010 Roman Zimbelmann -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -This module is an abstract layer over subprocess.Popen - -It gives you highlevel control about how processes are run. - -Example: -run = Runner(logfunc=print) -run('sleep 2', wait=True) # waits until the process exists -run(['ls', '--help'], flags='p') # pipes output to pager -run() # prints an error message - -List of allowed flags: -s: silent mode. output will be discarded. -d: detach the process. -p: redirect output to the pager -(An uppercase key ensures that a certain flag will not be used.) -""" - -import os -import sys -from subprocess import Popen, PIPE -from ranger.ext.waitpid_no_intr import waitpid_no_intr - - -ALLOWED_FLAGS = 'sdpSDP' -devnull = open(os.devnull, 'a') - - -class Context(object): - """ - A context object contains data on how to run a process. - - The attributes are: - action -- a string with a command or a list of arguments for - the Popen call. - app -- the name of the app function. ("vim" for app_vim.) - app is used to get an action if the user didn't specify one. - mode -- a number, mainly used in determining the action in app_xyz() - flags -- a string with flags which change the way programs are run - files -- a list containing files, mainly used in app_xyz - file -- an arbitrary file from that list (or None) - fm -- the filemanager instance - wait -- boolean, wait for the end or execute programs in parallel? - popen_kws -- keyword arguments which are directly passed to Popen - """ - - def __init__(self, **keywords): - self.__dict__ = keywords - - @property - def filepaths(self): - try: - return [f.path for f in self.files] - except: - return [] - - def __iter__(self): - """Iterate over file paths""" - for item in self.filepaths: - yield item - - def squash_flags(self): - """Remove duplicates and lowercase counterparts of uppercase flags""" - for flag in self.flags: - if ord(flag) <= 90: - bad = flag + flag.lower() - self.flags = ''.join(c for c in self.flags if c not in bad) - - -class Runner(object): - def __init__(self, ui=None, logfunc=None, apps=None): - self.ui = ui - self.logfunc = logfunc - self.apps = apps - - def _log(self, text): - try: - self.logfunc(text) - except TypeError: - pass - return False - - def _activate_ui(self, boolean): - if self.ui is not None: - if boolean: - try: self.ui.initialize() - except: self._log("Failed to initialize UI") - else: - try: self.ui.suspend() - except: self._log("Failed to suspend UI") - - def __call__(self, action=None, try_app_first=False, - app='default', files=None, mode=0, - flags='', wait=True, **popen_kws): - """ - Run the application in the way specified by the options. - - Returns False if nothing can be done, None if there was an error, - otherwise the process object returned by Popen(). - - This function tries to find an action if none is defined. - """ - - # Find an action if none was supplied by - # creating a Context object and passing it to - # an Application object. - - context = Context(app=app, files=files, mode=mode, - flags=flags, wait=wait, popen_kws=popen_kws, - file=files and files[0] or None) - - if self.apps: - if try_app_first and action is not None: - test = self.apps.apply(app, context) - if test: - action = test - if action is None: - action = self.apps.apply(app, context) - if action is None: - return self._log("No action found!") - - if action is None: - return self._log("No way of determining the action!") - - # Preconditions - - context.squash_flags() - popen_kws = context.popen_kws # shortcut - - toggle_ui = True - pipe_output = False - - popen_kws['args'] = action - if 'shell' not in popen_kws: - popen_kws['shell'] = isinstance(action, str) - if 'stdout' not in popen_kws: - popen_kws['stdout'] = sys.stdout - if 'stderr' not in popen_kws: - popen_kws['stderr'] = sys.stderr - - # Evaluate the flags to determine keywords - # for Popen() and other variables - - if 'p' in context.flags: - popen_kws['stdout'] = PIPE - popen_kws['stderr'] = PIPE - toggle_ui = False - pipe_output = True - context.wait = False - if 's' in context.flags or 'd' in context.flags: - for key in ('stdout', 'stderr', 'stdin'): - popen_kws[key] = devnull - if 'd' in context.flags: - toggle_ui = False - context.wait = False - - # Finally, run it - - if toggle_ui: - self._activate_ui(False) - try: - process = None - try: - process = Popen(**popen_kws) - except: - self._log("Failed to run: " + str(action)) - else: - if context.wait: - waitpid_no_intr(process.pid) - finally: - if toggle_ui: - self._activate_ui(True) - if pipe_output and process: - return self(action='less', app='pager', try_app_first=True, - stdin=process.stdout) - return process diff --git a/ranger/shared/settings.py b/ranger/shared/settings.py index b549bd20..6df5241f 100644 --- a/ranger/shared/settings.py +++ b/ranger/shared/settings.py @@ -14,6 +14,8 @@ # along with this program. If not, see . import types +from inspect import isclass, ismodule +import ranger from ranger.ext.openstruct import OpenStruct from ranger.gui.colorscheme import ColorScheme @@ -41,54 +43,52 @@ class SettingsAware(object): @staticmethod def _setup(): - from inspect import isclass, ismodule - from ranger.gui.colorscheme import ColorScheme + settings = OpenStruct() - # overwrite single default options with custom options from ranger.defaults import options - try: - import options as custom_options - for setting in ALLOWED_SETTINGS: - if hasattr(custom_options, setting): - setattr(options, setting, getattr(custom_options, setting)) - elif not hasattr(options, setting): - raise Exception("This option was not defined: " + setting) - except ImportError: - pass - - assert check_option_types(options) - - try: - import apps - except ImportError: - from ranger.defaults import apps - - try: - import keys - except ImportError: - from ranger.defaults import keys + for setting in ALLOWED_SETTINGS: + try: + settings[setting] = getattr(options, setting) + except AttributeError: + raise Exception("The option `{0}' was not defined" \ + " in the defaults!".format(setting)) + + import sys + if not ranger.arg.clean: + # overwrite single default options with custom options + try: + import rangerrc + except ImportError: + pass + else: + for setting in ALLOWED_SETTINGS: + try: + settings[setting] = getattr(rangerrc, setting) + except AttributeError: + pass + assert check_option_types(settings) # If a module is specified as the colorscheme, replace it with one # valid colorscheme inside that module. - all_content = options.colorscheme.__dict__.items() + all_content = settings.colorscheme.__dict__.items() - if isclass(options.colorscheme) and \ - issubclass(options.colorscheme, ColorScheme): - options.colorscheme = options.colorscheme() + if isclass(settings.colorscheme) and \ + issubclass(settings.colorscheme, ColorScheme): + settings.colorscheme = settings.colorscheme() - elif ismodule(options.colorscheme): + elif ismodule(settings.colorscheme): def is_scheme(x): return isclass(x) and issubclass(x, ColorScheme) - if hasattr(options.colorscheme, 'Scheme') \ - and is_scheme(options.colorscheme.Scheme): - options.colorscheme = options.colorscheme.Scheme() + if hasattr(settings.colorscheme, 'Scheme') \ + and is_scheme(settings.colorscheme.Scheme): + settings.colorscheme = settings.colorscheme.Scheme() else: - for name, var in options.colorscheme.__dict__.items(): + for name, var in settings.colorscheme.__dict__.items(): if var != ColorScheme and is_scheme(var): - options.colorscheme = var() + settings.colorscheme = var() break else: raise Exception("The module contains no " \ @@ -96,12 +96,18 @@ class SettingsAware(object): else: raise Exception("Cannot locate colorscheme!") - for setting in ALLOWED_SETTINGS: - SettingsAware.settings[setting] = getattr(options, setting) - - SettingsAware.settings.keys = keys - SettingsAware.settings.apps = apps + try: + import apps + except ImportError: + from ranger.defaults import apps + settings.apps = apps + try: + import keys + except ImportError: + from ranger.defaults import keys + settings.keys = keys + SettingsAware.settings = settings def check_option_types(opt): import inspect -- cgit 1.4.1-2-gfad0 From 1f62d7dbfdce9150ba8c2706216d5abf9a5ba7af Mon Sep 17 00:00:00 2001 From: hut Date: Sun, 14 Mar 2010 17:37:14 +0100 Subject: general updates, allow column levels of >1 --- TODO | 1 + ranger/core/environment.py | 20 +++++++++++++++----- ranger/gui/widgets/browsercolumn.py | 10 ++++++++-- ranger/gui/widgets/browserview.py | 8 ++++---- ranger/gui/widgets/statusbar.py | 5 ++++- 5 files changed, 32 insertions(+), 12 deletions(-) (limited to 'TODO') diff --git a/TODO b/TODO index 81af21db..964cccc9 100644 --- a/TODO +++ b/TODO @@ -47,6 +47,7 @@ General (X) #63 10/02/15 limit filesize in previews ( ) #64 10/02/25 scroll in previews (X) #66 10/02/28 explain how colorschemes work + ( ) #70 10/03/14 mouse handler for titlebar Bugs diff --git a/ranger/core/environment.py b/ranger/core/environment.py index 506e4230..984db57c 100644 --- a/ranger/core/environment.py +++ b/ranger/core/environment.py @@ -63,22 +63,32 @@ class Environment(SettingsAware): self.keybuffer.clear() def at_level(self, level): - """Returns the FileSystemObject at the given level. - level 1 => preview + """ + Returns the FileSystemObject at the given level. + level >0 => previews level 0 => current file/directory - level <0 => parent directories""" + level <0 => parent directories + """ if level <= 0: try: return self.pathway[level - 1] except IndexError: return None else: + directory = self.cf + for i in range(level - 1): + if directory is None: + return None + if directory.is_directory: + directory = directory.pointed_obj + else: + return None try: - return self.directories[self.cf.path] + return self.directories[directory.path] except AttributeError: return None except KeyError: - return self.cf + return directory def garbage_collect(self): """Delete unused directory objects""" diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index b98005b5..51c19b8a 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -53,6 +53,14 @@ class BrowserColumn(Pager, Widget): old_cf = None def __init__(self, win, level): + """ + win = the curses window object of the BrowserView + level = what to display? + + level >0 => previews + level 0 => current file/directory + level <0 => parent directories + """ Pager.__init__(self, win) Widget.__init__(self, win) self.level = level @@ -108,8 +116,6 @@ class BrowserColumn(Pager, Widget): def draw(self): """Call either _draw_file() or _draw_directory()""" - from ranger import log - if self.target != self.old_dir: self.need_redraw = True self.old_dir = self.target diff --git a/ranger/gui/widgets/browserview.py b/ranger/gui/widgets/browserview.py index 54f21fa9..24bf85b0 100644 --- a/ranger/gui/widgets/browserview.py +++ b/ranger/gui/widgets/browserview.py @@ -33,7 +33,7 @@ class BrowserView(Widget, DisplayableContainer): # normalize ratios: ratio_sum = float(sum(ratios)) - self.ratios = tuple(map(lambda x: x / ratio_sum, ratios)) + self.ratios = tuple(x / ratio_sum for x in ratios) if len(self.ratios) >= 2: self.stretch_ratios = self.ratios[:-2] + \ @@ -114,13 +114,13 @@ class BrowserView(Widget, DisplayableContainer): and self.stretch_ratios if cut_off_last: - generator = zip(self.stretch_ratios, range(len(self.ratios))) + generator = enumerate(self.stretch_ratios) else: - generator = zip(self.ratios, range(len(self.ratios))) + generator = enumerate(self.ratios) last_i = len(self.ratios) - 1 - for ratio, i in generator: + for i, ratio in generator: wid = int(ratio * self.wid) if i == last_i: diff --git a/ranger/gui/widgets/statusbar.py b/ranger/gui/widgets/statusbar.py index 26f5c7f4..6f52f8ef 100644 --- a/ranger/gui/widgets/statusbar.py +++ b/ranger/gui/widgets/statusbar.py @@ -135,7 +135,8 @@ class StatusBar(Widget): def _get_left_part(self, bar): left = bar.left - if self.column is not None: + if self.column is not None and self.column.target is not None\ + and self.column.target.is_directory: target = self.column.target.pointed_obj else: target = self.env.at_level(0).pointed_obj @@ -195,6 +196,8 @@ class StatusBar(Widget): return target = self.column.target + if target is None: + return if not target.content_loaded or not target.accessible: return -- cgit 1.4.1-2-gfad0 From 9207e83c0672c6b8b49fce3b621197fb1e77b2be Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 17 Mar 2010 12:38:21 +0100 Subject: fixed #69: tab completion breaks with Apps subclass --- TODO | 2 +- ranger/api/apps.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'TODO') diff --git a/TODO b/TODO index 964cccc9..f20d542e 100644 --- a/TODO +++ b/TODO @@ -70,7 +70,7 @@ Bugs (X) #62 10/02/15 curs_set can raise an exception (X) #65 10/02/16 "source ranger ranger some/file.txt" shouldn't cd after exit ( ) #67 10/03/08 terminal title in tty - ( ) #69 10/03/11 tab-completion breaks with Apps subclass + (X) #69 10/03/11 tab-completion breaks with Apps subclass Ideas diff --git a/ranger/api/apps.py b/ranger/api/apps.py index e61b5e2c..a17a6601 100644 --- a/ranger/api/apps.py +++ b/ranger/api/apps.py @@ -112,8 +112,12 @@ class Applications(FileManagerAware): def all(self): """Returns a list with all application functions""" - methods = self.__class__.__dict__ - return [meth[4:] for meth in methods if meth.startswith('app_')] + result = set() + # go through all the classes in the mro (method resolution order) + # so subclasses will return the apps of their superclasses. + for cls in self.__class__.__mro__: + result |= set(m[4:] for m in cls.__dict__ if m.startswith('app_')) + return sorted(result) def tup(*args): -- cgit 1.4.1-2-gfad0 From c776804d9db1f0ae837aaafe8ed27eb47bb369f5 Mon Sep 17 00:00:00 2001 From: hut Date: Sun, 21 Mar 2010 03:52:58 +0100 Subject: updated TODO and pydoc --- TODO | 3 +++ doc/pydoc/ranger.colorschemes.html | 12 ++---------- doc/pydoc/ranger.container.bookmarks.html | 2 +- doc/pydoc/ranger.container.history.html | 2 +- doc/pydoc/ranger.defaults.apps.html | 6 +++++- doc/pydoc/ranger.defaults.keys.html | 6 +++--- doc/pydoc/ranger.defaults.options.html | 13 ++++++++----- doc/pydoc/ranger.ext.openstruct.html | 4 ++-- doc/pydoc/ranger.ext.shutil_generatorized.html | 4 ++-- doc/pydoc/ranger.fsobject.directory.html | 6 ++++-- doc/pydoc/ranger.fsobject.file.html | 2 ++ doc/pydoc/ranger.fsobject.fsobject.html | 2 ++ doc/pydoc/ranger.fsobject.html | 2 +- doc/pydoc/ranger.gui.bar.html | 2 +- doc/pydoc/ranger.gui.colorscheme.html | 8 ++++++-- doc/pydoc/ranger.gui.ui.html | 16 ++++++++++++---- doc/pydoc/ranger.gui.widgets.browsercolumn.html | 19 +++++++++---------- doc/pydoc/ranger.gui.widgets.browserview.html | 8 ++++++++ doc/pydoc/ranger.gui.widgets.pager.html | 8 ++++---- doc/pydoc/ranger.shared.mimetype.html | 8 ++++++++ doc/pydoc/ranger.shared.settings.html | 7 ++++--- 21 files changed, 88 insertions(+), 52 deletions(-) (limited to 'TODO') diff --git a/TODO b/TODO index f20d542e..fa6d4d91 100644 --- a/TODO +++ b/TODO @@ -48,6 +48,7 @@ General ( ) #64 10/02/25 scroll in previews (X) #66 10/02/28 explain how colorschemes work ( ) #70 10/03/14 mouse handler for titlebar + ( ) #71 10/03/21 previews: black/whitelist + read file Bugs @@ -71,6 +72,7 @@ Bugs (X) #65 10/02/16 "source ranger ranger some/file.txt" shouldn't cd after exit ( ) #67 10/03/08 terminal title in tty (X) #69 10/03/11 tab-completion breaks with Apps subclass + ( ) #73 10/03/21 when clicking on the first column, it goes 1x down Ideas @@ -83,4 +85,5 @@ Ideas ( ) #45 10/01/18 hooks for events like setting changes ( ) #53 10/01/23 merge fm and environment ( ) #68 10/03/10 threads, to seperate ui and loading + ( ) #72 10/03/21 ranger daemon which does the slow io tasks diff --git a/doc/pydoc/ranger.colorschemes.html b/doc/pydoc/ranger.colorschemes.html index f6793175..5dcb0f83 100644 --- a/doc/pydoc/ranger.colorschemes.html +++ b/doc/pydoc/ranger.colorschemes.html @@ -9,8 +9,7 @@  
ranger.colorschemes
index
/home/hut/ranger/ranger/colorschemes/__init__.py
-

Colorschemes are required to be located here,
-or in the CONFDIR/colorschemes/ directory

+

Colorschemes are required to be located here or in CONFDIR/colorschemes/

@@ -23,12 +22,5 @@ or in the CONFDIR/colorschemes/ directory

jungle
snow
texas
-

- - - - - -
 
-Data
       __all__ = ['default88', 'snow', 'jungle', 'texas', 'default']
+ \ No newline at end of file diff --git a/doc/pydoc/ranger.container.bookmarks.html b/doc/pydoc/ranger.container.bookmarks.html index bc19d5ca..2868a5ae 100644 --- a/doc/pydoc/ranger.container.bookmarks.html +++ b/doc/pydoc/ranger.container.bookmarks.html @@ -110,7 +110,7 @@ Data and other attributes defined here:

last_mtime = None
-
load_pattern = <_sre.SRE_Pattern object at 0x1be2db0>
+
load_pattern = <_sre.SRE_Pattern object>

diff --git a/doc/pydoc/ranger.container.history.html b/doc/pydoc/ranger.container.history.html index 3820f2de..5a98f7ec 100644 --- a/doc/pydoc/ranger.container.history.html +++ b/doc/pydoc/ranger.container.history.html @@ -110,7 +110,7 @@ Methods inherited from exceptions.Exception<
Data and other attributes inherited from
exceptions.Exception:
-
__new__ = <built-in method __new__ of type object at 0x2ae9659f6000>
T.__new__(S, ...) -> a new object with type S, a subtype of T
+
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T

Methods inherited from exceptions.BaseException:
diff --git a/doc/pydoc/ranger.defaults.apps.html b/doc/pydoc/ranger.defaults.apps.html index 00034e0b..a759a187 100644 --- a/doc/pydoc/ranger.defaults.apps.html +++ b/doc/pydoc/ranger.defaults.apps.html @@ -99,6 +99,8 @@ Methods defined here:
app_firefox(self, c)
+
app_gimp(self, c)
+
app_java(self, c)
app_javac(self, c)
@@ -119,6 +121,8 @@ Methods defined here:
app_wine(self, c)
+
app_zathura(self, c)
+
app_zsnes(self, c)

@@ -154,6 +158,6 @@ Data descriptors inherited from ranger.sh Data -
       INTERPRETED_LANGUAGES = <_sre.SRE_Pattern object at 0x1d24430>
+
INTERPRETED_LANGUAGES = <_sre.SRE_Pattern object>
PIPE = -1
\ No newline at end of file diff --git a/doc/pydoc/ranger.defaults.keys.html b/doc/pydoc/ranger.defaults.keys.html index 37e1a637..ee20b40b 100644 --- a/doc/pydoc/ranger.defaults.keys.html +++ b/doc/pydoc/ranger.defaults.keys.html @@ -10,7 +10,7 @@ >index
/home/hut/ranger/ranger/defaults/keys.py

This is the default key configuration file of ranger.
-Syntax for binding keys: bind(*keys, fnc)
+Syntax for binding keys: map(*keys, fnc)
 
keys are one or more key-combinations which are either:
* a string
@@ -374,7 +374,7 @@ Check ranger.keyapi for more information

US = 31
VT = 11
controlnames = ['NUL', 'SOH', 'STX', 'ETX', 'EOT', 'ENQ', 'ACK', 'BEL', 'BS', 'HT', 'LF', 'VT', 'FF', 'CR', 'SO', 'SI', 'DLE', 'DC1', 'DC2', 'DC3', ...]
-fm = <ranger.api.keys.Wrapper object at 0x1c72b90>
+fm = <ranger.api.keys.Wrapper object>
version = '2.2'
-wdg = <ranger.api.keys.Wrapper object at 0x1c72bd0> +wdg = <ranger.api.keys.Wrapper object> \ No newline at end of file diff --git a/doc/pydoc/ranger.defaults.options.html b/doc/pydoc/ranger.defaults.options.html index efc7ad3c..76e7089d 100644 --- a/doc/pydoc/ranger.defaults.options.html +++ b/doc/pydoc/ranger.defaults.options.html @@ -31,10 +31,9 @@ of the values stay the same.

Modules         -
ranger.colorschemes.default
-
ranger.colorschemes
+
ranger.colorschemes
re
-

+

 
@@ -43,16 +42,20 @@ of the values stay the same.

        autosave_bookmarks = True
collapse_preview = True
+colorscheme = 'default'
directories_first = True
+draw_borders = False
flushinput = True
-hidden_filter = <_sre.SRE_Pattern object at 0x1d26810>
+hidden_filter = <_sre.SRE_Pattern object>
max_filesize_for_preview = 307200
max_history_size = 20
+preview_directories = True
preview_files = True
reverse = False
scroll_offset = 2
+shorten_title = 3
show_cursor = False
show_hidden = False
sort = 'basename'
-update_title = False
+update_title = True \ No newline at end of file diff --git a/doc/pydoc/ranger.ext.openstruct.html b/doc/pydoc/ranger.ext.openstruct.html index 50b0ef14..d4340807 100644 --- a/doc/pydoc/ranger.ext.openstruct.html +++ b/doc/pydoc/ranger.ext.openstruct.html @@ -135,9 +135,9 @@ In either case, this is followed by: for  Data and other attributes inherited from __builtin__.dict:

__hash__ = None
-
__new__ = <built-in method __new__ of type object at 0x2ae965a01840>
T.__new__(S, ...) -> a new object with type S, a subtype of T
+
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T
-
fromkeys = <built-in method fromkeys of type object at 0x1c16510>
dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.
+
fromkeys = <built-in method fromkeys of type object>
dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.
v defaults to None.
diff --git a/doc/pydoc/ranger.ext.shutil_generatorized.html b/doc/pydoc/ranger.ext.shutil_generatorized.html index bed50870..f9db29b7 100644 --- a/doc/pydoc/ranger.ext.shutil_generatorized.html +++ b/doc/pydoc/ranger.ext.shutil_generatorized.html @@ -80,7 +80,7 @@ Data descriptors inherited from excep

Data and other attributes inherited from
exceptions.EnvironmentError:
-
__new__ = <built-in method __new__ of type object at 0x2ae9659f6d00>
T.__new__(S, ...) -> a new object with type S, a subtype of T
+
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T

Methods inherited from exceptions.BaseException:
@@ -154,7 +154,7 @@ Data descriptors inherited from excep
Data and other attributes inherited from
exceptions.EnvironmentError:
-
__new__ = <built-in method __new__ of type object at 0x2ae9659f6d00>
T.__new__(S, ...) -> a new object with type S, a subtype of T
+
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T

Methods inherited from exceptions.BaseException:
diff --git a/doc/pydoc/ranger.fsobject.directory.html b/doc/pydoc/ranger.fsobject.directory.html index b7f77952..3def97f7 100644 --- a/doc/pydoc/ranger.fsobject.directory.html +++ b/doc/pydoc/ranger.fsobject.directory.html @@ -183,7 +183,7 @@ Data and other attributes defined here:
scroll_offset = 0
-
sort_dict = {'basename': <function sort_by_basename at 0x1ce2c08>, 'mtime': <function <lambda> at 0x1ce51b8>, 'size': <function <lambda> at 0x1ce5140>, 'type': <function <lambda> at 0x1ce5230>}
+
sort_dict = {'basename': <function sort_by_basename>, 'mtime': <function <lambda>>, 'size': <function <lambda>>, 'type': <function <lambda>>}

Methods inherited from ranger.fsobject.fsobject.FileSystemObject:
@@ -213,6 +213,8 @@ or nonexistant.

Data descriptors inherited from ranger.fsobject.fsobject.FileSystemObject:
+
filetype
+
shell_escaped_basename

@@ -331,7 +333,7 @@ Methods inherited from exceptions.Exception<
Data and other attributes inherited from
exceptions.Exception:
-
__new__ = <built-in method __new__ of type object at 0x2ae9659f6000>
T.__new__(S, ...) -> a new object with type S, a subtype of T
+
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T

Methods inherited from exceptions.BaseException:
diff --git a/doc/pydoc/ranger.fsobject.file.html b/doc/pydoc/ranger.fsobject.file.html index edd39d3f..b0816bd0 100644 --- a/doc/pydoc/ranger.fsobject.file.html +++ b/doc/pydoc/ranger.fsobject.file.html @@ -87,6 +87,8 @@ or nonexistant.
Data descriptors inherited from ranger.fsobject.fsobject.FileSystemObject:
+
filetype
+
shell_escaped_basename

diff --git a/doc/pydoc/ranger.fsobject.fsobject.html b/doc/pydoc/ranger.fsobject.fsobject.html index d4ce99ae..0681dfaa 100644 --- a/doc/pydoc/ranger.fsobject.fsobject.html +++ b/doc/pydoc/ranger.fsobject.fsobject.html @@ -88,6 +88,8 @@ or nonexistant.
Data descriptors defined here:
+
filetype
+
shell_escaped_basename

diff --git a/doc/pydoc/ranger.fsobject.html b/doc/pydoc/ranger.fsobject.html index 1993e467..864aef98 100644 --- a/doc/pydoc/ranger.fsobject.html +++ b/doc/pydoc/ranger.fsobject.html @@ -61,7 +61,7 @@ Methods inherited from exceptions.Exception<
Data and other attributes inherited from
exceptions.Exception:
-
__new__ = <built-in method __new__ of type object at 0x2ae9659f6000>
T.__new__(S, ...) -> a new object with type S, a subtype of T
+
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T

Methods inherited from exceptions.BaseException:
diff --git a/doc/pydoc/ranger.gui.bar.html b/doc/pydoc/ranger.gui.bar.html index 9e9bbebd..b4036c14 100644 --- a/doc/pydoc/ranger.gui.bar.html +++ b/doc/pydoc/ranger.gui.bar.html @@ -203,7 +203,7 @@ cmp(x, y) -> -1, 0, 1 Data and other attributes inherited from __builtin__.list:
__hash__ = None
-
__new__ = <built-in method __new__ of type object at 0x2ae9659ffbc0>
T.__new__(S, ...) -> a new object with type S, a subtype of T
+
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T

diff --git a/doc/pydoc/ranger.gui.colorscheme.html b/doc/pydoc/ranger.gui.colorscheme.html index 6e14b5ca..52b56a83 100644 --- a/doc/pydoc/ranger.gui.colorscheme.html +++ b/doc/pydoc/ranger.gui.colorscheme.html @@ -75,8 +75,12 @@ colors for faster access. Ready to use for curses.setattr()
use(self, context)
Use the colorscheme to determine the (fg, bg, attr) tuple.
-This is a dummy function which always returns default_colors.
-Override this in your custom colorscheme!

+When no colorscheme is found, ranger will fall back to this very
+basic colorscheme where directories are blue and bold, and
+selected files have the color inverted.

+Override this method in your own colorscheme.
Data descriptors defined here:
diff --git a/doc/pydoc/ranger.gui.ui.html b/doc/pydoc/ranger.gui.ui.html index 6f213ba6..abd01711 100644 --- a/doc/pydoc/ranger.gui.ui.html +++ b/doc/pydoc/ranger.gui.ui.html @@ -31,10 +31,11 @@
       
_curses
-
curses
-
socket
+curses
+
os
+socket
sys
-

+

 
@@ -167,5 +168,12 @@ Methods inherited from ranger.shared.settings.SettingsAware:
settings = {}
-
+

+ + + + + +
 
+Data
       TERMINALS_WITH_TITLE = ('xterm', 'xterm-256color', 'rxvt', 'rxvt-256color', 'rxvt-unicode', 'aterm', 'Eterm', 'screen', 'screen-256color')
\ No newline at end of file diff --git a/doc/pydoc/ranger.gui.widgets.browsercolumn.html b/doc/pydoc/ranger.gui.widgets.browsercolumn.html index a34d6fa3..98700199 100644 --- a/doc/pydoc/ranger.gui.widgets.browsercolumn.html +++ b/doc/pydoc/ranger.gui.widgets.browsercolumn.html @@ -26,16 +26,10 @@        

-
ranger.gui.widgets.Widget(ranger.gui.displayable.Displayable) -
-
-
BrowserColumn(ranger.gui.widgets.pager.Pager, ranger.gui.widgets.Widget) -
-
ranger.gui.widgets.pager.Pager(ranger.gui.widgets.Widget)
-
BrowserColumn(ranger.gui.widgets.pager.Pager, ranger.gui.widgets.Widget) +
BrowserColumn
@@ -43,7 +37,7 @@ +class BrowserColumn(ranger.gui.widgets.pager.Pager) -
 
-class BrowserColumn(ranger.gui.widgets.pager.Pager, ranger.gui.widgets.Widget)
    
Method resolution order:
@@ -60,7 +54,12 @@

Methods defined here:
-
__init__(self, win, level)
+
__init__(self, win, level)
win = the curses window object of the BrowserView
+level = what to display?

+level >0 => previews
+level 0 => current file/directory
+level <0 => parent directories
__str__(self)
@@ -187,5 +186,5 @@ Fractions of a second may be present if  Data
       PREVIEW_BLACKLIST = <_sre.SRE_Pattern object at 0x1df5760>
+PREVIEW_BLACKLIST = <_sre.SRE_Pattern object> \ No newline at end of file diff --git a/doc/pydoc/ranger.gui.widgets.browserview.html b/doc/pydoc/ranger.gui.widgets.browserview.html index 8bf98c20..627a62bf 100644 --- a/doc/pydoc/ranger.gui.widgets.browserview.html +++ b/doc/pydoc/ranger.gui.widgets.browserview.html @@ -12,6 +12,14 @@

The BrowserView manages a set of BrowserColumns.

+ + + + +
 
+Modules
       
curses
+

+ diff --git a/doc/pydoc/ranger.gui.widgets.pager.html b/doc/pydoc/ranger.gui.widgets.pager.html index da82b394..9705600f 100644 --- a/doc/pydoc/ranger.gui.widgets.pager.html +++ b/doc/pydoc/ranger.gui.widgets.pager.html @@ -145,8 +145,8 @@ Data and other attributes inherited from Data -
 
Classes
       BAR_REGEXP = <_sre.SRE_Pattern object at 0x1dba390>
-QUOTES_REGEXP = <_sre.SRE_Pattern object at 0x1d91718>
-SPECIAL_CHARS_REGEXP = <_sre.SRE_Pattern object at 0x1db4450>
-TITLE_REGEXP = <_sre.SRE_Pattern object at 0x1d933b0>
+BAR_REGEXP = <_sre.SRE_Pattern object>
+QUOTES_REGEXP = <_sre.SRE_Pattern object>
+SPECIAL_CHARS_REGEXP = <_sre.SRE_Pattern object>
+TITLE_REGEXP = <_sre.SRE_Pattern object> \ No newline at end of file diff --git a/doc/pydoc/ranger.shared.mimetype.html b/doc/pydoc/ranger.shared.mimetype.html index 2308a9bc..5ed1c0ba 100644 --- a/doc/pydoc/ranger.shared.mimetype.html +++ b/doc/pydoc/ranger.shared.mimetype.html @@ -25,6 +25,14 @@ # along with this program.  If not, see <
http://www.gnu.org/licenses/>.

+ + + + +
 
+Modules
       
mimetypes
+

+ diff --git a/doc/pydoc/ranger.shared.settings.html b/doc/pydoc/ranger.shared.settings.html index e6d09a32..29d43fc6 100644 --- a/doc/pydoc/ranger.shared.settings.html +++ b/doc/pydoc/ranger.shared.settings.html @@ -30,9 +30,10 @@ Modules -
 
Classes
       
ranger
+
os
+
ranger
types
-

+

-
 
@@ -82,5 +83,5 @@ Data and other attributes defined here:
Data
       ALLOWED_SETTINGS = {'autosave_bookmarks': <type 'bool'>, 'collapse_preview': <type 'bool'>, 'colorscheme': (<class 'ranger.gui.colorscheme.ColorScheme'>, <type 'module'>), 'directories_first': <type 'bool'>, 'flushinput': <type 'bool'>, 'hidden_filter': <function <lambda> at 0x1bf4c80>, 'max_filesize_for_preview': (<type 'int'>, <type 'NoneType'>), 'max_history_size': (<type 'int'>, <type 'NoneType'>), 'preview_files': <type 'bool'>, 'reverse': <type 'bool'>, ...}
+ALLOWED_SETTINGS = {'autosave_bookmarks': <type 'bool'>, 'collapse_preview': <type 'bool'>, 'colorscheme': <type 'str'>, 'directories_first': <type 'bool'>, 'draw_borders': <type 'bool'>, 'flushinput': <type 'bool'>, 'hidden_filter': <function <lambda>>, 'max_filesize_for_preview': (<type 'int'>, <type 'NoneType'>), 'max_history_size': (<type 'int'>, <type 'NoneType'>), 'preview_directories': <type 'bool'>, ...} \ No newline at end of file -- cgit 1.4.1-2-gfad0 From 75d98c66fffb40c8d84fbfd3fd0e469b2a2db3d2 Mon Sep 17 00:00:00 2001 From: hut Date: Sun, 21 Mar 2010 04:33:26 +0100 Subject: TODO: added bug #74 --- TODO | 1 + 1 file changed, 1 insertion(+) (limited to 'TODO') diff --git a/TODO b/TODO index fa6d4d91..17991c40 100644 --- a/TODO +++ b/TODO @@ -73,6 +73,7 @@ Bugs ( ) #67 10/03/08 terminal title in tty (X) #69 10/03/11 tab-completion breaks with Apps subclass ( ) #73 10/03/21 when clicking on the first column, it goes 1x down + ( ) #74 10/03/21 console doesn't scroll Ideas -- cgit 1.4.1-2-gfad0