summary refs log tree commit diff stats
path: root/ranger
diff options
context:
space:
mode:
authorsiikamiika <siikamiika@users.noreply.github.com>2019-12-09 21:58:02 +0200
committerGitHub <noreply@github.com>2019-12-09 21:58:02 +0200
commita9a85c201eda486ff7d3be9b06fca705d4675612 (patch)
tree71d6a4e00c28a6e45738dff4d0a20c5b458825a3 /ranger
parent05e7e2c502a07d9b38ca0c8f055445c38b10d049 (diff)
parent4ff19f6c059fc0d477273304988dc6b7c0ee6320 (diff)
downloadranger-a9a85c201eda486ff7d3be9b06fca705d4675612.tar.gz
Merge branch 'master' into feat-update-icon-title
Diffstat (limited to 'ranger')
-rwxr-xr-xranger/config/commands.py120
-rw-r--r--ranger/config/rc.conf10
-rw-r--r--ranger/config/rifle.conf26
-rw-r--r--ranger/container/fsobject.py6
-rw-r--r--ranger/container/settings.py5
-rw-r--r--ranger/core/actions.py8
-rw-r--r--ranger/core/fm.py25
-rw-r--r--ranger/core/main.py10
-rw-r--r--ranger/core/runner.py4
-rw-r--r--ranger/data/mime.types4
-rwxr-xr-xranger/data/scope.sh1
-rw-r--r--ranger/ext/img_display.py35
-rwxr-xr-xranger/ext/rifle.py7
-rw-r--r--ranger/gui/widgets/statusbar.py6
14 files changed, 217 insertions, 50 deletions
diff --git a/ranger/config/commands.py b/ranger/config/commands.py
index 2b1f4940..cb6fa132 100755
--- a/ranger/config/commands.py
+++ b/ranger/config/commands.py
@@ -572,7 +572,7 @@ class default_linemode(Command):
 class quit(Command):  # pylint: disable=redefined-builtin
     """:quit
 
-    Closes the current tab, if there's only one tab.
+    Closes the current tab, if there's more than one tab.
     Otherwise quits if there are no tasks in progress.
     """
     def _exit_no_work(self):
@@ -591,7 +591,7 @@ class quit(Command):  # pylint: disable=redefined-builtin
 class quit_bang(Command):
     """:quit!
 
-    Closes the current tab, if there's only one tab.
+    Closes the current tab, if there's more than one tab.
     Otherwise force quits immediately.
     """
     name = 'quit!'
@@ -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...]
 
@@ -1244,7 +1302,7 @@ class copycmap(copymap):
 
 
 class copytmap(copymap):
-    """:copycmap <keys> <newkeys1> [<newkeys2>...]
+    """:copytmap <keys> <newkeys1> [<newkeys2>...]
 
     Copies a "taskview" keybinding from <keys> to <newkeys>
     """
@@ -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 b4bb4bfc..23601fb6 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
 
@@ -304,6 +307,11 @@ set freeze_files false
 # Print file sizes in bytes instead of the default human-readable format.
 set size_in_bytes false
 
+# Warn at startup if RANGER_LEVEL env var is greater than 0, in other words
+# give a warning when you nest ranger in a subshell started by ranger.
+# Special value "error" makes the warning more visible.
+set nested_ranger_warning true
+
 # ===================================================================
 # == Local Options
 # ===================================================================
@@ -399,6 +407,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
@@ -486,6 +495,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..86f53fd1 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.
@@ -66,13 +66,13 @@ ext x?html?, has uzbl-tabbed,      X, flag f = uzbl-tabbed -- "$@"
 ext x?html?, has uzbl-browser,     X, flag f = uzbl-browser -- "$@"
 ext x?html?, has uzbl-core,        X, flag f = uzbl-core -- "$@"
 ext x?html?, has midori,           X, flag f = midori -- "$@"
-ext x?html?, has chromium-browser, X, flag f = chromium-browser -- "$@"
-ext x?html?, has chromium,         X, flag f = chromium -- "$@"
-ext x?html?, has google-chrome,    X, flag f = google-chrome -- "$@"
 ext x?html?, has opera,            X, flag f = opera -- "$@"
 ext x?html?, has firefox,          X, flag f = firefox -- "$@"
 ext x?html?, has seamonkey,        X, flag f = seamonkey -- "$@"
 ext x?html?, has iceweasel,        X, flag f = iceweasel -- "$@"
+ext x?html?, has chromium-browser, X, flag f = chromium-browser -- "$@"
+ext x?html?, has chromium,         X, flag f = chromium -- "$@"
+ext x?html?, has google-chrome,    X, flag f = google-chrome -- "$@"
 ext x?html?, has epiphany,         X, flag f = epiphany -- "$@"
 ext x?html?, has konqueror,        X, flag f = konqueror -- "$@"
 ext x?html?, has elinks,            terminal = elinks "$@"
@@ -259,10 +259,26 @@ label wallpaper, number 12, mime ^image, has feh, X = feh --bg-tile "$1"
 label wallpaper, number 13, mime ^image, has feh, X = feh --bg-center "$1"
 label wallpaper, number 14, mime ^image, has feh, X = feh --bg-fill "$1"
 
+#-------------------------------------------
+# Generic file openers
+#-------------------------------------------
+label open, has xdg-open = xdg-open -- "$@"
+label open, has open     = open -- "$@"
+
 # Define the editor for non-text files + pager as last action
               !mime ^text, !ext xml|json|csv|tex|py|pl|rb|js|sh|php  = ask
 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/fsobject.py b/ranger/container/fsobject.py
index 4fb47354..7de889bf 100644
--- a/ranger/container/fsobject.py
+++ b/ranger/container/fsobject.py
@@ -342,10 +342,10 @@ class FileSystemObject(  # pylint: disable=too-many-instance-attributes,too-many
         if self.permissions is not None:
             return self.permissions
 
-        if self.is_directory:
-            perms = ['d']
-        elif self.is_link:
+        if self.is_link:
             perms = ['l']
+        elif self.is_directory:
+            perms = ['d']
         else:
             perms = ['-']
 
diff --git a/ranger/container/settings.py b/ranger/container/settings.py
index 3075aadf..5f0c528b 100644
--- a/ranger/container/settings.py
+++ b/ranger/container/settings.py
@@ -58,6 +58,7 @@ ALLOWED_SETTINGS = {
     'max_history_size': (int, type(None)),
     'metadata_deep_search': bool,
     'mouse_enabled': bool,
+    'nested_ranger_warning': str,
     'one_indexed': bool,
     'open_all_images': bool,
     'padding_right': bool,
@@ -94,6 +95,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,
@@ -106,6 +108,7 @@ ALLOWED_VALUES = {
     'confirm_on_delete': ['multiple', 'always', 'never'],
     'draw_borders': ['none', 'both', 'outline', 'separators'],
     'line_numbers': ['false', 'absolute', 'relative'],
+    'nested_ranger_warning': ['true', 'false', 'error'],
     'one_indexed': [False, True],
     'preview_images_method': ['w3m', 'iterm2', 'terminology',
                               'urxvt', 'urxvt-full', 'kitty',
@@ -277,7 +280,7 @@ class Settings(SignalDispatcher, FileManagerAware):
         if path:
             if path not in self._localsettings:
                 try:
-                    regex = re.compile(path)
+                    regex = re.compile(re.escape(path))
                 except re.error:  # Bad regular expression
                     return
                 self._localregexes[path] = regex
diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index 435fcf13..18302431 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -1597,20 +1597,22 @@ class Actions(  # pylint: disable=too-many-instance-attributes,too-many-public-m
         Paste the selected items into the current directory or to dest
         if provided.
         """
-        if dest is None or isdir(dest):
+        if dest is None:
+            dest = self.thistab.path
+        if isdir(dest):
             loadable = CopyLoader(self.copy_buffer, self.do_cut, overwrite,
                                   dest)
             self.loader.add(loadable, append=append)
             self.do_cut = False
         else:
-            self.notify('Failed to paste. The given path is invalid.', bad=True)
+            self.notify('Failed to paste. The destination is invalid.', bad=True)
 
     def delete(self, files=None):
         # XXX: warn when deleting mount points/unseen marked files?
-        self.notify("Deleting!")
         # COMPAT: old command.py use fm.delete() without arguments
         if files is None:
             files = (fobj.path for fobj in self.thistab.get_selection())
+        self.notify("Deleting {}!".format(", ".join(files)))
         files = [os.path.abspath(path) for path in files]
         for path in files:
             # Untag the deleted files.
diff --git a/ranger/core/fm.py b/ranger/core/fm.py
index 43001e8b..7d23c9b6 100644
--- a/ranger/core/fm.py
+++ b/ranger/core/fm.py
@@ -22,11 +22,7 @@ from ranger.container.tags import Tags, TagsDummy
 from ranger.gui.ui import UI
 from ranger.container.bookmarks import Bookmarks
 from ranger.core.runner import Runner
-from ranger.ext.img_display import (W3MImageDisplayer, ITerm2ImageDisplayer,
-                                    TerminologyImageDisplayer,
-                                    URXVTImageDisplayer, URXVTImageFSDisplayer,
-                                    KittyImageDisplayer, UeberzugImageDisplayer,
-                                    ImageDisplayer)
+from ranger.ext.img_display import get_image_displayer
 from ranger.core.metadata import MetadataManager
 from ranger.ext.rifle import Rifle
 from ranger.container.directory import Directory
@@ -104,7 +100,7 @@ class FM(Actions,  # pylint: disable=too-many-instance-attributes
         def set_image_displayer():
             if self.image_displayer:
                 self.image_displayer.quit()
-            self.image_displayer = self._get_image_displayer()
+            self.image_displayer = get_image_displayer(self.settings.preview_images_method)
         set_image_displayer()
         self.settings.signal_bind('setopt.preview_images_method', set_image_displayer,
                                   priority=settings.SIGNAL_PRIORITY_AFTER_SYNC)
@@ -227,23 +223,6 @@ class FM(Actions,  # pylint: disable=too-many-instance-attributes
             for line in entry.splitlines():
                 yield line
 
-    def _get_image_displayer(self):  # pylint: disable=too-many-return-statements
-        if self.settings.preview_images_method == "w3m":
-            return W3MImageDisplayer()
-        elif self.settings.preview_images_method == "iterm2":
-            return ITerm2ImageDisplayer()
-        elif self.settings.preview_images_method == "terminology":
-            return TerminologyImageDisplayer()
-        elif self.settings.preview_images_method == "urxvt":
-            return URXVTImageDisplayer()
-        elif self.settings.preview_images_method == "urxvt-full":
-            return URXVTImageFSDisplayer()
-        elif self.settings.preview_images_method == "kitty":
-            return KittyImageDisplayer()
-        elif self.settings.preview_images_method == "ueberzug":
-            return UeberzugImageDisplayer()
-        return ImageDisplayer()
-
     def _get_thisfile(self):
         return self.thistab.thisfile
 
diff --git a/ranger/core/main.py b/ranger/core/main.py
index 23648677..aefaacbc 100644
--- a/ranger/core/main.py
+++ b/ranger/core/main.py
@@ -180,6 +180,16 @@ def main(
             for command in args.cmd:
                 fm.execute_console(command)
 
+        if int(os.environ[level]) > 1:
+            warning = 'Warning:'
+            nested_warning = "You're in a nested ranger instance!"
+            warn_when_nested = fm.settings.nested_ranger_warning.lower()
+            if warn_when_nested == 'true':
+                fm.notify(' '.join((warning, nested_warning)), bad=False)
+            elif warn_when_nested == 'error':
+                fm.notify(' '.join((warning.upper(), nested_warning + '!!')),
+                          bad=True)
+
         if ranger.args.profile:
             import cProfile
             import pstats
diff --git a/ranger/core/runner.py b/ranger/core/runner.py
index f38b026a..d465f070 100644
--- a/ranger/core/runner.py
+++ b/ranger/core/runner.py
@@ -214,7 +214,9 @@ 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/data/mime.types b/ranger/data/mime.types
index 900cb7d9..abee11f6 100644
--- a/ranger/data/mime.types
+++ b/ranger/data/mime.types
@@ -12,11 +12,13 @@
 
 audio/flac              flac
 audio/musepack          mpc mpp mp+
-audio/ogg               oga ogg spx
+audio/ogg               oga ogg spx opus
 audio/wavpack           wv wvc
 audio/webm              weba
 audio/x-ape             ape
 
+image/webp              webp
+
 video/mkv               mkv
 video/webm              webm
 video/flash             flv
diff --git a/ranger/data/scope.sh b/ranger/data/scope.sh
index 306eeed0..eb09b2bf 100755
--- a/ranger/data/scope.sh
+++ b/ranger/data/scope.sh
@@ -45,7 +45,6 @@ HIGHLIGHT_STYLE=${HIGHLIGHT_STYLE:-pablo}
 HIGHLIGHT_OPTIONS="--replace-tabs=${HIGHLIGHT_TABWIDTH} --style=${HIGHLIGHT_STYLE} ${HIGHLIGHT_OPTIONS:-}"
 PYGMENTIZE_STYLE=${PYGMENTIZE_STYLE:-autumn}
 
-
 handle_extension() {
     case "${FILE_EXTENSION_LOWER}" in
         ## Archive
diff --git a/ranger/ext/img_display.py b/ranger/ext/img_display.py
index 2cce5c7a..7e911848 100644
--- a/ranger/ext/img_display.py
+++ b/ranger/ext/img_display.py
@@ -23,6 +23,7 @@ import warnings
 import json
 import threading
 from subprocess import Popen, PIPE
+from collections import defaultdict
 
 import termios
 from contextlib import contextmanager
@@ -72,6 +73,33 @@ class ImgDisplayUnsupportedException(Exception):
     pass
 
 
+def fallback_image_displayer():
+    """Simply makes some noise when chosen. Temporary fallback behavior."""
+
+    raise ImgDisplayUnsupportedException
+
+
+IMAGE_DISPLAYER_REGISTRY = defaultdict(fallback_image_displayer)
+
+
+def register_image_displayer(nickname=None):
+    """Register an ImageDisplayer by nickname if available."""
+
+    def decorator(image_displayer_class):
+        if nickname:
+            registry_key = nickname
+        else:
+            registry_key = image_displayer_class.__name__
+        IMAGE_DISPLAYER_REGISTRY[registry_key] = image_displayer_class
+        return image_displayer_class
+    return decorator
+
+
+def get_image_displayer(registry_key):
+    image_displayer_class = IMAGE_DISPLAYER_REGISTRY[registry_key]
+    return image_displayer_class()
+
+
 class ImageDisplayer(object):
     """Image display provider functions for drawing images in the terminal"""
 
@@ -90,6 +118,7 @@ class ImageDisplayer(object):
         pass
 
 
+@register_image_displayer("w3m")
 class W3MImageDisplayer(ImageDisplayer, FileManagerAware):
     """Implementation of ImageDisplayer using w3mimgdisplay, an utilitary
     program from w3m (a text-based web browser). w3mimgdisplay can display
@@ -243,6 +272,7 @@ class W3MImageDisplayer(ImageDisplayer, FileManagerAware):
 # ranger-independent libraries.
 
 
+@register_image_displayer("iterm2")
 class ITerm2ImageDisplayer(ImageDisplayer, FileManagerAware):
     """Implementation of ImageDisplayer using iTerm2 image display support
     (http://iterm2.com/images.html).
@@ -351,6 +381,7 @@ class ITerm2ImageDisplayer(ImageDisplayer, FileManagerAware):
         return width, height
 
 
+@register_image_displayer("terminology")
 class TerminologyImageDisplayer(ImageDisplayer, FileManagerAware):
     """Implementation of ImageDisplayer using terminology image display support
     (https://github.com/billiob/terminology).
@@ -390,6 +421,7 @@ class TerminologyImageDisplayer(ImageDisplayer, FileManagerAware):
         self.clear(0, 0, 0, 0)
 
 
+@register_image_displayer("urxvt")
 class URXVTImageDisplayer(ImageDisplayer, FileManagerAware):
     """Implementation of ImageDisplayer working by setting the urxvt
     background image "under" the preview pane.
@@ -474,6 +506,7 @@ class URXVTImageDisplayer(ImageDisplayer, FileManagerAware):
         self.clear(0, 0, 0, 0)  # dummy assignments
 
 
+@register_image_displayer("urxvt-full")
 class URXVTImageFSDisplayer(URXVTImageDisplayer):
     """URXVTImageDisplayer that utilizes the whole terminal."""
 
@@ -486,6 +519,7 @@ class URXVTImageFSDisplayer(URXVTImageDisplayer):
         return self._get_centered_offsets()
 
 
+@register_image_displayer("kitty")
 class KittyImageDisplayer(ImageDisplayer, FileManagerAware):
     """Implementation of ImageDisplayer for kitty (https://github.com/kovidgoyal/kitty/)
     terminal. It uses the built APC to send commands and data to kitty,
@@ -681,6 +715,7 @@ class KittyImageDisplayer(ImageDisplayer, FileManagerAware):
         #         continue
 
 
+@register_image_displayer("ueberzug")
 class UeberzugImageDisplayer(ImageDisplayer):
     """Implementation of ImageDisplayer using ueberzug.
     Ueberzug can display images in a Xorg session.
diff --git a/ranger/ext/rifle.py b/ranger/ext/rifle.py
index a55e14c7..a73a188b 100755
--- a/ranger/ext/rifle.py
+++ b/ranger/ext/rifle.py
@@ -237,7 +237,9 @@ 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':
@@ -293,6 +295,9 @@ class Rifle(object):  # pylint: disable=too-many-instance-attributes
             self._app_flags = ''
             self._app_label = None
             if skip_ask and cmd == ASK_COMMAND:
+                # TODO(vifon): Fix properly, see
+                # https://github.com/ranger/ranger/pull/1341#issuecomment-537264495
+                count += 1
                 continue
             for test in tests:
                 if not self._eval_condition(test, files, None):
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