From 176e8a684cb490393f84e7fdccc6aafda559364b Mon Sep 17 00:00:00 2001 From: hut Date: Thu, 2 Aug 2012 03:51:00 +0200 Subject: renamed ranger/defaults to ranger/config --- README | 6 +- doc/HACKING | 6 +- doc/ranger.pod | 6 +- ranger/config/__init__.py | 1 + ranger/config/commands.py | 1013 +++++++++++++++++++++++++++++++++++++++++++ ranger/config/options.py | 212 +++++++++ ranger/config/rc.conf | 372 ++++++++++++++++ ranger/config/rifle.conf | 181 ++++++++ ranger/core/fm.py | 10 +- ranger/core/helper.py | 6 +- ranger/core/main.py | 2 +- ranger/core/shared.py | 2 +- ranger/defaults/__init__.py | 1 - ranger/defaults/commands.py | 1013 ------------------------------------------- ranger/defaults/options.py | 212 --------- ranger/defaults/rc.conf | 372 ---------------- ranger/defaults/rifle.conf | 181 -------- ranger/ext/rifle.py | 2 +- 18 files changed, 1799 insertions(+), 1799 deletions(-) create mode 100644 ranger/config/__init__.py create mode 100644 ranger/config/commands.py create mode 100644 ranger/config/options.py create mode 100644 ranger/config/rc.conf create mode 100644 ranger/config/rifle.conf delete mode 100644 ranger/defaults/__init__.py delete mode 100644 ranger/defaults/commands.py delete mode 100644 ranger/defaults/options.py delete mode 100644 ranger/defaults/rc.conf delete mode 100644 ranger/defaults/rifle.conf diff --git a/README b/README index 0688030d..c0a1abb3 100644 --- a/README +++ b/README @@ -7,8 +7,8 @@ open your files with. This file describes ranger and how to get it to run. For instructions on the usage, please read the man page. See doc/HACKING for development specific -information. For configuration, check the files in ranger/defaults/. They -are usually installed to /usr/lib/python*/site-packages/ranger/defaults/ +information. For configuration, check the files in ranger/config/. They +are usually installed to /usr/lib/python*/site-packages/ranger/config/ and can be obtained with ranger's --copy-config option. A note to packagers: Versions meant for packaging are listed in the changelog @@ -92,5 +92,5 @@ directory. Ranger can automatically copy default configuration files to ~/.config/ranger if you run it with the switch --copy-config. (see ranger --help for a -description of that switch.) Also check ranger/defaults/ for the default +description of that switch.) Also check ranger/config/ for the default configuration. diff --git a/doc/HACKING b/doc/HACKING index f6d5d064..89452398 100644 --- a/doc/HACKING +++ b/doc/HACKING @@ -46,7 +46,7 @@ In ranger/fsobject/file.py the constant PREVIEW_BLACKLIST * Adding options: -In ranger/defaults/options.py +In ranger/config/options.py add the default value, like: my_option = True In ranger/container/settingobject.py add the name of your option to the constant ALLOWED_SETTINGS @@ -58,12 +58,12 @@ assuming is a "SettingsAware" object. Copy ranger/colorschemes/default.py to ranger/colorschemes/myscheme.py and modify it according to your needs. Alternatively, mimic the jungle colorscheme. It subclasses the default scheme and just modifies a few things. -In ranger/defaults/options.py (or ~/.config/ranger/options.py), change +In ranger/config/options.py (or ~/.config/ranger/options.py), change colorscheme = 'default' to: colorscheme = 'myscheme' * Change the file type => application associations: -In ranger/defaults/apps.py +In ranger/config/apps.py modify the method app_default. The variable "f" is a filesystem-object with attributes like mimetype, extension, etc. For a full list, check ranger/fsobject/fsobject.py diff --git a/doc/ranger.pod b/doc/ranger.pod index 9f8b4f04..2a3a345b 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -24,8 +24,8 @@ open your files with. This manual mainly contains information on the usage of ranger. Refer to the F for install instructions and to F for development -specific information. For configuration, see the files in F. -They are usually installed to F +specific information. For configuration, see the files in F. +They are usually installed to F and can be obtained with ranger's --copy-config option. Inside ranger, you can press I<1?> for a list of key bindings, I<2?> for a list @@ -229,7 +229,7 @@ and modes. =head1 KEY BINDINGS -Key bindings are defined in the file F. Check this +Key bindings are defined in the file F. Check this file for a list of all key bindings. You can copy it to your local configuration directory with the --copy-config=rc option. diff --git a/ranger/config/__init__.py b/ranger/config/__init__.py new file mode 100644 index 00000000..71df3cb3 --- /dev/null +++ b/ranger/config/__init__.py @@ -0,0 +1 @@ +"""Default options and configration files""" diff --git a/ranger/config/commands.py b/ranger/config/commands.py new file mode 100644 index 00000000..db411436 --- /dev/null +++ b/ranger/config/commands.py @@ -0,0 +1,1013 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2009, 2010, 2011 Roman Zimbelmann +# This configuration file is licensed under the same terms as ranger. +# =================================================================== +# This file contains ranger's commands. +# It's all in python; lines beginning with # are comments. +# +# Note that additional commands are automatically generated from the methods +# of the class ranger.core.actions.Actions. +# +# You can customize commands in the file ~/.config/ranger/commands.py. +# It has the same syntax as this file. In fact, you can just copy this +# file there with `ranger --copy-config=commands' and make your modifications. +# But make sure you update your configs when you update ranger. +# +# =================================================================== +# Every class defined here which is a subclass of `Command' will be used as a +# command in ranger. Several methods are defined to interface with ranger: +# execute(): called when the command is executed. +# cancel(): called when closing the console. +# tab(): called when is pressed. +# quick(): called after each keypress. +# +# The return values for tab() can be either: +# None: There is no tab completion +# A string: Change the console to this string +# A list/tuple/generator: cycle through every item in it +# +# The return value for quick() can be: +# False: Nothing happens +# True: Execute the command afterwards +# +# The return value for execute() and cancel() doesn't matter. +# +# =================================================================== +# Commands have certain attributes and methods that facilitate parsing of +# the arguments: +# +# self.line: The whole line that was written in the console. +# self.args: A list of all (space-separated) arguments to the command. +# self.quantifier: If this command was mapped to the key "X" and +# the user pressed 6X, self.quantifier will be 6. +# self.arg(n): The n-th argument, or an empty string if it doesn't exist. +# self.rest(n): The n-th argument plus everything that followed. For example, +# If the command was "search foo bar a b c", rest(2) will be "bar a b c" +# self.start(n): The n-th argument and anything before it. For example, +# If the command was "search foo bar a b c", rest(2) will be "bar a b c" +# +# =================================================================== +# And this is a little reference for common ranger functions and objects: +# +# self.fm: A reference to the "fm" object which contains most information +# about ranger. +# self.fm.notify(string): Print the given string on the screen. +# self.fm.notify(string, bad=True): Print the given string in RED. +# self.fm.reload_cwd(): Reload the current working directory. +# self.fm.env.cwd: The current working directory. (A File object.) +# self.fm.env.cf: The current file. (A File object too.) +# self.fm.env.cwd.get_selection(): A list of all selected files. +# self.fm.execute_console(string): Execute the string as a ranger command. +# self.fm.open_console(string): Open the console with the given string +# already typed in for you. +# self.fm.move(direction): Moves the cursor in the given direction, which +# can be something like down=3, up=5, right=1, left=1, to=6, ... +# +# File objects (for example self.fm.env.cf) have these useful attributes and +# methods: +# +# cf.path: The path to the file. +# cf.basename: The base name only. +# cf.load_content(): Force a loading of the directories content (which +# obviously works with directories only) +# cf.is_directory: True/False depending on whether it's a directory. +# +# For advanced commands it is unavoidable to dive a bit into the source code +# of ranger. +# =================================================================== + +from ranger.api.commands import * +from ranger.ext.get_executables import get_executables +from ranger.core.runner import ALLOWED_FLAGS + +class alias(Command): + """ + :alias + + Copies the oldcommand as newcommand. + """ + + context = 'browser' + resolve_macros = False + + def execute(self): + if not self.arg(1) or not self.arg(2): + self.fm.notify('Syntax: alias ', bad=True) + else: + self.fm.commands.alias(self.arg(1), self.rest(2)) + +class cd(Command): + """ + :cd [-r] + + The cd command changes the directory. + The command 'cd -' is equivalent to typing ``. + Using the option "-r" will get you to the real path. + """ + + def execute(self): + if self.arg(1) == '-r': + import os.path + self.shift() + destination = os.path.realpath(self.rest(1)) + if os.path.isfile(destination): + destination = os.path.dirname(destination) + else: + destination = self.rest(1) + + if not destination: + destination = '~' + + if destination == '-': + self.fm.enter_bookmark('`') + else: + self.fm.cd(destination) + + def tab(self): + from os.path import dirname, basename, expanduser, join + + cwd = self.fm.env.cwd.path + rel_dest = self.rest(1) + + bookmarks = [v.path for v in self.fm.bookmarks.dct.values() + if rel_dest in v.path ] + + # expand the tilde into the user directory + if rel_dest.startswith('~'): + rel_dest = expanduser(rel_dest) + + # define some shortcuts + abs_dest = join(cwd, rel_dest) + abs_dirname = dirname(abs_dest) + rel_basename = basename(rel_dest) + rel_dirname = dirname(rel_dest) + + try: + # are we at the end of a directory? + if rel_dest.endswith('/') or rel_dest == '': + _, dirnames, _ = next(os.walk(abs_dest)) + + # are we in the middle of the filename? + else: + _, dirnames, _ = next(os.walk(abs_dirname)) + dirnames = [dn for dn in dirnames \ + if dn.startswith(rel_basename)] + except (OSError, StopIteration): + # os.walk found nothing + pass + else: + dirnames.sort() + dirnames = bookmarks + dirnames + + # no results, return None + if len(dirnames) == 0: + return + + # one result. since it must be a directory, append a slash. + if len(dirnames) == 1: + return self.start(1) + join(rel_dirname, dirnames[0]) + '/' + + # more than one result. append no slash, so the user can + # manually type in the slash to advance into that directory + return (self.start(1) + join(rel_dirname, dirname) for dirname in dirnames) + + +class chain(Command): + """ + :chain ; ; ... + Calls multiple commands at once, separated by semicolons. + """ + def execute(self): + for command in self.rest(1).split(";"): + self.fm.execute_console(command) + + +class search(Command): + def execute(self): + self.fm.search_file(self.rest(1), regexp=True) + + +class search_inc(Command): + def quick(self): + self.fm.search_file(self.rest(1), regexp=True, offset=0) + + +class shell(Command): + escape_macros_for_shell = True + + def execute(self): + if self.arg(1) and self.arg(1)[0] == '-': + flags = self.arg(1)[1:] + command = self.rest(2) + else: + flags = '' + command = self.rest(1) + + if not command and 'p' in flags: command = 'cat %f' + if command: + if '%' in command: + command = self.fm.substitute_macros(command) + self.fm.execute_command(command, flags=flags) + + def tab(self): + if self.arg(1) and self.arg(1)[0] == '-': + command = self.rest(2) + else: + command = self.rest(1) + start = self.line[0:len(self.line) - len(command)] + + try: + position_of_last_space = command.rindex(" ") + except ValueError: + return (start + program + ' ' for program \ + in get_executables() if program.startswith(command)) + if position_of_last_space == len(command) - 1: + selection = self.fm.env.get_selection() + if len(selection) == 1: + return self.line + selection[0].shell_escaped_basename + ' ' + else: + return self.line + '%s ' + else: + before_word, start_of_word = self.line.rsplit(' ', 1) + return (before_word + ' ' + file.shell_escaped_basename \ + for file in self.fm.env.cwd.files \ + if file.shell_escaped_basename.startswith(start_of_word)) + +class open_with(Command): + def execute(self): + app, flags, mode = self._get_app_flags_mode(self.rest(1)) + self.fm.execute_file( + files = [f for f in self.fm.env.cwd.get_selection()], + app = app, + flags = flags, + mode = mode) + + def _get_app_flags_mode(self, string): + """ + Extracts the application, flags and mode from a string. + + examples: + "mplayer d 1" => ("mplayer", "d", 1) + "aunpack 4" => ("aunpack", "", 4) + "p" => ("", "p", 0) + "" => None + """ + + app = '' + flags = '' + mode = 0 + split = string.split() + + if len(split) == 0: + pass + + elif len(split) == 1: + part = split[0] + if self._is_app(part): + app = part + elif self._is_flags(part): + flags = part + elif self._is_mode(part): + mode = part + + elif len(split) == 2: + part0 = split[0] + part1 = split[1] + + if self._is_app(part0): + app = part0 + if self._is_flags(part1): + flags = part1 + elif self._is_mode(part1): + mode = part1 + elif self._is_flags(part0): + flags = part0 + if self._is_mode(part1): + mode = part1 + elif self._is_mode(part0): + mode = part0 + if self._is_flags(part1): + flags = part1 + + elif len(split) >= 3: + part0 = split[0] + part1 = split[1] + part2 = split[2] + + if self._is_app(part0): + app = part0 + if self._is_flags(part1): + flags = part1 + if self._is_mode(part2): + mode = part2 + elif self._is_mode(part1): + mode = part1 + if self._is_flags(part2): + flags = part2 + elif self._is_flags(part0): + flags = part0 + if self._is_mode(part1): + mode = part1 + elif self._is_mode(part0): + mode = part0 + if self._is_flags(part1): + flags = part1 + + return app, flags, int(mode) + + def _is_app(self, arg): + return not self._is_flags(arg) and not arg.isdigit() + + def _is_flags(self, arg): + return all(x in ALLOWED_FLAGS for x in arg) + + def _is_mode(self, arg): + return all(x in '0123456789' for x in arg) + + +class find(Command): + """ + :find + + The find command will attempt to find a partial, case insensitive + match in the filenames of the current directory and execute the + file automatically. + """ + + count = 0 + tab = Command._tab_directory_content + + def execute(self): + if self.quick(): + self.fm.move(right=1) + self.fm.block_input(0.5) + else: + self.fm.cd(self.rest(1)) + + def quick(self): + self.count = 0 + cwd = self.fm.env.cwd + arg = self.rest(1) + if not arg: + return False + + if arg == '.': + return False + if arg == '..': + return True + + deq = deque(cwd.files) + deq.rotate(-cwd.pointer) + i = 0 + case_insensitive = arg.lower() == arg + for fsobj in deq: + if case_insensitive: + filename = fsobj.basename_lower + else: + filename = fsobj.basename + if arg in filename: + self.count += 1 + if self.count == 1: + cwd.move(to=(cwd.pointer + i) % len(cwd.files)) + self.fm.env.cf = cwd.pointed_obj + if self.count > 1: + return False + i += 1 + + return self.count == 1 + + +class set_(Command): + """ + :set