summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--examples/rc_emacs.conf1
-rwxr-xr-xranger/config/commands.py76
-rw-r--r--ranger/config/rc.conf7
-rw-r--r--ranger/config/rifle.conf1
-rw-r--r--ranger/container/directory.py8
-rw-r--r--ranger/core/main.py22
-rw-r--r--ranger/gui/widgets/statusbar.py6
7 files changed, 103 insertions, 18 deletions
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 c2ecb3af..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]
@@ -1660,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..0561f23d 100644
--- a/ranger/config/rc.conf
+++ b/ranger/config/rc.conf
@@ -375,10 +375,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/config/rifle.conf b/ranger/config/rifle.conf
index 39dee7e9..a0b46a40 100644
--- a/ranger/config/rifle.conf
+++ b/ranger/config/rifle.conf
@@ -175,6 +175,7 @@ mime ^image, has mirage,    X, flag f = mirage -- "$@"
 mime ^image, has ristretto, X, flag f = ristretto "$@"
 mime ^image, has eog,       X, flag f = eog -- "$@"
 mime ^image, has eom,       X, flag f = eom -- "$@"
+mime ^image, has nomacs,    X, flag f = nomacs -- "$@"
 mime ^image, has gimp,      X, flag f = gimp -- "$@"
 ext xcf,                    X, flag f = gimp -- "$@"
 
diff --git a/ranger/container/directory.py b/ranger/container/directory.py
index 4b067d35..fbbf4d22 100644
--- a/ranger/container/directory.py
+++ b/ranger/container/directory.py
@@ -114,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
@@ -258,6 +259,13 @@ 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
diff --git a/ranger/core/main.py b/ranger/core/main.py
index 3e68e15c..69fd6909 100644
--- a/ranger/core/main.py
+++ b/ranger/core/main.py
@@ -354,19 +354,6 @@ def load_settings(  # pylint: disable=too-many-locals,too-many-branches,too-many
                 LOG.debug("Loaded custom commands from '%s'", custom_comm_path)
             sys.dont_write_bytecode = old_bytecode_setting
 
-        allow_access_to_confdir(ranger.args.confdir, False)
-
-        # Load rc.conf
-        custom_conf = fm.confpath('rc.conf')
-        default_conf = fm.relpath('config', 'rc.conf')
-
-        if os.environ.get('RANGER_LOAD_DEFAULT_RC', 'TRUE').upper() != 'FALSE':
-            fm.source(default_conf)
-        if os.access(custom_conf, os.R_OK):
-            fm.source(custom_conf)
-
-        allow_access_to_confdir(ranger.args.confdir, True)
-
         # XXX Load plugins (experimental)
         plugindir = fm.confpath('plugins')
         try:
@@ -403,6 +390,15 @@ def load_settings(  # pylint: disable=too-many-locals,too-many-branches,too-many
             ranger.fm = None
 
         allow_access_to_confdir(ranger.args.confdir, False)
+        # Load rc.conf
+        custom_conf = fm.confpath('rc.conf')
+        default_conf = fm.relpath('config', 'rc.conf')
+
+        if os.environ.get('RANGER_LOAD_DEFAULT_RC', 'TRUE').upper() != 'FALSE':
+            fm.source(default_conf)
+        if os.access(custom_conf, os.R_OK):
+            fm.source(custom_conf)
+
     else:
         fm.source(fm.relpath('config', 'rc.conf'))
 
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')