diff options
author | rage311 <rage311@users.noreply.github.com> | 2017-06-27 13:15:37 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-27 13:15:37 -0600 |
commit | 747bb88e9ccf4b47b2dccbe9dc0ebcbceeeff03a (patch) | |
tree | 6696f067172c606ac363f614679c558d445483cb | |
parent | b5f5ffe69d0ae3668c34ffa14f907e98977d5e35 (diff) | |
parent | 086074db6f08af058ffdced7319287715a88d42a (diff) | |
download | ranger-747bb88e9ccf4b47b2dccbe9dc0ebcbceeeff03a.tar.gz |
Merge branch 'master' into master
-rw-r--r-- | doc/ranger.1 | 7 | ||||
-rw-r--r-- | doc/ranger.pod | 6 | ||||
-rw-r--r-- | examples/rc_emacs.conf | 1 | ||||
-rwxr-xr-x | ranger/config/commands.py | 90 | ||||
-rw-r--r-- | ranger/config/rc.conf | 11 | ||||
-rw-r--r-- | ranger/container/directory.py | 32 | ||||
-rw-r--r-- | ranger/container/settings.py | 1 | ||||
-rw-r--r-- | ranger/core/main.py | 6 | ||||
-rw-r--r-- | ranger/core/runner.py | 4 | ||||
-rw-r--r-- | ranger/gui/widgets/statusbar.py | 6 | ||||
-rw-r--r-- | ranger/gui/widgets/view_base.py | 1 |
11 files changed, 143 insertions, 22 deletions
diff --git a/doc/ranger.1 b/doc/ranger.1 index 940ffc0a..045d8b95 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.9.0b5" "2017-03-23" "ranger manual" +.TH RANGER 1 "ranger-1.9.0b5" "2017-06-16" "ranger manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -143,6 +143,7 @@ ranger \- visual file manager [\fB\-\-copy\-config\fR=\fIwhich\fR] [\fB\-\-choosefile\fR=\fItarget\fR] [\fB\-\-choosefiles\fR=\fItarget\fR] [\fB\-\-choosedir\fR=\fItarget\fR] [\fB\-\-selectfile\fR=\fIfilepath\fR] +[\fB\-\-show\-only\-dirs\fR] [\fB\-\-list\-unused\-keys\fR] [\fB\-\-list\-tagged\-files\fR=\fItag\fR] [\fB\-\-profile\fR] [\fB\-\-cmd\fR=\fIcommand\fR] [\fIpath\fR] .SH "DESCRIPTION" @@ -225,6 +226,10 @@ write the last visited directory into \fItargetfile\fR. .IP "\fB\-\-selectfile\fR=\fItargetfile\fR" 14 .IX Item "--selectfile=targetfile" Open ranger with \fItargetfile\fR selected. +.IP "\fB\-\-show\-only\-dirs\fR" 14 +.IX Item "--show-only-dirs" +Display only the directories. May be used in conjunction with +\&\fB\-\-choosedir\fR=\fItargetfile\fR. .IP "\fB\-\-list\-unused\-keys\fR" 14 .IX Item "--list-unused-keys" List common keys which are not bound to any action in the \*(L"browser\*(R" context. diff --git a/doc/ranger.pod b/doc/ranger.pod index ebeeafbe..d9dd6b3d 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -12,6 +12,7 @@ B<ranger> [B<--version>] [B<--help>] [B<--debug>] [B<--clean>] [B<--copy-config>=I<which>] [B<--choosefile>=I<target>] [B<--choosefiles>=I<target>] [B<--choosedir>=I<target>] [B<--selectfile>=I<filepath>] +[B<--show-only-dirs>] [B<--list-unused-keys>] [B<--list-tagged-files>=I<tag>] [B<--profile>] [B<--cmd>=I<command>] [I<path>] @@ -118,6 +119,11 @@ write the last visited directory into I<targetfile>. Open ranger with I<targetfile> selected. +=item B<--show-only-dirs> + +Display only the directories. May be used in conjunction with +B<--choosedir>=I<targetfile>. + =item B<--list-unused-keys> List common keys which are not bound to any action in the "browser" context. diff --git a/examples/rc_emacs.conf b/examples/rc_emacs.conf index d3707a12..26074a42 100644 --- a/examples/rc_emacs.conf +++ b/examples/rc_emacs.conf @@ -406,6 +406,7 @@ map <C-x>zs toggle_option sort_case_insensitive map <C-x>zu toggle_option autoupdate_cumulative_size map <C-x>zv toggle_option use_preview_script map <C-x>zf console filter%space +map <C-x>nn narrow # Bookmarks map <C-x>rb<any> enter_bookmark %any diff --git a/ranger/config/commands.py b/ranger/config/commands.py index 4cedc4e1..be0bbe3e 100755 --- a/ranger/config/commands.py +++ b/ranger/config/commands.py @@ -1469,6 +1469,22 @@ class scout(Command): return count == 1 +class narrow(Command): + """ + :narrow + + Show only the files selected right now. If no files are selected, + disable narrowing. + """ + def execute(self): + if self.fm.thisdir.marked_items: + selection = [f.basename for f in self.fm.thistab.get_selection()] + self.fm.thisdir.narrow_filter = selection + else: + self.fm.thisdir.narrow_filter = None + self.fm.thisdir.refilter() + + class filter_inode_type(Command): """ :filter_inode_type [dfl] @@ -1480,22 +1496,12 @@ class filter_inode_type(Command): f display files l display links """ - # pylint: disable=bad-whitespace - FILTER_DIRS = 'd' - FILTER_FILES = 'f' - FILTER_LINKS = 'l' - # pylint: enable=bad-whitespace def execute(self): if not self.arg(1): - self.fm.thisdir.inode_type_filter = None + self.fm.thisdir.inode_type_filter = "" else: - self.fm.thisdir.inode_type_filter = lambda file: ( - True if ( - (self.FILTER_DIRS in self.arg(1) and file.is_directory) or - (self.FILTER_FILES in self.arg(1) and file.is_file and not file.is_link) or - (self.FILTER_LINKS in self.arg(1) and file.is_link) - ) else False) + self.fm.thisdir.inode_type_filter = self.arg(1) self.fm.thisdir.refilter() @@ -1670,3 +1676,63 @@ class linemode(default_linemode): # Ask the browsercolumns to redraw for col in self.fm.ui.browser.columns: col.need_redraw = True + + +class yank(Command): + """:yank [name|dir|path] + + Copies the file's name (default), directory or path into both the primary X + selection and the clipboard. + """ + + modes = { + '': 'basename', + 'name': 'basename', + 'dir': 'dirname', + 'path': 'path', + } + + def execute(self): + import subprocess + + def clipboards(): + from ranger.ext.get_executables import get_executables + clipboard_managers = { + 'xclip': [ + ['xclip'], + ['xclip', '-selection', 'clipboard'], + ], + 'xsel': [ + ['xsel'], + ['xsel', '-b'], + ], + 'pbcopy': [ + ['pbcopy'], + ], + } + ordered_managers = ['pbcopy', 'xclip', 'xsel'] + executables = get_executables() + for manager in ordered_managers: + if manager in executables: + return clipboard_managers[manager] + return [] + + clipboard_commands = clipboards() + + selection = self.get_selection_attr(self.modes[self.arg(1)]) + new_clipboard_contents = "\n".join(selection) + for command in clipboard_commands: + process = subprocess.Popen(command, universal_newlines=True, + stdin=subprocess.PIPE) + process.communicate(input=new_clipboard_contents) + + def get_selection_attr(self, attr): + return [getattr(item, attr) for item in + self.fm.thistab.get_selection()] + + def tab(self, tabnum): + return ( + self.start(1) + mode for mode + in sorted(self.modes.keys()) + if mode + ) diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 9af5a953..e088b660 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -228,6 +228,10 @@ set save_tabs_on_exit false # the top and vice versa. set wrap_scroll false +# Set the global_inode_type_filter to nothing. Possible options: d, f and l for +# directories, files and symlinks respectively. +set global_inode_type_filter + # =================================================================== # == Local Options # =================================================================== @@ -375,10 +379,9 @@ map g? cd /usr/share/doc/ranger map E edit map du shell -p du --max-depth=1 -h --apparent-size map dU shell -p du --max-depth=1 -h --apparent-size | sort -rh -map yp shell -f echo -n %d/%f | xsel -i && xsel -o | xsel -i -b -map yd shell -f echo -n %d | xsel -i && xsel -o | xsel -i -b -map yn shell -f echo -n %f | xsel -i && xsel -o | xsel -i -b -map ys shell -f printf '%%s\n' %s | xsel -i && xsel -o | xsel -i -b +map yp yank path +map yd yank dir +map yn yank name # Filesystem Operations map = chmod diff --git a/ranger/container/directory.py b/ranger/container/directory.py index 168a46c7..fbbf4d22 100644 --- a/ranger/container/directory.py +++ b/ranger/container/directory.py @@ -93,6 +93,12 @@ def mtimelevel(path, level): return mtime +class InodeFilterConstants(object): # pylint: disable=too-few-public-methods + DIRS = 'd' + FILES = 'f' + LINKS = 'l' + + class Directory( # pylint: disable=too-many-instance-attributes,too-many-public-methods FileSystemObject, Accumulator, Loadable): is_directory = True @@ -108,6 +114,7 @@ class Directory( # pylint: disable=too-many-instance-attributes,too-many-public files_all = None filter = None temporary_filter = None + narrow_filter = None inode_type_filter = None marked_items = None scroll_begin = 0 @@ -252,11 +259,32 @@ class Directory( # pylint: disable=too-many-instance-attributes,too-many-public return False return True filters.append(hidden_filter_func) + if self.narrow_filter: + # pylint: disable=unsupported-membership-test + + # Pylint complains that self.narrow_filter is by default + # None but the execution won't reach this line if it is + # still None. + filters.append(lambda fobj: fobj.basename in self.narrow_filter) + if self.settings.global_inode_type_filter or self.inode_type_filter: + def inode_filter_func(obj): + # Use local inode_type_filter if present, global otherwise + inode_filter = self.inode_type_filter or self.settings.global_inode_type_filter + # Apply filter + if InodeFilterConstants.DIRS in inode_filter and \ + obj.is_directory: + return True + elif InodeFilterConstants.FILES in inode_filter and \ + obj.is_file and not obj.is_link: + return True + elif InodeFilterConstants.LINKS in inode_filter and \ + obj.is_link: + return True + return False + filters.append(inode_filter_func) if self.filter: filter_search = self.filter.search filters.append(lambda fobj: filter_search(fobj.basename)) - if self.inode_type_filter: - filters.append(self.inode_type_filter) if self.temporary_filter: temporary_filter_search = self.temporary_filter.search filters.append(lambda fobj: temporary_filter_search(fobj.basename)) diff --git a/ranger/container/settings.py b/ranger/container/settings.py index 70e299c7..00563772 100644 --- a/ranger/container/settings.py +++ b/ranger/container/settings.py @@ -41,6 +41,7 @@ ALLOWED_SETTINGS = { 'draw_borders': bool, 'draw_progress_bar_in_status_bar': bool, 'flushinput': bool, + 'global_inode_type_filter': str, 'hidden_filter': str, 'idle_delay': int, 'line_numbers': str, diff --git a/ranger/core/main.py b/ranger/core/main.py index 9a0fe59f..3f4f068a 100644 --- a/ranger/core/main.py +++ b/ranger/core/main.py @@ -119,6 +119,10 @@ def main( FileManagerAware.fm_set(fm) load_settings(fm, args.clean) + if args.show_only_dirs: + from ranger.container.directory import InodeFilterConstants + fm.settings.global_inode_type_filter = InodeFilterConstants.DIRS + if args.list_unused_keys: from ranger.ext.keybinding_parser import (special_keys, reversed_special_keys) @@ -274,6 +278,8 @@ def parse_arguments(): parser.add_option('--choosedir', type='string', metavar='PATH', help="Makes ranger act like a directory chooser. When ranger quits" ", it will write the name of the last visited directory to PATH") + parser.add_option('--show-only-dirs', action='store_true', + help="Show only directories, no files or links") parser.add_option('--selectfile', type='string', metavar='filepath', help="Open ranger with supplied file selected.") parser.add_option('--list-unused-keys', action='store_true', diff --git a/ranger/core/runner.py b/ranger/core/runner.py index 8c3e3162..bb4e512a 100644 --- a/ranger/core/runner.py +++ b/ranger/core/runner.py @@ -27,7 +27,7 @@ from __future__ import (absolute_import, division, print_function) import logging import os import sys -from subprocess import Popen, PIPE +from subprocess import Popen, PIPE, STDOUT from ranger.ext.get_executables import get_executables, get_term from ranger.ext.popen_forked import Popen_forked @@ -185,7 +185,7 @@ class Runner(object): # pylint: disable=too-few-public-methods if 'p' in context.flags: popen_kws['stdout'] = PIPE - popen_kws['stderr'] = PIPE + popen_kws['stderr'] = STDOUT toggle_ui = False pipe_output = True context.wait = False diff --git a/ranger/gui/widgets/statusbar.py b/ranger/gui/widgets/statusbar.py index eb2250ae..980945dc 100644 --- a/ranger/gui/widgets/statusbar.py +++ b/ranger/gui/widgets/statusbar.py @@ -234,7 +234,7 @@ class StatusBar(Widget): # pylint: disable=too-many-instance-attributes except KeyError: return str(gid) - def _get_right_part(self, bar): # pylint: disable=too-many-branches + def _get_right_part(self, bar): # pylint: disable=too-many-branches,too-many-statements right = bar.right if self.column is None: return @@ -256,6 +256,10 @@ class StatusBar(Widget): # pylint: disable=too-many-instance-attributes right.add(str(self.fm.thisdir.flat), base, 'flat') right.add(", ", "space") + if self.fm.thisdir.narrow_filter: + right.add("narrowed") + right.add(", ", "space") + if self.fm.thisdir.filter: right.add("f=`", base, 'filter') right.add(self.fm.thisdir.filter.pattern, base, 'filter') diff --git a/ranger/gui/widgets/view_base.py b/ranger/gui/widgets/view_base.py index 5cdb2615..cb205d92 100644 --- a/ranger/gui/widgets/view_base.py +++ b/ranger/gui/widgets/view_base.py @@ -109,6 +109,7 @@ class ViewBase(Widget, DisplayableContainer): # pylint: disable=too-many-instan def _draw_hints(self): self.columns[-1].clear_image(force=True) + self.color_reset() self.need_clear = True hints = [] for key, value in self.fm.ui.keybuffer.pointer.items(): |