summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--doc/ranger.133
-rw-r--r--doc/ranger.pod12
-rwxr-xr-xranger/config/commands.py2
-rw-r--r--ranger/config/rc.conf10
-rw-r--r--ranger/core/actions.py19
-rwxr-xr-xranger/data/scope.sh37
-rw-r--r--ranger/gui/ui.py4
-rw-r--r--ranger/gui/widgets/titlebar.py5
8 files changed, 104 insertions, 18 deletions
diff --git a/doc/ranger.1 b/doc/ranger.1
index 060686b8..ea010eac 100644
--- a/doc/ranger.1
+++ b/doc/ranger.1
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35)
+.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
@@ -54,16 +54,20 @@
 .\" Avoid warning from groff about undefined register 'F'.
 .de IX
 ..
-.if !\nF .nr F 0
-.if \nF>0 \{\
-.    de IX
-.    tm Index:\\$1\t\\n%\t"\\$2"
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{\
+.    if \nF \{\
+.        de IX
+.        tm Index:\\$1\t\\n%\t"\\$2"
 ..
-.    if !\nF==2 \{\
-.        nr % 0
-.        nr F 2
+.        if !\nF==2 \{\
+.            nr % 0
+.            nr F 2
+.        \}
 .    \}
 .\}
+.rr rF
 .\"
 .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
 .\" Fear.  Run.  Save yourself.  No user-serviceable parts.
@@ -169,7 +173,7 @@ plugins, sample configuration files and some programs for integrating ranger
 with other software.  They are usually installed to
 \&\fI/usr/share/doc/ranger/examples\fR.
 .PP
-The man page of \fIrifle\fR\|(1) describes the functions of the file opener
+The man page of \fBrifle\fR\|(1) describes the functions of the file opener
 .PP
 The section \fI\s-1LINKS\s0\fR of this man page contains further resources.
 .SH "POSITIONAL ARGUMENTS"
@@ -639,6 +643,9 @@ to use to open the current file selection.
 .IP "cd" 14
 .IX Item "cd"
 Open the console with the content \*(L"cd \*(R"
+.IP "^P" 14
+.IX Item "^P"
+Open the console with the most recent command.
 .IP "Alt\-\fIN\fR" 14
 .IX Item "Alt-N"
 Open a tab. N has to be a number from 0 to 9. If the tab doesn't exist yet, it
@@ -703,6 +710,12 @@ Move up and down (P for previous, N for Next)
 .IP "^A, ^E" 14
 .IX Item "^A, ^E"
 Move to the start or to the end
+.IP "Alt-B, Alt-LEFT" 14
+.IX Item "Alt-B, Alt-LEFT"
+Move backwards by words.
+.IP "Alt-F, Alt-RIGHT" 14
+.IX Item "Alt-F, Alt-RIGHT"
+Move forwards by words.
 .IP "^D" 14
 .IX Item "^D"
 Delete the current character.
@@ -1632,7 +1645,7 @@ copy, run:
 .Ve
 .SH "SEE ALSO"
 .IX Header "SEE ALSO"
-\&\fIrifle\fR\|(1)
+\&\fBrifle\fR\|(1)
 .SH "BUGS"
 .IX Header "BUGS"
 Report bugs here: <https://github.com/ranger/ranger/issues>
diff --git a/doc/ranger.pod b/doc/ranger.pod
index 48e6a41e..5c668235 100644
--- a/doc/ranger.pod
+++ b/doc/ranger.pod
@@ -597,6 +597,10 @@ to use to open the current file selection.
 
 Open the console with the content "cd "
 
+=item ^P
+
+Open the console with the most recent command.
+
 =item Alt-I<N>
 
 Open a tab. N has to be a number from 0 to 9. If the tab doesn't exist yet, it
@@ -690,6 +694,14 @@ Move up and down (P for previous, N for Next)
 
 Move to the start or to the end
 
+=item Alt-B, Alt-LEFT
+
+Move backwards by words.
+
+=item Alt-F, Alt-RIGHT
+
+Move forwards by words.
+
 =item ^D
 
 Delete the current character.
diff --git a/ranger/config/commands.py b/ranger/config/commands.py
index c136db56..d177203a 100755
--- a/ranger/config/commands.py
+++ b/ranger/config/commands.py
@@ -1585,7 +1585,7 @@ class filter_stack(Command):
                 + self.fm.thisdir.filter_stack[:-rotate_by]
             )
         elif subcommand == "show":
-            stack = map(str, self.fm.thisdir.filter_stack)
+            stack = list(map(str, self.fm.thisdir.filter_stack))
             pager = self.fm.ui.open_pager()
             pager.set_source(["Filter stack: "] + stack)
             pager.move(to=100, percentage=True)
diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf
index b112dc2c..9c1a6a83 100644
--- a/ranger/config/rc.conf
+++ b/ranger/config/rc.conf
@@ -349,6 +349,8 @@ map r  chain draw_possible_programs; console open_with%%space
 map f  console find%space
 map cd console cd%space
 
+map <C-p> chain console; eval fm.ui.console.history_move(-1)
+
 # Change the line mode
 map Mf linemode filename
 map Mi linemode fileinfo
@@ -615,8 +617,11 @@ cmap <left>  eval fm.ui.console.move(left=1)
 cmap <right> eval fm.ui.console.move(right=1)
 cmap <home>  eval fm.ui.console.move(right=0, absolute=True)
 cmap <end>   eval fm.ui.console.move(right=-1, absolute=True)
-cmap <a-left>   eval fm.ui.console.move_word(left=1)
-cmap <a-right>  eval fm.ui.console.move_word(right=1)
+cmap <a-b> eval fm.ui.console.move_word(left=1)
+cmap <a-f> eval fm.ui.console.move_word(right=1)
+
+copycmap <a-b> <a-left>
+copycmap <a-f> <a-right>
 
 # Line Editing
 cmap <backspace>  eval fm.ui.console.delete(-1)
@@ -628,6 +633,7 @@ cmap <C-u>        eval fm.ui.console.delete_rest(-1)
 cmap <C-y>        eval fm.ui.console.paste()
 
 # And of course the emacs way
+copycmap <ESC>       <C-g>
 copycmap <up>        <C-p>
 copycmap <down>      <C-n>
 copycmap <left>      <C-b>
diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index 087758c5..1c5459d0 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -240,10 +240,25 @@ class Actions(  # pylint: disable=too-many-instance-attributes,too-many-public-m
         cmd = cmd_class(string, quantifier=quantifier)
 
         if cmd.resolve_macros and _MacroTemplate.delimiter in cmd.line:
-            macros = dict(('any%d' % i, key_to_string(char))
-                          for i, char in enumerate(wildcards if wildcards is not None else []))
+            def any_macro(i, char):
+                return ('any{:d}'.format(i), key_to_string(char))
+
+            def anypath_macro(i, char):
+                try:
+                    val = self.fm.bookmarks[key_to_string(char)]
+                except KeyError:
+                    self.notify('No bookmark defined for `{}`'.format(
+                        key_to_string(char)), bad=True)
+                    val = MACRO_FAIL
+                return ('any_path{:d}'.format(i), val)
+
+            macros = dict(f(i, char) for f in (any_macro, anypath_macro)
+                          for i, char in enumerate(wildcards if wildcards
+                                                   is not None else []))
             if 'any0' in macros:
                 macros['any'] = macros['any0']
+                if 'any_path0' in macros:
+                    macros['any_path'] = macros['any_path0']
             try:
                 line = self.substitute_macros(cmd.line, additional=macros,
                                               escape=cmd.escape_macros_for_shell)
diff --git a/ranger/data/scope.sh b/ranger/data/scope.sh
index 25251533..13a25b45 100755
--- a/ranger/data/scope.sh
+++ b/ranger/data/scope.sh
@@ -123,6 +123,43 @@ handle_image() {
         #              -jpeg -tiffcompression jpeg \
         #              -- "${FILE_PATH}" "${IMAGE_CACHE_PATH%.*}" \
         #         && exit 6 || exit 1;;
+
+        # Preview archives using the first image inside.
+        # (Very useful for comic book collections for example.)
+        # application/zip|application/x-rar|application/x-7z-compressed|\
+        #     application/x-xz|application/x-bzip2|application/x-gzip|application/x-tar)
+        #     local fn=""; local fe=""
+        #     local zip=""; local rar=""; local tar=""; local bsd=""
+        #     case "${mimetype}" in
+        #         application/zip) zip=1 ;;
+        #         application/x-rar) rar=1 ;;
+        #         application/x-7z-compressed) ;;
+        #         *) tar=1 ;;
+        #     esac
+        #     { [ "$tar" ] && fn=$(tar --list --file "${FILE_PATH}"); } || \
+        #     { fn=$(bsdtar --list --file "${FILE_PATH}") && bsd=1 && tar=""; } || \
+        #     { [ "$rar" ] && fn=$(unrar lb -p- -- "${FILE_PATH}"); } || \
+        #     { [ "$zip" ] && fn=$(zipinfo -1 -- "${FILE_PATH}"); } || return
+        #
+        #     fn=$(echo "$fn" | python -c "import sys; import mimetypes as m; \
+        #             [ print(l, end='') for l in sys.stdin if \
+        #               (m.guess_type(l[:-1])[0] or '').startswith('image/') ]" |\
+        #         sort -V | head -n 1)
+        #     [ "$fn" = "" ] && return
+        #     [ "$bsd" ] && fn=$(printf '%b' "$fn")
+        #
+        #     [ "$tar" ] && tar --extract --to-stdout \
+        #         --file "${FILE_PATH}" -- "$fn" > "${IMAGE_CACHE_PATH}" && exit 6
+        #     fe=$(echo -n "$fn" | sed 's/[][*?\]/\\\0/g')
+        #     [ "$bsd" ] && bsdtar --extract --to-stdout \
+        #         --file "${FILE_PATH}" -- "$fe" > "${IMAGE_CACHE_PATH}" && exit 6
+        #     [ "$bsd" ] || [ "$tar" ] && rm -- "${IMAGE_CACHE_PATH}"
+        #     [ "$rar" ] && unrar p -p- -inul -- "${FILE_PATH}" "$fn" > \
+        #         "${IMAGE_CACHE_PATH}" && exit 6
+        #     [ "$zip" ] && unzip -pP "" -- "${FILE_PATH}" "$fe" > \
+        #         "${IMAGE_CACHE_PATH}" && exit 6
+        #     [ "$rar" ] || [ "$zip" ] && rm -- "${IMAGE_CACHE_PATH}"
+        #     ;;
     esac
 }
 
diff --git a/ranger/gui/ui.py b/ranger/gui/ui.py
index 4f76dfab..441e9032 100644
--- a/ranger/gui/ui.py
+++ b/ranger/gui/ui.py
@@ -365,7 +365,9 @@ class UI(  # pylint: disable=too-many-instance-attributes,too-many-public-method
         DisplayableContainer.draw(self)
         if self._draw_title and self.settings.update_title:
             cwd = self.fm.thisdir.path
-            if cwd.startswith(self.fm.home_path):
+            if self.settings.tilde_in_titlebar \
+               and (cwd == self.fm.home_path
+                    or cwd.startswith(self.fm.home_path + "/")):
                 cwd = '~' + cwd[len(self.fm.home_path):]
             if self.settings.shorten_title:
                 split = cwd.rsplit(os.sep, self.settings.shorten_title)
diff --git a/ranger/gui/widgets/titlebar.py b/ranger/gui/widgets/titlebar.py
index 042b4b04..765c1248 100644
--- a/ranger/gui/widgets/titlebar.py
+++ b/ranger/gui/widgets/titlebar.py
@@ -102,8 +102,9 @@ class TitleBar(Widget):
             bar.add(' ', 'hostname', clr, fixed=True)
 
         pathway = self.fm.thistab.pathway
-        if self.settings.tilde_in_titlebar and \
-                self.fm.thisdir.path.startswith(self.fm.home_path):
+        if self.settings.tilde_in_titlebar \
+           and (self.fm.thisdir.path.startswith(self.fm.home_path + "/")
+                or self.fm.thisdir.path == self.fm.home_path):
             pathway = pathway[self.fm.home_path.count('/') + 1:]
             bar.add('~/', 'directory', fixed=True)