summary refs log tree commit diff stats
path: root/ranger
diff options
context:
space:
mode:
authorJoseph Rice <mrwildrice@gmail.com>2019-10-11 03:09:56 -0400
committerJoseph Rice <mrwildrice@gmail.com>2019-10-11 03:09:56 -0400
commit59932cfb0ce62be99dedc9025a6c560ed738312c (patch)
treef65e30a14383f5ae0685368966bfc3cbde082577 /ranger
parentb039f06f2fdb49709768225b2032e6a739c7ae51 (diff)
parent22a6f6d89db9d19277c44fde3752a9530277bd28 (diff)
downloadranger-59932cfb0ce62be99dedc9025a6c560ed738312c.tar.gz
Merge branch 'master' into image-displayer-registry
Diffstat (limited to 'ranger')
-rwxr-xr-xranger/config/commands.py114
-rw-r--r--ranger/config/rc.conf5
-rw-r--r--ranger/config/rifle.conf14
-rw-r--r--ranger/container/settings.py1
-rw-r--r--ranger/core/runner.py2
-rwxr-xr-xranger/ext/rifle.py2
-rw-r--r--ranger/gui/widgets/statusbar.py6
7 files changed, 132 insertions, 12 deletions
diff --git a/ranger/config/commands.py b/ranger/config/commands.py
index 55dd9cd1..cb6fa132 100755
--- a/ranger/config/commands.py
+++ b/ranger/config/commands.py
@@ -699,6 +699,64 @@ class delete(Command):
             self.fm.delete(files)
 
 
+class trash(Command):
+    """:trash
+
+    Tries to move the selection or the files passed in arguments (if any) to
+    the trash, using rifle rules with label "trash".
+    The arguments use a shell-like escaping.
+
+    "Selection" is defined as all the "marked files" (by default, you
+    can mark files with space or v). If there are no marked files,
+    use the "current file" (where the cursor is)
+
+    When attempting to trash non-empty directories or multiple
+    marked files, it will require a confirmation.
+    """
+
+    allow_abbrev = False
+    escape_macros_for_shell = True
+
+    def execute(self):
+        import shlex
+        from functools import partial
+
+        def is_directory_with_files(path):
+            return os.path.isdir(path) and not os.path.islink(path) and len(os.listdir(path)) > 0
+
+        if self.rest(1):
+            files = shlex.split(self.rest(1))
+            many_files = (len(files) > 1 or is_directory_with_files(files[0]))
+        else:
+            cwd = self.fm.thisdir
+            tfile = self.fm.thisfile
+            if not cwd or not tfile:
+                self.fm.notify("Error: no file selected for deletion!", bad=True)
+                return
+
+            # relative_path used for a user-friendly output in the confirmation.
+            files = [f.relative_path for f in self.fm.thistab.get_selection()]
+            many_files = (cwd.marked_items or is_directory_with_files(tfile.path))
+
+        confirm = self.fm.settings.confirm_on_delete
+        if confirm != 'never' and (confirm != 'multiple' or many_files):
+            self.fm.ui.console.ask(
+                "Confirm deletion of: %s (y/N)" % ', '.join(files),
+                partial(self._question_callback, files),
+                ('n', 'N', 'y', 'Y'),
+            )
+        else:
+            # no need for a confirmation, just delete
+            self.fm.execute_file(files, label='trash')
+
+    def tab(self, tabnum):
+        return self._tab_directory_content()
+
+    def _question_callback(self, files, answer):
+        if answer == 'y' or answer == 'Y':
+            self.fm.execute_file(files, label='trash')
+
+
 class jump_non(Command):
     """:jump_non [-FLAGS...]
 
@@ -1263,30 +1321,69 @@ class unmap(Command):
             self.fm.ui.keymaps.unbind(self.context, arg)
 
 
-class cunmap(unmap):
+class uncmap(unmap):
+    """:uncmap <keys> [<keys2>, ...]
+
+    Remove the given "console" mappings
+    """
+    context = 'console'
+
+
+class cunmap(uncmap):
     """:cunmap <keys> [<keys2>, ...]
 
     Remove the given "console" mappings
+
+    DEPRECATED in favor of uncmap.
     """
-    context = 'browser'
 
+    def execute(self):
+        self.fm.notify("cunmap is deprecated in favor of uncmap!")
+        super(cunmap, self).execute()
 
-class punmap(unmap):
-    """:punmap <keys> [<keys2>, ...]
+
+class unpmap(unmap):
+    """:unpmap <keys> [<keys2>, ...]
 
     Remove the given "pager" mappings
     """
     context = 'pager'
 
 
-class tunmap(unmap):
-    """:tunmap <keys> [<keys2>, ...]
+class punmap(unpmap):
+    """:punmap <keys> [<keys2>, ...]
+
+    Remove the given "pager" mappings
+
+    DEPRECATED in favor of unpmap.
+    """
+
+    def execute(self):
+        self.fm.notify("punmap is deprecated in favor of unpmap!")
+        super(punmap, self).execute()
+
+
+class untmap(unmap):
+    """:untmap <keys> [<keys2>, ...]
 
     Remove the given "taskview" mappings
     """
     context = 'taskview'
 
 
+class tunmap(untmap):
+    """:tunmap <keys> [<keys2>, ...]
+
+    Remove the given "taskview" mappings
+
+    DEPRECATED in favor of untmap.
+    """
+
+    def execute(self):
+        self.fm.notify("tunmap is deprecated in favor of untmap!")
+        super(tunmap, self).execute()
+
+
 class map_(Command):
     """:map <keysequence> <command>
 
@@ -1827,11 +1924,14 @@ class yank(Command):
                     ['xsel'],
                     ['xsel', '-b'],
                 ],
+                'wl-copy': [
+                    ['wl-copy'],
+                ],
                 'pbcopy': [
                     ['pbcopy'],
                 ],
             }
-            ordered_managers = ['pbcopy', 'xclip', 'xsel']
+            ordered_managers = ['pbcopy', 'wl-copy', 'xclip', 'xsel']
             executables = get_executables()
             for manager in ordered_managers:
                 if manager in executables:
diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf
index 00a20def..e557d4de 100644
--- a/ranger/config/rc.conf
+++ b/ranger/config/rc.conf
@@ -67,6 +67,9 @@ set vcs_backend_hg disabled
 set vcs_backend_bzr disabled
 set vcs_backend_svn disabled
 
+# Truncate the long commit messages to this length when shown in the statusbar.
+set vcs_msg_length 50
+
 # Use one of the supported image preview protocols
 set preview_images false
 
@@ -401,6 +404,7 @@ map <F5> copy
 map <F6> cut
 map <F7> console mkdir%space
 map <F8> console delete
+#map <F8> console trash
 map <F10> exit
 
 # In case you work on a keyboard with dvorak layout
@@ -488,6 +492,7 @@ map p`<any> paste dest=%any_path
 map p'<any> paste dest=%any_path
 
 map dD console delete
+map dT console trash
 
 map dd cut
 map ud uncut
diff --git a/ranger/config/rifle.conf b/ranger/config/rifle.conf
index a90646e2..c269cfc4 100644
--- a/ranger/config/rifle.conf
+++ b/ranger/config/rifle.conf
@@ -26,7 +26,7 @@
 #   directory      | $1 is a directory
 #   number <n>     | change the number of this command to n
 #   terminal       | stdin, stderr and stdout are connected to a terminal
-#   X              | $DISPLAY is not empty (i.e. Xorg runs)
+#   X              | A graphical environment is available (darwin, Xorg, or Wayland)
 #
 # There are also pseudo-conditions which have a "side effect":
 #   flag <flags>  | Change how the program is run. See below.
@@ -264,5 +264,15 @@ label wallpaper, number 14, mime ^image, has feh, X = feh --bg-fill "$1"
 label editor, !mime ^text, !ext xml|json|csv|tex|py|pl|rb|js|sh|php  = ${VISUAL:-$EDITOR} -- "$@"
 label pager,  !mime ^text, !ext xml|json|csv|tex|py|pl|rb|js|sh|php  = "$PAGER" -- "$@"
 
-# The very last action, so that it's never triggered accidentally, is to execute a program:
+
+######################################################################
+# The actions below are left so low down in this file on purpose, so #
+# they are never triggered accidentally.                             #
+######################################################################
+
+# Execute a file as program/script.
 mime application/x-executable = "$1"
+
+# Move the file to trash using trash-cli.
+label trash, has trash-put = trash-put -- "$@"
+label trash = mkdir -p -- ${XDG_DATA_DIR:-$HOME/.ranger}/ranger-trash; mv -- "$@" ${XDG_DATA_DIR:-$HOME/.ranger}/ranger-trash
diff --git a/ranger/container/settings.py b/ranger/container/settings.py
index 82901ac0..6fc2da5e 100644
--- a/ranger/container/settings.py
+++ b/ranger/container/settings.py
@@ -94,6 +94,7 @@ ALLOWED_SETTINGS = {
     'vcs_backend_git': str,
     'vcs_backend_hg': str,
     'vcs_backend_svn': str,
+    'vcs_msg_length': int,
     'viewmode': str,
     'w3m_delay': float,
     'w3m_offset': int,
diff --git a/ranger/core/runner.py b/ranger/core/runner.py
index f38b026a..efb307da 100644
--- a/ranger/core/runner.py
+++ b/ranger/core/runner.py
@@ -214,7 +214,7 @@ class Runner(object):  # pylint: disable=too-few-public-methods
             toggle_ui = True
             context.wait = True
         if 't' in context.flags:
-            if 'DISPLAY' not in os.environ:
+            if not ('WAYLAND_DISPLAY' in os.environ or sys.platform == 'darwin' or 'DISPLAY' in os.environ):
                 return self._log("Can not run with 't' flag, no display found!")
             term = get_term()
             if isinstance(action, str):
diff --git a/ranger/ext/rifle.py b/ranger/ext/rifle.py
index a55e14c7..cdf0d729 100755
--- a/ranger/ext/rifle.py
+++ b/ranger/ext/rifle.py
@@ -237,7 +237,7 @@ class Rifle(object):  # pylint: disable=too-many-instance-attributes
             self._app_flags = argument
             return True
         elif function == 'X':
-            return sys.platform == 'darwin' or 'DISPLAY' in os.environ
+            return 'WAYLAND_DISPLAY' in os.environ or sys.platform == 'darwin' or 'DISPLAY' in os.environ
         elif function == 'env':
             return bool(os.environ.get(argument))
         elif function == 'else':
diff --git a/ranger/gui/widgets/statusbar.py b/ranger/gui/widgets/statusbar.py
index 71064ed4..fd44613e 100644
--- a/ranger/gui/widgets/statusbar.py
+++ b/ranger/gui/widgets/statusbar.py
@@ -212,7 +212,11 @@ class StatusBar(Widget):  # pylint: disable=too-many-instance-attributes
                 left.add_space()
                 left.add(directory.vcs.rootvcs.head['date'].strftime(self.timeformat), 'vcsdate')
                 left.add_space()
-                left.add(directory.vcs.rootvcs.head['summary'], 'vcscommit')
+                summary_length = self.settings.vcs_msg_length or 50
+                left.add(
+                    directory.vcs.rootvcs.head['summary'][:summary_length],
+                    'vcscommit'
+                )
 
     def _get_owner(self, target):
         uid = target.stat.st_uid