From efbbdac00f1ca71615ae83e4f3a9899620454d07 Mon Sep 17 00:00:00 2001 From: squigz Date: Thu, 4 Jan 2018 07:19:44 -0500 Subject: Update manpage with 'draw_separator' setting --- doc/ranger.1 | 5 ++++- doc/ranger.pod | 4 ++++ doc/rifle.1 | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index bb7114a2..39a9c051 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.9.0b6" "12/07/2017" "ranger manual" +.TH RANGER 1 "ranger-1.9.0b6" "01/04/2018" "ranger manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -769,6 +769,9 @@ Display tags in all columns? .IP "draw_borders [bool]" 4 .IX Item "draw_borders [bool]" Draw borders around columns? +.IP "draw_separators [bool]" 4 +.IX Item "draw_separators [bool]" +Draw vertical separators between columns? .IP "draw_progress_bar_in_status_bar [bool]" 4 .IX Item "draw_progress_bar_in_status_bar [bool]" Draw a progress bar in the status bar which displays the average state of all diff --git a/doc/ranger.pod b/doc/ranger.pod index 43926f46..76d879d4 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -759,6 +759,10 @@ Display tags in all columns? Draw borders around columns? +=item draw_separators [bool] + +Draw vertical separators between columns? + =item draw_progress_bar_in_status_bar [bool] Draw a progress bar in the status bar which displays the average state of all diff --git a/doc/rifle.1 b/doc/rifle.1 index 8531d69c..753b3c3c 100644 --- a/doc/rifle.1 +++ b/doc/rifle.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RIFLE 1" -.TH RIFLE 1 "rifle-1.9.0b6" "12/07/2017" "rifle manual" +.TH RIFLE 1 "rifle-1.9.0b6" "01/04/2018" "rifle manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l -- cgit 1.4.1-2-gfad0 From de45af6210e55e053504d734e058b9360e74762b Mon Sep 17 00:00:00 2001 From: squigz Date: Thu, 4 Jan 2018 20:16:37 -0500 Subject: Update manpage section on draw_borders --- doc/ranger.1 | 13 ++++++++++--- doc/ranger.pod | 9 +++++++-- 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index 39a9c051..21665bbf 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -766,9 +766,16 @@ Display the file size in the status bar? .IP "display_tags_in_all_columns [bool]" 4 .IX Item "display_tags_in_all_columns [bool]" Display tags in all columns? -.IP "draw_borders [bool]" 4 -.IX Item "draw_borders [bool]" -Draw borders around columns? +.IP "draw_borders [string]" 4 +.IX Item "draw_borders [string]" +Draw borders around or between the columns? Possible values are: +.Sp +.Vb 4 +\& none no borders of any sort +\& outline draw an outline around all the columns +\& separators draw only vertical lines between columns +\& both both of the above +.Ve .IP "draw_separators [bool]" 4 .IX Item "draw_separators [bool]" Draw vertical separators between columns? diff --git a/doc/ranger.pod b/doc/ranger.pod index 76d879d4..c54b6dfb 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -755,10 +755,15 @@ Display the file size in the status bar? Display tags in all columns? -=item draw_borders [bool] +=item draw_borders [string] -Draw borders around columns? +Draw borders around or between the columns? Possible values are: + none no borders of any sort + outline draw an outline around all the columns + separators draw only vertical lines between columns + both both of the above + =item draw_separators [bool] Draw vertical separators between columns? -- cgit 1.4.1-2-gfad0 From b47a95abbaa6f7c578b98295c3d1846c1e94b260 Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 21 Feb 2018 23:49:48 +0100 Subject: update howto-publish-a-release.md --- doc/howto-publish-a-release.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'doc') diff --git a/doc/howto-publish-a-release.md b/doc/howto-publish-a-release.md index 9b6e1dfe..87d97c92 100644 --- a/doc/howto-publish-a-release.md +++ b/doc/howto-publish-a-release.md @@ -30,7 +30,10 @@ Update the website * [ ] Update both signatures `gpg --local-user 0x00FB5CDF --sign --detach-sign ` * [ ] Update the changelog * [ ] Update the man page -* [ ] Rerun `boobies.py` + * [ ] run `make manhtml` in ranger's repository + * [ ] copy the generated `doc/ranger.1.html` to the `ranger.github.io` repository +* [ ] Rebuild the website, see `README.md` in https://github.com/ranger/ranger.github.io +* [ ] Commit & push the website Make a PyPI release ------------------- @@ -43,7 +46,6 @@ Announce the update ------------------- * [ ] To the mailing list * [ ] In the arch linux forum -* [ ] Write a news entry on savannah Change back to before --------------------- -- cgit 1.4.1-2-gfad0 From efa84a3f2db0ab8a83ed5e37da5be46aa4b388a5 Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 21 Feb 2018 23:52:19 +0100 Subject: removed redundant directive in howto-publish-a-release.md --- doc/howto-publish-a-release.md | 1 - 1 file changed, 1 deletion(-) (limited to 'doc') diff --git a/doc/howto-publish-a-release.md b/doc/howto-publish-a-release.md index 87d97c92..3bd9a9c3 100644 --- a/doc/howto-publish-a-release.md +++ b/doc/howto-publish-a-release.md @@ -28,7 +28,6 @@ Update the website * [ ] Add the new version as `ranger-stable.tar.gz` * [ ] Add the new version as `ranger-X.Y.Z.tar.gz` * [ ] Update both signatures `gpg --local-user 0x00FB5CDF --sign --detach-sign ` -* [ ] Update the changelog * [ ] Update the man page * [ ] run `make manhtml` in ranger's repository * [ ] copy the generated `doc/ranger.1.html` to the `ranger.github.io` repository -- cgit 1.4.1-2-gfad0 From 720e3fd798caa2f8bfd0a19fd9ed5c0eab5dd14c Mon Sep 17 00:00:00 2001 From: Wojciech Siewierski Date: Thu, 22 Feb 2018 14:19:28 +0100 Subject: Please do not turn off your phone while upgrading... --- CHANGELOG.md | 11 +++++++++++ README.md | 2 +- doc/ranger.1 | 6 +++--- doc/rifle.1 | 4 ++-- ranger/__init__.py | 2 +- ranger/ext/rifle.py | 2 +- 6 files changed, 19 insertions(+), 8 deletions(-) (limited to 'doc') diff --git a/CHANGELOG.md b/CHANGELOG.md index e7becb27..346b18dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ This log documents changes between stable versions. +# 2018-02-22: version 1.9.1 +* Fixed the rifle config backwards compatibility (regression in 1.9.0) +* Fixed the POSIX compatibility of `Makefile` +* Fixed `--choosefile`, `--choosefiles` and `--choosedir` so they work + with the process substitution (`>(...)` in Bash) +* Changed the default `gt` binding to `gp` due to a conflict +* Changed the help message for `--choosefile`, `--choosefiles` and + `--choosedir` to avoid confusion +* Changed the behavior of `:reset` to reload the tags too +* Added `geeqie` to the default `rifle.conf` + # 2018-01-25: version 1.9.0 * Fixed memory leak in w3m image preview * Fixed `Q` binding, map it to `quitall` instead of `quit!` diff --git a/README.md b/README.md index ca181b95..ef644ae6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -ranger 1.9.0 +ranger 1.9.1 ============ [![Build Status](https://travis-ci.org/ranger/ranger.svg?branch=master)](https://travis-ci.org/ranger/ranger) diff --git a/doc/ranger.1 b/doc/ranger.1 index f4bdc02f..fca30604 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.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.9.0" "2018-02-05" "ranger manual" +.TH RANGER 1 "ranger-1.9.1" "02/22/2018" "ranger manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -599,7 +599,7 @@ Toggle the mark-status of all files .IP "V" 14 .IX Item "V" Starts the visual mode, which selects all files between the starting point and -the cursor until you press \s-1ESC.\s0 To unselect files in the same way, use \*(L"uV\*(R". +the cursor until you press \s-1ESC. \s0 To unselect files in the same way, use \*(L"uV\*(R". .IP "/" 14 Search for files in the current directory. .IP ":" 14 diff --git a/doc/rifle.1 b/doc/rifle.1 index 755ac959..9e439c35 100644 --- a/doc/rifle.1 +++ b/doc/rifle.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) +.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RIFLE 1" -.TH RIFLE 1 "rifle-1.9.0" "2018-01-25" "rifle manual" +.TH RIFLE 1 "rifle-1.9.1" "02/22/2018" "rifle manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/ranger/__init__.py b/ranger/__init__.py index 60a536a0..0d7c8fdc 100644 --- a/ranger/__init__.py +++ b/ranger/__init__.py @@ -14,7 +14,7 @@ import os # Information __license__ = 'GPL3' -__version__ = '1.9.0' +__version__ = '1.9.1' __author__ = __maintainer__ = 'Roman Zimbelmann' __email__ = 'hut@hut.pm' diff --git a/ranger/ext/rifle.py b/ranger/ext/rifle.py index 8f28cef8..70215039 100755 --- a/ranger/ext/rifle.py +++ b/ranger/ext/rifle.py @@ -21,7 +21,7 @@ import re from subprocess import Popen, PIPE import sys -__version__ = 'rifle 1.9.0' +__version__ = 'rifle 1.9.1' # Options and constants that a user might want to change: DEFAULT_PAGER = 'less' -- cgit 1.4.1-2-gfad0 From d4017ed294358e98ac1c264dce968f44c20f398b Mon Sep 17 00:00:00 2001 From: hut Date: Thu, 22 Feb 2018 00:17:01 +0100 Subject: Added chapter about preparing the stable branch before release --- doc/howto-publish-a-release.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'doc') diff --git a/doc/howto-publish-a-release.md b/doc/howto-publish-a-release.md index 3bd9a9c3..3ff1eb27 100644 --- a/doc/howto-publish-a-release.md +++ b/doc/howto-publish-a-release.md @@ -1,3 +1,26 @@ +Prepare the "stable" branch +--------------------------- +Before you can do anything else, you need to decide what should be included in +the new version. + +**Bugfix releases** bump the third number of the version, e.g. 1.9.0 -> 1.9.1. +They may include bugfix commits that you `git cherry-pick`ed from the master +branch into the stable branch, or you can just do a fast-forward merge of +master into stable, if there were only bugfix commits since the last major +version. You can also add minor new features that are very likely not causing +any bugs. However, there should be absolutely **no** backward-incompatible +changes, like: + +- renamed or removed settings, commands or python functions +- renamed, removed or reordered function arguments +- change in syntax of configuration files or in API of configuration scripts + +New settings are okay, just make sure a sane default value is defined. + +**Major releases** bump the second number of the version, e.g. 1.9.2 -> 1.10.0 +and are necessary if you introduce any breaking changes, like the ones +mentioned in the list above. + Test everything ---------------- * [ ] `make test` -- cgit 1.4.1-2-gfad0 From c2b9dd31de649f19805f07f58814d3054d3c9c54 Mon Sep 17 00:00:00 2001 From: hut Date: Thu, 22 Feb 2018 18:51:06 +0100 Subject: elaborated on how to tag a commit --- doc/howto-publish-a-release.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'doc') diff --git a/doc/howto-publish-a-release.md b/doc/howto-publish-a-release.md index 3ff1eb27..572a2eb7 100644 --- a/doc/howto-publish-a-release.md +++ b/doc/howto-publish-a-release.md @@ -36,7 +36,9 @@ Make a release commit * [ ] `make man` * [ ] Write changelog entry * [ ] Think of a witty commit message -* [ ] Tag signed release +* [ ] Commit +* [ ] Tag the signed release with `git tag -a `, using the same + commit message as annotation * [ ] Push release and tag Make snapshot and test again -- cgit 1.4.1-2-gfad0 From ed4eb4bf282354886e52ae6fa92bf68078edfef6 Mon Sep 17 00:00:00 2001 From: Stephane Fontaine Date: Sat, 24 Feb 2018 21:10:35 +0400 Subject: Add new option to disable display of free disk space in statusbar Fixes #1087 Useful on high-latency filesystems as it avoid calls to statvfs system call which costs: (number of redraw) * latency. --- doc/ranger.1 | 3 +++ doc/ranger.pod | 4 ++++ examples/rc_emacs.conf | 3 +++ ranger/config/rc.conf | 3 +++ ranger/container/settings.py | 1 + ranger/gui/widgets/statusbar.py | 15 ++++++++------- 6 files changed, 22 insertions(+), 7 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index fca30604..9ec79cfd 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -766,6 +766,9 @@ Display the file size in the main column? Display the file size in the status bar? .IP "display_tags_in_all_columns [bool]" 4 .IX Item "display_tags_in_all_columns [bool]" +Display the free disk space in the status bar? +.IP "display_free_space_in_status_bar [bool]" 4 +.IX Item "display_free_space_in_status_bar [bool]" Display tags in all columns? .IP "draw_borders [bool]" 4 .IX Item "draw_borders [bool]" diff --git a/doc/ranger.pod b/doc/ranger.pod index 523d8d9d..04598bd2 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -752,6 +752,10 @@ Display the file size in the main column? Display the file size in the status bar? +=item display_free_space_in_status_bar [bool] + +Display the free disk space in the status bar? + =item display_tags_in_all_columns [bool] Display tags in all columns? diff --git a/examples/rc_emacs.conf b/examples/rc_emacs.conf index 26074a42..4743f8a3 100644 --- a/examples/rc_emacs.conf +++ b/examples/rc_emacs.conf @@ -122,6 +122,9 @@ set mouse_enabled true set display_size_in_main_column true set display_size_in_status_bar true +# Display the free disk space in the status bar? +set display_free_space_in_status_bar true + # Display files tags in all columns or only in main column? set display_tags_in_all_columns true diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 676090fb..51d18ff2 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -137,6 +137,9 @@ set mouse_enabled true set display_size_in_main_column true set display_size_in_status_bar true +# Display the free disk space in the status bar? +set display_free_space_in_status_bar true + # Display files tags in all columns or only in main column? set display_tags_in_all_columns true diff --git a/ranger/container/settings.py b/ranger/container/settings.py index d0b094d0..e87b6e48 100644 --- a/ranger/container/settings.py +++ b/ranger/container/settings.py @@ -38,6 +38,7 @@ ALLOWED_SETTINGS = { 'dirname_in_tabs': bool, 'display_size_in_main_column': bool, 'display_size_in_status_bar': bool, + "display_free_space_in_status_bar": bool, 'display_tags_in_all_columns': bool, 'draw_borders': bool, 'draw_progress_bar_in_status_bar': bool, diff --git a/ranger/gui/widgets/statusbar.py b/ranger/gui/widgets/statusbar.py index 266d48ca..3457955e 100644 --- a/ranger/gui/widgets/statusbar.py +++ b/ranger/gui/widgets/statusbar.py @@ -275,13 +275,14 @@ class StatusBar(Widget): # pylint: disable=too-many-instance-attributes right.add("/" + str(len(target.marked_items))) else: right.add(human_readable(target.disk_usage, separator='') + " sum") - try: - free = get_free_space(target.mount_path) - except OSError: - pass - else: - right.add(", ", "space") - right.add(human_readable(free, separator='') + " free") + if self.settings.display_free_space_in_status_bar: + try: + free = get_free_space(target.mount_path) + except OSError: + pass + else: + right.add(", ", "space") + right.add(human_readable(free, separator='') + " free") right.add(" ", "space") if target.marked_items: -- cgit 1.4.1-2-gfad0 From 6f8fa8b5ef21792a69066500375b3643c50decfb Mon Sep 17 00:00:00 2001 From: Wojciech Siewierski Date: Sun, 4 Mar 2018 14:13:55 +0100 Subject: Add the 'hint_collapse_threshold' that controls when the submaps are collapsed --- doc/ranger.pod | 5 +++++ ranger/config/rc.conf | 4 ++++ ranger/container/settings.py | 1 + ranger/gui/widgets/view_base.py | 21 ++++++++++++++++----- 4 files changed, 26 insertions(+), 5 deletions(-) (limited to 'doc') diff --git a/doc/ranger.pod b/doc/ranger.pod index 523d8d9d..71a9342d 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -791,6 +791,11 @@ this pattern will hide all files that start with a dot or end with a tilde. set hidden_filter ^\.|~$ +=item hint_collapse_threshold [int] + +The key hint lists up to this size have their sublists expanded. +Otherwise the submaps are replaced with "...". + =item idle_delay [integer] The delay that ranger idly waits for user input, in milliseconds, with a diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 676090fb..fe00c7c0 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -216,6 +216,10 @@ set cd_tab_fuzzy false # disable this feature. set preview_max_size 0 +# The key hint lists up to this size have their sublists expanded. +# Otherwise the submaps are replaced with "...". +set hint_collapse_threshold 10 + # Add the highlighted file to the path in the titlebar set show_selection_in_titlebar true diff --git a/ranger/container/settings.py b/ranger/container/settings.py index d0b094d0..8b7364a2 100644 --- a/ranger/container/settings.py +++ b/ranger/container/settings.py @@ -45,6 +45,7 @@ ALLOWED_SETTINGS = { 'freeze_files': bool, 'global_inode_type_filter': str, 'hidden_filter': str, + 'hint_collapse_threshold' : int, 'hostname_in_titlebar': bool, 'idle_delay': int, 'iterm2_font_width': int, diff --git a/ranger/gui/widgets/view_base.py b/ranger/gui/widgets/view_base.py index b005f1d5..0878ab0f 100644 --- a/ranger/gui/widgets/view_base.py +++ b/ranger/gui/widgets/view_base.py @@ -132,7 +132,7 @@ class ViewBase(Widget, DisplayableContainer): # pylint: disable=too-many-instan """ from itertools import groupby - # groupby needs the list to be sorted + # groupby needs the list to be sorted. hints.sort(key=lambda t: t[0]) def group_hints(hints): @@ -147,13 +147,24 @@ class ViewBase(Widget, DisplayableContainer): # pylint: disable=too-many-instan in groupby( hints, key=first_key)) - hints = sorted( - group_hints(hints), - key=lambda g: g[0][1]) # sort by the first action in group + + grouped_hints = group_hints(hints) + + # If there are too many hints, collapse the sublists. + if len(hints) > self.fm.settings.hint_collapse_threshold: + def first_key_in_group(group): + return group[0][0][0] + grouped_hints = [[(first_key_in_group(hint_group), "...")] + if len(hint_group) > 1 + else hint_group + for hint_group in grouped_hints] + + # Sort by the first action in group. + grouped_hints = sorted(grouped_hints, key=lambda g: g[0][1]) def flatten(nested_list): return [item for inner_list in nested_list for item in inner_list] - return flatten(hints) + return flatten(grouped_hints) hints = sort_hints(hints) hei = min(self.hei - 1, len(hints)) -- cgit 1.4.1-2-gfad0 From 727fd3aa19b904e6359d76792735fa155015a0ec Mon Sep 17 00:00:00 2001 From: Wojciech Siewierski Date: Sun, 4 Mar 2018 14:24:32 +0100 Subject: Update the manpage --- doc/ranger.1 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index fca30604..ded6a5d6 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.9.1" "02/22/2018" "ranger manual" +.TH RANGER 1 "ranger-1.9.1" "03/04/2018" "ranger manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -800,6 +800,10 @@ this pattern will hide all files that start with a dot or end with a tilde. .Vb 1 \& set hidden_filter ^\e.|~$ .Ve +.IP "hint_collapse_threshold [int]" 4 +.IX Item "hint_collapse_threshold [int]" +The key hint lists up to this size have their sublists expanded. +Otherwise the submaps are replaced with \*(L"...\*(R". .IP "idle_delay [integer]" 4 .IX Item "idle_delay [integer]" The delay that ranger idly waits for user input, in milliseconds, with a -- cgit 1.4.1-2-gfad0 From 4c9b2143d39d09fd286ec79419b00852b5d181ff Mon Sep 17 00:00:00 2001 From: Wojciech Siewierski Date: Mon, 5 Mar 2018 18:25:56 +0100 Subject: doc/ranger.1: Reorder the settings alphabetically --- doc/ranger.1 | 8 ++++---- doc/ranger.pod | 8 ++++---- doc/rifle.1 | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index ded6a5d6..f362d263 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.9.1" "03/04/2018" "ranger manual" +.TH RANGER 1 "ranger-1.9.1" "05.03.2018" "ranger manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -804,6 +804,9 @@ this pattern will hide all files that start with a dot or end with a tilde. .IX Item "hint_collapse_threshold [int]" The key hint lists up to this size have their sublists expanded. Otherwise the submaps are replaced with \*(L"...\*(R". +.IP "hostname_in_titlebar [bool]" 4 +.IX Item "hostname_in_titlebar [bool]" +Show hostname in titlebar? .IP "idle_delay [integer]" 4 .IX Item "idle_delay [integer]" The delay that ranger idly waits for user input, in milliseconds, with a @@ -936,9 +939,6 @@ combination, e.g. \*(L"oN\*(R" to sort from Z to A. .IP "status_bar_on_top [bool]" 4 .IX Item "status_bar_on_top [bool]" Put the status bar at the top of the window? -.IP "hostname_in_titlebar [bool]" 4 -.IX Item "hostname_in_titlebar [bool]" -Show hostname in titlebar? .IP "tilde_in_titlebar [bool]" 4 .IX Item "tilde_in_titlebar [bool]" Abbreviate \f(CW$HOME\fR with ~ in the titlebar (first line) of ranger? diff --git a/doc/ranger.pod b/doc/ranger.pod index 71a9342d..8599a1a6 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -796,6 +796,10 @@ this pattern will hide all files that start with a dot or end with a tilde. The key hint lists up to this size have their sublists expanded. Otherwise the submaps are replaced with "...". +=item hostname_in_titlebar [bool] + +Show hostname in titlebar? + =item idle_delay [integer] The delay that ranger idly waits for user input, in milliseconds, with a @@ -956,10 +960,6 @@ combination, e.g. "oN" to sort from Z to A. Put the status bar at the top of the window? -=item hostname_in_titlebar [bool] - -Show hostname in titlebar? - =item tilde_in_titlebar [bool] Abbreviate $HOME with ~ in the titlebar (first line) of ranger? diff --git a/doc/rifle.1 b/doc/rifle.1 index 9e439c35..ad32e4f4 100644 --- a/doc/rifle.1 +++ b/doc/rifle.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RIFLE 1" -.TH RIFLE 1 "rifle-1.9.1" "02/22/2018" "rifle manual" +.TH RIFLE 1 "rifle-1.9.1" "05.03.2018" "rifle manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l -- cgit 1.4.1-2-gfad0 From 4d9d271d458aa65a69a897ab26a64771fd63f056 Mon Sep 17 00:00:00 2001 From: toonn Date: Sat, 31 Mar 2018 16:43:07 +0200 Subject: Added positional arguments section to manpage The optional positional argument "path" wasn't documented, changed the argument to "path ..." because you can provide more than one and documented what happens. Added a sentence to the `--selectfile` item pointing out it's superceded by the positional arguments. --- doc/ranger.1 | 17 ++++++++++++----- doc/ranger.pod | 17 +++++++++++++++-- 2 files changed, 27 insertions(+), 7 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index f362d263..7f307490 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.9.1" "05.03.2018" "ranger manual" +.TH RANGER 1 "ranger-1.9.1" "2018-03-31" "ranger manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -145,7 +145,7 @@ ranger \- visual file manager [\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] +[\fB\-\-profile\fR] [\fB\-\-cmd\fR=\fIcommand\fR] [\fIpath ...\fR] .SH "DESCRIPTION" .IX Header "DESCRIPTION" ranger is a console file manager with \s-1VI\s0 key bindings. @@ -172,6 +172,12 @@ with other software. They are usually installed to The man page of \fIrifle\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" +.IX Header "POSITIONAL ARGUMENTS" +.IP "\fIpath ...\fR" 14 +.IX Item "path ..." +Each path will be opened in a tab and if the path is a file it will be selected. +Omitting this is equivalent to providing the current directory. .SH "OPTIONS" .IX Header "OPTIONS" .IP "\fB\-d\fR, \fB\-\-debug\fR" 14 @@ -225,7 +231,8 @@ Allows you to pick a directory with ranger. When you exit ranger, it will 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. +Open ranger with \fItargetfile\fR selected. This is a legacy option, superseded by +the behavior for the \s-1POSITIONAL ARGUMENTS.\s0 .IP "\fB\-\-show\-only\-dirs\fR" 14 .IX Item "--show-only-dirs" Display only the directories. May be used in conjunction with @@ -599,7 +606,7 @@ Toggle the mark-status of all files .IP "V" 14 .IX Item "V" Starts the visual mode, which selects all files between the starting point and -the cursor until you press \s-1ESC. \s0 To unselect files in the same way, use \*(L"uV\*(R". +the cursor until you press \s-1ESC.\s0 To unselect files in the same way, use \*(L"uV\*(R". .IP "/" 14 Search for files in the current directory. .IP ":" 14 diff --git a/doc/ranger.pod b/doc/ranger.pod index 8599a1a6..470eaa7e 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -14,7 +14,7 @@ B [B<--version>] [B<--help>] [B<--debug>] [B<--clean>] [B<--choosedir>=I] [B<--selectfile>=I] [B<--show-only-dirs>] [B<--list-unused-keys>] [B<--list-tagged-files>=I] -[B<--profile>] [B<--cmd>=I] [I] +[B<--profile>] [B<--cmd>=I] [I] @@ -53,6 +53,18 @@ The section I of this man page contains further resources. +=head1 POSITIONAL ARGUMENTS + +=over 14 + +=item I + +Each path will be opened in a tab and if the path is a file it will be selected. +Omitting this is equivalent to providing the current directory. + + + + =head1 OPTIONS =over 14 @@ -117,7 +129,8 @@ write the last visited directory into I. =item B<--selectfile>=I -Open ranger with I selected. +Open ranger with I selected. This is a legacy option, superseded by +the behavior for the POSITIONAL ARGUMENTS. =item B<--show-only-dirs> -- cgit 1.4.1-2-gfad0 From a938392ddb43169712dda6809f3b55e396c46dfb Mon Sep 17 00:00:00 2001 From: hut Date: Sun, 1 Apr 2018 13:21:17 +0200 Subject: Apply patch from debian package: 0004-fix-type-in-manpage.patch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Description: Fix typo in manpage Author: Mateusz Łukasik --- doc/ranger.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index f362d263..745f1032 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -702,7 +702,7 @@ in ranger. .IP "automatically_count_files [bool]" 4 .IX Item "automatically_count_files [bool]" Should ranger count and display the number of files in each directory -as soon as it's visible? This gets slow with remote file sytems. Turning it +as soon as it's visible? This gets slow with remote file systems. Turning it off will still allow you to see the number of files after entering the directory. .IP "autosave_bookmarks [bool]" 4 -- cgit 1.4.1-2-gfad0 From 3c430ba0f1b3fe2e17225788866f37bcd1f85c3b Mon Sep 17 00:00:00 2001 From: toonn Date: Tue, 3 Apr 2018 14:10:35 +0200 Subject: Document change in :cd behavior Added a sentence about the file selecting behavior of `:cd` to the docstring and the manpage. Added missing `=back` to POSITIONAL ARGUMENTS section in the manpage. --- doc/ranger.1 | 12 ++++++------ doc/ranger.pod | 10 ++++++---- ranger/config/commands.py | 3 ++- 3 files changed, 14 insertions(+), 11 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index 7f307490..bd6116d1 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.9.1" "2018-03-31" "ranger manual" +.TH RANGER 1 "ranger-1.9.1" "2018-04-03" "ranger manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -996,7 +996,7 @@ ranger. For your convenience, this is a list of the \*(L"public\*(R" commands i .Vb 10 \& alias [newcommand] [oldcommand] \& bulkrename -\& cd [directory] +\& cd [path] \& chain command1[; command2[; command3...]] \& chmod octal_number \& cmap key command @@ -1072,10 +1072,10 @@ renaming according to the changes you did in the file. .Sp This shell script is opened in an editor for you to review. After you close it, it will be executed. -.IP "cd [\fIdirectory\fR]" 2 -.IX Item "cd [directory]" -The cd command changes the directory. The command \f(CW\*(C`:cd \-\*(C'\fR is equivalent to -typing ``. +.IP "cd [\fIpath\fR]" 2 +.IX Item "cd [path]" +The cd command changes the directory. If path is a file, selects that file. +The command \f(CW\*(C`:cd \-\*(C'\fR is equivalent to typing ``. .IP "chain \fIcommand1\fR[; \fIcommand2\fR[; \fIcommand3\fR...]]" 2 .IX Item "chain command1[; command2[; command3...]]" Combines multiple commands into one, separated by semicolons. diff --git a/doc/ranger.pod b/doc/ranger.pod index 470eaa7e..4b0e90b1 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -62,6 +62,8 @@ The section I of this man page contains further resources. Each path will be opened in a tab and if the path is a file it will be selected. Omitting this is equivalent to providing the current directory. +=back + @@ -1033,7 +1035,7 @@ ranger. For your convenience, this is a list of the "public" commands including alias [newcommand] [oldcommand] bulkrename - cd [directory] + cd [path] chain command1[; command2[; command3...]] chmod octal_number cmap key command @@ -1113,10 +1115,10 @@ renaming according to the changes you did in the file. This shell script is opened in an editor for you to review. After you close it, it will be executed. -=item cd [I] +=item cd [I] -The cd command changes the directory. The command C<:cd -> is equivalent to -typing ``. +The cd command changes the directory. If path is a file, selects that file. +The command C<:cd -> is equivalent to typing ``. =item chain I[; I[; I...]] diff --git a/ranger/config/commands.py b/ranger/config/commands.py index a3837d8e..2f1480b9 100755 --- a/ranger/config/commands.py +++ b/ranger/config/commands.py @@ -120,9 +120,10 @@ class echo(Command): class cd(Command): - """:cd [-r] + """:cd [-r] The cd command changes the directory. + If the path is a file, selects that file. The command 'cd -' is equivalent to typing ``. Using the option "-r" will get you to the real path. """ -- cgit 1.4.1-2-gfad0 From 107b72e74cf740489c8eae7464b9ee24dcaeed6e Mon Sep 17 00:00:00 2001 From: toonn Date: Mon, 16 Apr 2018 12:38:01 +0200 Subject: Add support for mutool pdf previews in scope.sh --- README.md | 2 +- doc/ranger.1 | 10 +++++----- doc/ranger.pod | 2 +- ranger/data/scope.sh | 1 + 4 files changed, 8 insertions(+), 7 deletions(-) (limited to 'doc') diff --git a/README.md b/README.md index ef644ae6..df17f731 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ Optional, for enhanced file previews (with `scope.sh`): * `highlight` or `pygmentize` for syntax highlighting of code * `atool`, `bsdtar` and/or `unrar` for previews of archives * `lynx`, `w3m` or `elinks` for previews of html pages -* `pdftotext` for pdf previews +* `pdftotext` or `mutool` for pdf previews * `transmission-show` for viewing bit-torrent information * `mediainfo` or `exiftool` for viewing information about media files * `odt2txt` for OpenDocument text files (`odt`, `ods`, `odp` and `sxw`) diff --git a/doc/ranger.1 b/doc/ranger.1 index 745f1032..71310541 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.9.1" "05.03.2018" "ranger manual" +.TH RANGER 1 "ranger-1.9.1" "2018-04-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 @@ -270,7 +270,7 @@ scripts by setting the option \f(CW\*(C`use_preview_script\*(C'\fR and \f(CW\*(C This default script is \fI~/.config/ranger/scope.sh\fR. It contains more documentation and calls to the programs \fIlynx\fR and \fIelinks\fR for html, \&\fIhighlight\fR for text/code, \fIimg2txt\fR for images, \fIatool\fR for archives, -\&\fIpdftotext\fR for PDFs and \fImediainfo\fR for video and audio files. +\&\fIpdftotext\fR or \fImutool\fR for PDFs and \fImediainfo\fR for video and audio files. .PP Install these programs (just the ones you need) and scope.sh will automatically use them. @@ -599,7 +599,7 @@ Toggle the mark-status of all files .IP "V" 14 .IX Item "V" Starts the visual mode, which selects all files between the starting point and -the cursor until you press \s-1ESC. \s0 To unselect files in the same way, use \*(L"uV\*(R". +the cursor until you press \s-1ESC.\s0 To unselect files in the same way, use \*(L"uV\*(R". .IP "/" 14 Search for files in the current directory. .IP ":" 14 @@ -702,7 +702,7 @@ in ranger. .IP "automatically_count_files [bool]" 4 .IX Item "automatically_count_files [bool]" Should ranger count and display the number of files in each directory -as soon as it's visible? This gets slow with remote file systems. Turning it +as soon as it's visible? This gets slow with remote file sytems. Turning it off will still allow you to see the number of files after entering the directory. .IP "autosave_bookmarks [bool]" 4 diff --git a/doc/ranger.pod b/doc/ranger.pod index 8599a1a6..41bafdd3 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -177,7 +177,7 @@ scripts by setting the option C and C to true This default script is F<~/.config/ranger/scope.sh>. It contains more documentation and calls to the programs I and I for html, I for text/code, I for images, I for archives, -I for PDFs and I for video and audio files. +I or I for PDFs and I for video and audio files. Install these programs (just the ones you need) and scope.sh will automatically use them. diff --git a/ranger/data/scope.sh b/ranger/data/scope.sh index 540a910e..f7a0f589 100755 --- a/ranger/data/scope.sh +++ b/ranger/data/scope.sh @@ -61,6 +61,7 @@ handle_extension() { pdf) # Preview as text conversion pdftotext -l 10 -nopgbrk -q -- "${FILE_PATH}" - && exit 5 + mutool draw -F txt -i -- "${FILE_PATH}" 1-10 && exit 5 exiftool "${FILE_PATH}" && exit 5 exit 1;; -- cgit 1.4.1-2-gfad0 From f6af1ebad94b902d61f73b00978272018e2ef438 Mon Sep 17 00:00:00 2001 From: toonn Date: Mon, 16 Apr 2018 14:13:49 +0200 Subject: Refix typo "sytem" --- doc/ranger.1 | 2 +- doc/ranger.pod | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index 71310541..238aafd5 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -702,7 +702,7 @@ in ranger. .IP "automatically_count_files [bool]" 4 .IX Item "automatically_count_files [bool]" Should ranger count and display the number of files in each directory -as soon as it's visible? This gets slow with remote file sytems. Turning it +as soon as it's visible? This gets slow with remote file systems. Turning it off will still allow you to see the number of files after entering the directory. .IP "autosave_bookmarks [bool]" 4 diff --git a/doc/ranger.pod b/doc/ranger.pod index 41bafdd3..0a34209a 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -678,7 +678,7 @@ in ranger. =item automatically_count_files [bool] Should ranger count and display the number of files in each directory -as soon as it's visible? This gets slow with remote file sytems. Turning it +as soon as it's visible? This gets slow with remote file systems. Turning it off will still allow you to see the number of files after entering the directory. -- cgit 1.4.1-2-gfad0 From 5ddfc6477643ffd3690d430f2f04d2b340d5e6a3 Mon Sep 17 00:00:00 2001 From: toonn Date: Tue, 8 May 2018 12:15:43 +0200 Subject: Document system-wide configuration files. --- doc/ranger.1 | 9 ++++++--- doc/ranger.pod | 7 +++++-- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index ab47de61..352b6a27 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.9.0" "2018-01-28" "ranger manual" +.TH RANGER 1 "ranger-1.9.0" "2018-05-08" "ranger manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -267,7 +267,7 @@ typing \fI"\fR. By default, only text files are previewed, but you can enable external preview scripts by setting the option \f(CW\*(C`use_preview_script\*(C'\fR and \f(CW\*(C`preview_files\*(C'\fR to true. .PP -This default script is \fI~/.config/ranger/scope.sh\fR. It contains more +This default script is \fI\f(CI%rangerdir\fI/data/scope.sh\fR. It contains more documentation and calls to the programs \fIlynx\fR and \fIelinks\fR for html, \&\fIhighlight\fR for text/code, \fIimg2txt\fR for images, \fIatool\fR for archives, \&\fIpdftotext\fR for PDFs and \fImediainfo\fR for video and audio files. @@ -463,7 +463,7 @@ sample plugins in the \fI/usr/share/doc/ranger/examples/\fR directory, including hello-world plugin that describes this procedure. .SH "KEY BINDINGS" .IX Header "KEY BINDINGS" -Key bindings are defined in the file \fIranger/config/rc.conf\fR. Check this +Key bindings are defined in the file \fI\f(CI%rangerdir\fI/config/rc.conf\fR. Check this file for a list of all key bindings. You can copy it to your local configuration directory with the \-\-copy\-config=rc option. .PP @@ -1421,6 +1421,9 @@ being bound despite the corresponding line being removed from the user's copy of the configuration file. This behavior may be disabled with an environment variable (see also: \fB\s-1ENVIRONMENT\s0\fR). Note: All other configuration files only read from one source; i.e. default \s-1OR\s0 user, not both. +\&\fIrc.conf\fR and \fIcommands.py\fR are additionally read from \fI/etc/ranger\fR if they +exist for system-wide configuration, user configuration overrides system +configuration which overrides the default configuration. .PP When starting ranger with the \fB\-\-clean\fR option, it will not access or create any of these files. diff --git a/doc/ranger.pod b/doc/ranger.pod index ee869393..69adc78e 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -174,7 +174,7 @@ typing I<">. By default, only text files are previewed, but you can enable external preview scripts by setting the option C and C to true. -This default script is F<~/.config/ranger/scope.sh>. It contains more +This default script is F<%rangerdir/data/scope.sh>. It contains more documentation and calls to the programs I and I for html, I for text/code, I for images, I for archives, I for PDFs and I for video and audio files. @@ -364,7 +364,7 @@ hello-world plugin that describes this procedure. =head1 KEY BINDINGS -Key bindings are defined in the file F. Check this +Key bindings are defined in the file F<%rangerdir/config/rc.conf>. Check this file for a list of all key bindings. You can copy it to your local configuration directory with the --copy-config=rc option. @@ -1507,6 +1507,9 @@ being bound despite the corresponding line being removed from the user's copy of the configuration file. This behavior may be disabled with an environment variable (see also: B). Note: All other configuration files only read from one source; i.e. default OR user, not both. +F and F are additionally read from F if they +exist for system-wide configuration, user configuration overrides system +configuration which overrides the default configuration. When starting ranger with the B<--clean> option, it will not access or create any of these files. -- cgit 1.4.1-2-gfad0 From b512e309a0a09ee88c6866535ed23ec80f7aaef9 Mon Sep 17 00:00:00 2001 From: mark-dawn Date: Wed, 14 Feb 2018 01:16:38 +0100 Subject: Kitty image display alpha, merge-ready Added more comments to the code reverted changes to default values in rc.conf addes explanations in rc.config about the new options Couple of small stylistic corrections after running make test Updated the man pages --- doc/ranger.1 | 17 ++++ doc/ranger.pod | 15 ++++ ranger/config/rc.conf | 19 ++++- ranger/container/settings.py | 3 +- ranger/ext/img_display.py | 182 +++++++++++++++++++++++-------------------- 5 files changed, 147 insertions(+), 89 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index 1290cb58..f8f0bd8c 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -324,6 +324,23 @@ The same as urxvt but utilizing not only the preview pane but the whole terminal window. .PP To enable this feature, set the option \f(CW\*(C`preview_images_method\*(C'\fR to urxvt-full. +.PP +\fIkitty\fR +.IX Subsection "kitty" +.PP +This only works on Kitty. +It requires \s-1PIL\s0 or pillow at the moment to work. A nasty bug that can +corrupt the terminal window when scrolling quicly many images, that can +be solved by with the \f(CW\*(C`redraw_window\*(C'\fR command. +.PP +To enable this feature, set the option \f(CW\*(C`preview_images_method\*(C'\fR to kitty +.PP +\fIkitty-network\fR +.IX Subsection "kitty-network" +.PP +The same as kitty, but uses a streaming method to allow previews remotely, +for example in an ssh session. However the system is slighly more computationally taxing +and the quality of the preview is reduced for bandwidth considerations. .SS "\s-1SELECTION\s0" .IX Subsection "SELECTION" The \fIselection\fR is defined as \*(L"All marked files \s-1IF THERE ARE ANY,\s0 otherwise diff --git a/doc/ranger.pod b/doc/ranger.pod index 4cac8ef9..79a61a98 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -236,6 +236,21 @@ window. To enable this feature, set the option C to urxvt-full. +=head3 kitty + +This only works on Kitty. +It requires PIL or pillow at the moment to work. A nasty bug that can +corrupt the terminal window when scrolling quicly many images, that can +be solved by with the C command. + +To enable this feature, set the option C to kitty + +=head3 kitty-network + +The same as kitty, but uses a streaming method to allow previews remotely, +for example in an ssh session. However the system is slighly more computationally taxing +and the quality of the preview is reduced for bandwidth considerations. + =head2 SELECTION The I is defined as "All marked files IF THERE ARE ANY, otherwise diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index bf858a50..b8bc00d8 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -68,7 +68,7 @@ set vcs_backend_bzr disabled set vcs_backend_svn disabled # Use one of the supported image preview protocols -set preview_images true +set preview_images false # Set the preview image method. Supported methods: # @@ -93,7 +93,22 @@ set preview_images true # * urxvt-full: # The same as urxvt but utilizing not only the preview pane but the # whole terminal window. -set preview_images_method kitty +# +# * kitty: +# Preview images in full color using kitty image protocol +# (https://github.com/kovidgoyal/kitty/blob/master/graphics-protocol.asciidoc), +# Requires python PIL or pillow library. +# In experimental stage: tmux support is untested, and a scrolling too fast a folder with many images may glitch ranger; +# Future improvements to kitty will ameliorate this issue, for now call the command 'redraw_window' to get rid of the garbage. +# +# * kitty-network +# Similar to base kitty, bit instead of local storage it uses kitty's protocol special feature to +# stream the whole image over standard input. More error prone, and more intensive since it scales down images, +# producing also worse quality previews. +# However it makes possible to see previews froma ranger instance over the network, +# so it makes sense to enable this on remote machines. +# Note that has been untested over an actual network. +set preview_images_method w3m # Default iTerm2 font size (see: preview_images_method: iterm2) set iterm2_font_width 8 diff --git a/ranger/container/settings.py b/ranger/container/settings.py index 170ace5a..dcadf8bf 100644 --- a/ranger/container/settings.py +++ b/ranger/container/settings.py @@ -100,7 +100,8 @@ ALLOWED_VALUES = { 'confirm_on_delete': ['multiple', 'always', 'never'], 'line_numbers': ['false', 'absolute', 'relative'], 'one_indexed': [False, True], - 'preview_images_method': ['w3m', 'iterm2', 'urxvt', 'urxvt-full'], + 'preview_images_method': ['w3m', 'iterm2', 'urxvt', + 'urxvt-full', 'kitty', 'kitty-network'], 'vcs_backend_bzr': ['disabled', 'local', 'enabled'], 'vcs_backend_git': ['enabled', 'disabled', 'local'], 'vcs_backend_hg': ['disabled', 'local', 'enabled'], diff --git a/ranger/ext/img_display.py b/ranger/ext/img_display.py index f34315e3..122e3a15 100644 --- a/ranger/ext/img_display.py +++ b/ranger/ext/img_display.py @@ -25,7 +25,8 @@ import termios import select from contextlib import contextmanager import tty -import fcntl +import codecs +from tempfile import NamedTemporaryFile from ranger.core.shared import FileManagerAware @@ -472,10 +473,19 @@ class URXVTImageFSDisplayer(URXVTImageDisplayer): class KittyImageDisplayer(ImageDisplayer): - """TODO: Document here the relevant parts of the protocol""" + """Implementation of ImageDisplayer for kitty (https://github.com/kovidgoyal/kitty/) + terminal. It uses the built APC to send commands and data to kitty, + which in turn renders the image. The APC takes the form + '\033_Gk=v,k=v...;bbbbbbbbbbbbbb\033\\' + | ---------- -------------- | + escape code | | escape code + | base64 encoded payload + key: value pairs as parameters + For more info please head over to : + https://github.com/kovidgoyal/kitty/blob/master/graphics-protocol.asciidoc""" + protocol_start = b'\033_G' + protocol_end = b'\033\\' def __init__(self, stream=False, resize_height=720): - self.protocol_start = b'\033_G' - self.protocol_end = b'\033\\' self.image_id = 0 self.temp_paths = [] # parameter deciding if we're going to send the picture data @@ -486,97 +496,98 @@ class KittyImageDisplayer(ImageDisplayer): if "screen" in os.environ['TERM']: # TODO: probably need to modify the preamble pass - # TODO: implement check if protocol terminal supports protocol - + # TODO: implement check if protocol terminal supports kitty protocol + # Poissibbly automatically check if transfer via file is possible, + # and if negative switch to streaming mode? + self.backend = None try: # pillow is the default since we are not going # to spawn other processes, so it _should_ be faster import PIL.Image - self.backend=PIL.Image + self.backend = PIL.Image self.filter = PIL.Image.BILINEAR except ImportError: - sys.stderr.write("PIL not Found, trying ImageMagick") - # TODO: check for ImageMagick - pass + sys.stderr.write("PIL not Found") + # TODO: implement a wrapper class for Imagemagick process to + # replicate the functionality we use from im def draw(self, path, start_x, start_y, width, height): # dictionary to store the command arguments for kitty # a is the display command, with T going for immediate output - cmds = {'a': 'T', 'm': 1} - - # let's open the image - if self.backend: - im = self.backend.open(path) - # first let's reduce the size of the image if we intend to stream it - aspect = im.width / im.height - if im.height > self.max_height: - im = im.resize((int(self.max_height * aspect), self.max_height), self.filter) - # since kitty streches the image to fill the view box - # we need to resize the box to not get distortion - cell_ratio = 0.5 - dest_aspect = width * cell_ratio / height - mismatch_ratio = aspect/dest_aspect - if mismatch_ratio > 1.02: - new_h = height / mismatch_ratio - start_y += int((height - new_h) / 2) - height = int(new_h) - elif mismatch_ratio < 0.98: - new_w = width * mismatch_ratio - start_x += int((width - new_w) / 2) - width = int(new_w) - # encode image or just the filename and save the image - elif self.backend == "immgk": - pass + cmds = {'a': 'T'} + # sys.stderr.write('{}-{}@{}x{}\t'.format(start_x, start_y, width, height)) + assert self.backend is not None # sanity check if we actually have a backend + image = self.backend.open(path) + aspect = image.width / image.height + # first let's reduce the size of the image if we intend to stream it + if image.height > self.max_height: + image = image.resize((int(self.max_height * aspect), self.max_height), self.filter) + # since kitty streches the image to fill the view box + # we need to resize the box to not get distortion + mismatch_ratio = aspect / (width * 0.5 / height) + if mismatch_ratio > 1.05: + new_h = height / mismatch_ratio + start_y += int((height - new_h) / 2) + height = int(new_h) + elif mismatch_ratio < 0.95: + new_w = width * mismatch_ratio + start_x += int((width - new_w) / 2) + width = int(new_w) if self.stream: - if im.mode != 'RGB' or im.mode != 'RGBA': - im = im.convert('RGB') - cmds.update({'t': 'd', 'f': len(im.getbands()) * 8, - 's': im.width, 'v': im.height, - 'c': width, 'r': height}) - raw = bytearray().join(map(bytes, im.getdata())) # TODO: check speed - payload = base64.standard_b64encode(raw) + # encode the whole image as base64 + # TODO: implement z compression + # to possibly increase resolution in sent image + if image.mode != 'RGB' or image.mode != 'RGBA': + image = image.convert('RGB') + # t: transmissium medium, 'd' for embedded + # f: size of a pixel fragment (8bytes per color) + # s, v: size of the image to recompose the flattened data + # c, r: size in cells of the viewbox + cmds.update({'t': 'd', 'f': len(image.getbands()) * 8, + 's': image.width, 'v': image.height, + 'c': width, 'r': height}) + payload = base64.standard_b64encode( + bytearray().join(map(bytes, image.getdata()))) else: - from tempfile import NamedTemporaryFile + # put the image in a temporary png file + # we need to find out the encoding for a path string, ascii won't cut it try: - fsenc = sys.getfilesystemencoding() or 'utf-8' + fsenc = sys.getfilesystemencoding() # returns None if standard utf-8 is used + # throws LookupError if can't find the codec, TypeError if fsenc is None codecs.lookup(fsenc) - except Exception: + except (LookupError, TypeError): fsenc = 'utf-8' + # t: transmissium medium, 't' for temporary file (kitty will delete it for us) + # f: size of a pixel fragment (100 just mean that the file is png encoded, + # the only format except raw RGB(A) bitmap that kitty understand) + # c, r: size in cells of the viewbox cmds.update({'t': 't', 'f': 100, 'c': width, 'r': height}) with NamedTemporaryFile(prefix='rgr_thumb_', suffix='.png', delete=False) as tmpf: - im.save(tmpf, format='png', compress_level=0) + image.save(tmpf, format='png', compress_level=0) self.temp_paths.append(tmpf.name) payload = base64.standard_b64encode(os.path.abspath(tmpf.name).encode(fsenc)) self.image_id += 1 + # image handle we'll use with kitty cmds['i'] = self.image_id - # now for some good old retrocompatibility C protocols # save current cursor position curses.putp(curses.tigetstr("sc")) # we then can move the cursor to our desired spot - # for some reason none is using curses.move(y, x) - # but this convoluted method - tparm = curses.tparm(curses.tigetstr("cup"), start_y, start_x) - if sys.version_info[0] < 3: - sys.stdout.write(tparm) - else: - sys.stdout.buffer.write(tparm) + # we can't call window.move(y, x) since we don't have the curses win instance + sys.stdout.buffer.write(curses.tparm(curses.tigetstr("cup"), start_y, start_x)) - #finally send the command + # finally send the command for cmd_str in self._format_cmd_str(cmds, payload=payload): sys.stdout.buffer.write(cmd_str) sys.stdout.flush() # to catch the incoming response (which breaks ranger) # a simple readline doesn't work, but this seems fine - with self.non_blocking_read() as fd: - while True: - rd = select.select([fd], [], [], 2 if self.stream else 0.1)[0] - if rd: - data = sys.stdin.buffer.read() #TODO: check if all is well - break - else: - break + # except when scrolling real fast. If kitty will implemnt a key to suppress + # responses this will be omitted + with self.non_blocking_read() as f_descr: + if select.select([f_descr], [], [], 2 if self.stream else 0.1)[0]: + sys.stdin.buffer.read() # TODO: check if all is well # Restore cursor curses.putp(curses.tigetstr("rc")) sys.stdout.flush() @@ -584,14 +595,16 @@ class KittyImageDisplayer(ImageDisplayer): def _format_cmd_str(self, cmd, payload=None, max_l=1024): central_blk = ','.join(["{}={}".format(k, v) for k, v in cmd.items()]).encode('ascii') if payload is not None: + # we add the m key to signal a multiframe communication + # appending the end (m=0) key to a single message has no effect while len(payload) > max_l: payload_blk, payload = payload[:max_l], payload[max_l:] yield self.protocol_start + \ - central_blk + b',m=1;' + payload_blk + \ - self.protocol_end - yield self.protocol_start + \ - central_blk + b',m=0;' + payload + \ + central_blk + b',m=1;' + payload_blk + \ self.protocol_end + yield self.protocol_start + \ + central_blk + b',m=0;' + payload + \ + self.protocol_end else: yield self.protocol_start + central_blk + b';' + self.protocol_end @@ -599,41 +612,38 @@ class KittyImageDisplayer(ImageDisplayer): @contextmanager def non_blocking_read(src=sys.stdin): # not entirely sure what's going on here - fd = src.fileno() + # but sure it looks like tty black magic + f_handle = src.fileno() if src.isatty(): - old = termios.tcgetattr(fd) - tty.setraw(fd) - oldfl = fcntl.fcntl(fd, fcntl.F_GETFL) - fcntl.fcntl(fd, fcntl.F_SETFL, oldfl | os.O_NONBLOCK) - yield fd + old = termios.tcgetattr(f_handle) + tty.setraw(f_handle) + oldfl = fcntl.fcntl(f_handle, fcntl.F_GETFL) + # this seems the juicy part were we actally set the non_blockingness + fcntl.fcntl(f_handle, fcntl.F_SETFL, oldfl | os.O_NONBLOCK) + yield f_handle + # after the with block is done we are resetting back to the old state if src.isatty(): - termios.tcsetattr(fd, termios.TCSADRAIN, old) - fcntl.fcntl(fd, fcntl.F_SETFL, oldfl) + termios.tcsetattr(f_handle, termios.TCSADRAIN, old) + fcntl.fcntl(f_handle, fcntl.F_SETFL, oldfl) def clear(self, start_x, start_y, width, height): # let's assume that every time ranger call this # it actually wants just to remove the previous image + # TODO: implement this using the actual x, y, since the protocol supports it cmds = {'a': 'd', 'i': self.image_id} for cmd_str in self._format_cmd_str(cmds): sys.stdout.buffer.write(cmd_str) sys.stdout.flush() -# with self.non_blocking_read() as fd: -# while True: -# rd = select.select([fd], [], [], 2 if self.stream else 0.3)[0] -# if rd: -# data = sys.stdin.buffer.read() #TODO: check if all is well -# break -# else: -# break + # kitty doesn't seem to reply on deletes, checking like we do in draw() + # will slows down scrolling with timeouts from select self.image_id -= 1 def quit(self): # clear all remaining images, then check if all files went through or are orphaned while self.image_id >= 1: - self.clear(0,0,0,0) - while len(self.temp_paths) != 0: + self.clear(0, 0, 0, 0) + while self.temp_paths: try: os.remove(self.temp_paths.pop()) except FileNotFoundError: continue - -- cgit 1.4.1-2-gfad0 From c7528ea081cd621829dd23c4e47d67d8d2da6a9b Mon Sep 17 00:00:00 2001 From: mark-dawn Date: Fri, 16 Feb 2018 03:13:29 +0100 Subject: Bugfixes & Improvements Fixed support for terminology terminal emulator Fixed the annoying bug affecting fast scrolling (tnkx@kovidgoyal) Refactored some code repeated for the whole module Eliminated some dependencies --- doc/ranger.1 | 6 ++ doc/ranger.pod | 5 ++ ranger/config/rc.conf | 4 + ranger/core/fm.py | 2 +- ranger/ext/img_display.py | 219 ++++++++++++++++++++++------------------------ 5 files changed, 120 insertions(+), 116 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index f8f0bd8c..a0fc79a1 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -307,6 +307,12 @@ This feature relies on the dimensions of the terminal's font. By default, a width of 8 and height of 11 are used. To use other values, set the options \&\f(CW\*(C`iterm2_font_width\*(C'\fR and \f(CW\*(C`iterm2_font_height\*(C'\fR to the desired values. .PP +\fIterminology\fR +.IX Subsection "terminology" +.PP +This only works in terminology. It can render vectors graphics, but works only locally. +To enable this feature, set the option \f(CW\*(C`preview_images_method\*(C'\fR to terminology. +.PP \fIurxvt\fR .IX Subsection "urxvt" .PP diff --git a/doc/ranger.pod b/doc/ranger.pod index 79a61a98..fbe20012 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -220,6 +220,11 @@ This feature relies on the dimensions of the terminal's font. By default, a width of 8 and height of 11 are used. To use other values, set the options C and C to the desired values. +=head3 terminology + +This only works in terminology. It can render vectors graphics, but works only locally. +To enable this feature, set the option C to terminology. + =head3 urxvt This only works in urxvt compiled with pixbuf support. Does not work over ssh. diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index b8bc00d8..cf27cbb5 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -86,6 +86,10 @@ set preview_images false # width of 8 and height of 11 are used. To use other values, set the options # iterm2_font_width and iterm2_font_height to the desired values. # +# * terminology: +# Previews images in full color in the terminology terminal emulator. +# Supports a wide variety of formats, even vector graphics like svg +# # * urxvt: # Preview images in full color using urxvt image backgrounds. This # requires using urxvt compiled with pixbuf support. diff --git a/ranger/core/fm.py b/ranger/core/fm.py index 26feb948..226b1461 100644 --- a/ranger/core/fm.py +++ b/ranger/core/fm.py @@ -225,7 +225,7 @@ class FM(Actions, # pylint: disable=too-many-instance-attributes for line in entry.splitlines(): yield line - def _get_image_displayer(self): + 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": diff --git a/ranger/ext/img_display.py b/ranger/ext/img_display.py index 122e3a15..09d3429c 100644 --- a/ranger/ext/img_display.py +++ b/ranger/ext/img_display.py @@ -22,9 +22,7 @@ import sys from subprocess import Popen, PIPE import termios -import select from contextlib import contextmanager -import tty import codecs from tempfile import NamedTemporaryFile @@ -40,6 +38,29 @@ W3MIMGDISPLAY_PATHS = [ '/usr/local/libexec/w3m/w3mimgdisplay', ] +# Helper functions shared between the previewers (make them static methods of the base class?) + + +@contextmanager +def temporarly_moved_cursor(to_y, to_x): + """Common boilerplate code to move the cursor to a drawing area. Use it as: + with temporarly_moved_cursor(dest_y, dest_x): + your_func_here()""" + curses.putp(curses.tigetstr("sc")) + move_cur(to_y, to_x) + yield + curses.putp(curses.tigetstr("rc")) + sys.stdout.flush() + + +# this is excised since Terminology needs to move the cursor multiple times +def move_cur(to_y, to_x): + tparm = curses.tparm(curses.tigetstr("cup"), to_y, to_x) + if sys.version_info[0] < 3: + sys.stdout.write(tparm) + else: + sys.stdout.buffer.write(tparm) + class ImageDisplayError(Exception): pass @@ -215,15 +236,8 @@ class ITerm2ImageDisplayer(ImageDisplayer, FileManagerAware): """ def draw(self, path, start_x, start_y, width, height): - curses.putp(curses.tigetstr("sc")) - tparm = curses.tparm(curses.tigetstr("cup"), start_y, start_x) - if sys.version_info[0] < 3: - sys.stdout.write(tparm) - else: - sys.stdout.buffer.write(tparm) # pylint: disable=no-member - sys.stdout.write(self._generate_iterm2_input(path, width, height)) - curses.putp(curses.tigetstr("rc")) - sys.stdout.flush() + with temporarly_moved_cursor(start_y, start_x): + sys.stdout.write(self._generate_iterm2_input(path, width, height)) def clear(self, start_x, start_y, width, height): self.fm.ui.win.redrawwin() @@ -332,44 +346,23 @@ class TerminologyImageDisplayer(ImageDisplayer, FileManagerAware): self.close_protocol = "\000" def draw(self, path, start_x, start_y, width, height): - # Save cursor - curses.putp(curses.tigetstr("sc")) - - y = start_y - # Move to drawing zone - self._move_to(start_x, y) - - # Write intent - sys.stdout.write("%s}ic#%d;%d;%s%s" % ( - self.display_protocol, - width, height, - path, - self.close_protocol)) - - # Write Replacement commands ('#') - for _ in range(0, height): - sys.stdout.write("%s}ib%s%s%s}ie%s" % ( - self.display_protocol, - self.close_protocol, - "#" * width, + with temporarly_moved_cursor(start_y, start_x): + # Write intent + sys.stdout.write("%s}ic#%d;%d;%s%s" % ( self.display_protocol, + width, height, + path, self.close_protocol)) - y = y + 1 - self._move_to(start_x, y) - - # Restore cursor - curses.putp(curses.tigetstr("rc")) - - sys.stdout.flush() - @staticmethod - def _move_to(x, y): - # curses.move(y, x) - tparm = curses.tparm(curses.tigetstr("cup"), y, x) - if sys.version_info[0] < 3: - sys.stdout.write(tparm) - else: - sys.stdout.buffer.write(tparm) # pylint: disable=no-member + # Write Replacement commands ('#') + for y in range(0, height): + move_cur(start_y + y, start_x) + sys.stdout.write("%s}ib%s%s%s}ie%s\n" % ( # needs a newline to work + self.display_protocol, + self.close_protocol, + "#" * width, + self.display_protocol, + self.close_protocol)) def clear(self, start_x, start_y, width, height): self.fm.ui.win.redrawwin() @@ -485,20 +478,49 @@ class KittyImageDisplayer(ImageDisplayer): https://github.com/kovidgoyal/kitty/blob/master/graphics-protocol.asciidoc""" protocol_start = b'\033_G' protocol_end = b'\033\\' + def __init__(self, stream=False, resize_height=720): self.image_id = 0 self.temp_paths = [] # parameter deciding if we're going to send the picture data # in the command body, or save it to a temporary file - # the former being default since it is network aware self.stream = stream self.max_height = resize_height + if "screen" in os.environ['TERM']: # TODO: probably need to modify the preamble pass - # TODO: implement check if protocol terminal supports kitty protocol - # Poissibbly automatically check if transfer via file is possible, - # and if negative switch to streaming mode? + + # we need to find out the encoding for a path string, ascii won't cut it + try: + self.fsenc = sys.getfilesystemencoding() # returns None if standard utf-8 is used + # throws LookupError if can't find the codec, TypeError if fsenc is None + codecs.lookup(self.fsenc) + except (LookupError, TypeError): + self.fsenc = 'utf-8' + + # automatic check if we share the filesystem using a dummy file + # TODO: this doesn't work somehow, the response from kitty appears on + # the tty, and until a newline is inserted the data won't be sent + # to the stdin we have. This works just fine in draw. Something tells me that since this is + # called early the tubes are not set up correctly yet, but I have no idea how to fix it + # + # with NamedTemporaryFile() as tmpf: + # tmpf.write(bytearray([0xFA]*3)) + # tmpf.flush() + # for cmd in self._format_cmd_str({'i': 1, 'f': 24,'t': 'f', 's': 1, 'v': 1, 'S': 3}, + # payload=base64.standard_b64encode(tmpf.name.encode(self.fsenc))): + # sys.stdout.buffer.write(cmd) + # resp = [b''] + # sys.stdout.flush() + # for _ in range(5): + # while resp[-1] != b'\\': + # resp.append(sys.stdin.buffer.read(1)) + # if b''.join(resp[-4:-2]) == b'OK': + # self.stream = False + # else: + # self.stream = True + self.backend = None try: # pillow is the default since we are not going @@ -511,17 +533,21 @@ class KittyImageDisplayer(ImageDisplayer): # TODO: implement a wrapper class for Imagemagick process to # replicate the functionality we use from im - def draw(self, path, start_x, start_y, width, height): + def draw(self, path, start_x, start_y, width, height): # pylint: disable=too-many-locals + self.image_id += 1 # dictionary to store the command arguments for kitty # a is the display command, with T going for immediate output - cmds = {'a': 'T'} + # i is the id entifier for the image + cmds = {'a': 'T', 'i': self.image_id} # sys.stderr.write('{}-{}@{}x{}\t'.format(start_x, start_y, width, height)) + assert self.backend is not None # sanity check if we actually have a backend image = self.backend.open(path) aspect = image.width / image.height - # first let's reduce the size of the image if we intend to stream it + # first let's reduce the size of the image if image.height > self.max_height: image = image.resize((int(self.max_height * aspect), self.max_height), self.filter) + # since kitty streches the image to fill the view box # we need to resize the box to not get distortion mismatch_ratio = aspect / (width * 0.5 / height) @@ -538,7 +564,7 @@ class KittyImageDisplayer(ImageDisplayer): # encode the whole image as base64 # TODO: implement z compression # to possibly increase resolution in sent image - if image.mode != 'RGB' or image.mode != 'RGBA': + if image.mode != 'RGB' and image.mode != 'RGBA': image = image.convert('RGB') # t: transmissium medium, 'd' for embedded # f: size of a pixel fragment (8bytes per color) @@ -551,13 +577,6 @@ class KittyImageDisplayer(ImageDisplayer): bytearray().join(map(bytes, image.getdata()))) else: # put the image in a temporary png file - # we need to find out the encoding for a path string, ascii won't cut it - try: - fsenc = sys.getfilesystemencoding() # returns None if standard utf-8 is used - # throws LookupError if can't find the codec, TypeError if fsenc is None - codecs.lookup(fsenc) - except (LookupError, TypeError): - fsenc = 'utf-8' # t: transmissium medium, 't' for temporary file (kitty will delete it for us) # f: size of a pixel fragment (100 just mean that the file is png encoded, # the only format except raw RGB(A) bitmap that kitty understand) @@ -566,33 +585,33 @@ class KittyImageDisplayer(ImageDisplayer): with NamedTemporaryFile(prefix='rgr_thumb_', suffix='.png', delete=False) as tmpf: image.save(tmpf, format='png', compress_level=0) self.temp_paths.append(tmpf.name) - payload = base64.standard_b64encode(os.path.abspath(tmpf.name).encode(fsenc)) + payload = base64.standard_b64encode(tmpf.name.encode(self.fsenc)) + + with temporarly_moved_cursor(start_y, start_x): + for cmd_str in self._format_cmd_str(cmds, payload=payload): + sys.stdout.buffer.write(cmd_str) + # catch kitty answer before the escape codes corrupt the console + resp = [b''] + while resp[-1] != b'\\': + resp.append(sys.stdin.buffer.read(1)) + if b''.join(resp[-4:-2]) == b'OK': + return + else: + raise ImageDisplayError - self.image_id += 1 - # image handle we'll use with kitty - cmds['i'] = self.image_id - # save current cursor position - curses.putp(curses.tigetstr("sc")) - # we then can move the cursor to our desired spot - # we can't call window.move(y, x) since we don't have the curses win instance - sys.stdout.buffer.write(curses.tparm(curses.tigetstr("cup"), start_y, start_x)) - - # finally send the command - for cmd_str in self._format_cmd_str(cmds, payload=payload): + def clear(self, start_x, start_y, width, height): + # let's assume that every time ranger call this + # it actually wants just to remove the previous image + # TODO: implement this using the actual x, y, since the protocol supports it + cmds = {'a': 'd', 'i': self.image_id} + for cmd_str in self._format_cmd_str(cmds): sys.stdout.buffer.write(cmd_str) sys.stdout.flush() - # to catch the incoming response (which breaks ranger) - # a simple readline doesn't work, but this seems fine - # except when scrolling real fast. If kitty will implemnt a key to suppress - # responses this will be omitted - with self.non_blocking_read() as f_descr: - if select.select([f_descr], [], [], 2 if self.stream else 0.1)[0]: - sys.stdin.buffer.read() # TODO: check if all is well - # Restore cursor - curses.putp(curses.tigetstr("rc")) - sys.stdout.flush() + # kitty doesn't seem to reply on deletes, checking like we do in draw() + # will slows down scrolling with timeouts from select + self.image_id -= 1 - def _format_cmd_str(self, cmd, payload=None, max_l=1024): + def _format_cmd_str(self, cmd, payload=None, max_l=2048): central_blk = ','.join(["{}={}".format(k, v) for k, v in cmd.items()]).encode('ascii') if payload is not None: # we add the m key to signal a multiframe communication @@ -608,36 +627,6 @@ class KittyImageDisplayer(ImageDisplayer): else: yield self.protocol_start + central_blk + b';' + self.protocol_end - @staticmethod - @contextmanager - def non_blocking_read(src=sys.stdin): - # not entirely sure what's going on here - # but sure it looks like tty black magic - f_handle = src.fileno() - if src.isatty(): - old = termios.tcgetattr(f_handle) - tty.setraw(f_handle) - oldfl = fcntl.fcntl(f_handle, fcntl.F_GETFL) - # this seems the juicy part were we actally set the non_blockingness - fcntl.fcntl(f_handle, fcntl.F_SETFL, oldfl | os.O_NONBLOCK) - yield f_handle - # after the with block is done we are resetting back to the old state - if src.isatty(): - termios.tcsetattr(f_handle, termios.TCSADRAIN, old) - fcntl.fcntl(f_handle, fcntl.F_SETFL, oldfl) - - def clear(self, start_x, start_y, width, height): - # let's assume that every time ranger call this - # it actually wants just to remove the previous image - # TODO: implement this using the actual x, y, since the protocol supports it - cmds = {'a': 'd', 'i': self.image_id} - for cmd_str in self._format_cmd_str(cmds): - sys.stdout.buffer.write(cmd_str) - sys.stdout.flush() - # kitty doesn't seem to reply on deletes, checking like we do in draw() - # will slows down scrolling with timeouts from select - self.image_id -= 1 - def quit(self): # clear all remaining images, then check if all files went through or are orphaned while self.image_id >= 1: @@ -645,5 +634,5 @@ class KittyImageDisplayer(ImageDisplayer): while self.temp_paths: try: os.remove(self.temp_paths.pop()) - except FileNotFoundError: + except IOError: continue -- cgit 1.4.1-2-gfad0 From 3c428cad7e752c38a282ba1c83190eb41fc4ff3a Mon Sep 17 00:00:00 2001 From: mark-dawn Date: Sun, 18 Feb 2018 15:06:20 +0100 Subject: Grammar Fixes Fixed grammar horrors in ranger.pod and ranger.conf Improved resize handling --- doc/ranger.pod | 12 ++++-------- ranger/config/rc.conf | 16 +++++++--------- ranger/container/settings.py | 2 +- ranger/core/fm.py | 2 +- ranger/ext/img_display.py | 43 ++++++++++++++++++++++++++----------------- 5 files changed, 39 insertions(+), 36 deletions(-) (limited to 'doc') diff --git a/doc/ranger.pod b/doc/ranger.pod index fbe20012..a45ab2e4 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -222,7 +222,7 @@ C and C to the desired values. =head3 terminology -This only works in terminology. It can render vectors graphics, but works only locally. +This only works in terminology. It can render vector graphics, but works only locally. To enable this feature, set the option C to terminology. =head3 urxvt @@ -243,18 +243,14 @@ To enable this feature, set the option C to urxvt-full. =head3 kitty -This only works on Kitty. -It requires PIL or pillow at the moment to work. A nasty bug that can -corrupt the terminal window when scrolling quicly many images, that can -be solved by with the C command. +This only works on Kitty. It requires PIL (or pillow) to work. -To enable this feature, set the option C to kitty +To enable this feature, set the option C to kitty. =head3 kitty-network The same as kitty, but uses a streaming method to allow previews remotely, -for example in an ssh session. However the system is slighly more computationally taxing -and the quality of the preview is reduced for bandwidth considerations. +for example in an ssh session. However the system is more computationally taxing. =head2 SELECTION diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index cf27cbb5..7adbc239 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -88,7 +88,7 @@ set preview_images false # # * terminology: # Previews images in full color in the terminology terminal emulator. -# Supports a wide variety of formats, even vector graphics like svg +# Supports a wide variety of formats, even vector graphics like svg. # # * urxvt: # Preview images in full color using urxvt image backgrounds. This @@ -99,17 +99,15 @@ set preview_images false # whole terminal window. # # * kitty: -# Preview images in full color using kitty image protocol -# (https://github.com/kovidgoyal/kitty/blob/master/graphics-protocol.asciidoc), +# Preview images in full color using kitty image protocol. # Requires python PIL or pillow library. -# In experimental stage: tmux support is untested, and a scrolling too fast a folder with many images may glitch ranger; -# Future improvements to kitty will ameliorate this issue, for now call the command 'redraw_window' to get rid of the garbage. +# Tmux support is untested. # # * kitty-network -# Similar to base kitty, bit instead of local storage it uses kitty's protocol special feature to -# stream the whole image over standard input. More error prone, and more intensive since it scales down images, -# producing also worse quality previews. -# However it makes possible to see previews froma ranger instance over the network, +# Similar to base kitty, but instead of local storage it streams the whole image +# over standard input. More error prone, +# and more intensive since it base64 encodes entire images. +# However it makes possible to see previews from ranger over the network, # so it makes sense to enable this on remote machines. # Note that has been untested over an actual network. set preview_images_method w3m diff --git a/ranger/container/settings.py b/ranger/container/settings.py index dcadf8bf..b360cf20 100644 --- a/ranger/container/settings.py +++ b/ranger/container/settings.py @@ -100,7 +100,7 @@ ALLOWED_VALUES = { 'confirm_on_delete': ['multiple', 'always', 'never'], 'line_numbers': ['false', 'absolute', 'relative'], 'one_indexed': [False, True], - 'preview_images_method': ['w3m', 'iterm2', 'urxvt', + 'preview_images_method': ['w3m', 'iterm2', 'terminology', 'urxvt', 'urxvt-full', 'kitty', 'kitty-network'], 'vcs_backend_bzr': ['disabled', 'local', 'enabled'], 'vcs_backend_git': ['enabled', 'disabled', 'local'], diff --git a/ranger/core/fm.py b/ranger/core/fm.py index 226b1461..5f4e141d 100644 --- a/ranger/core/fm.py +++ b/ranger/core/fm.py @@ -239,7 +239,7 @@ class FM(Actions, # pylint: disable=too-many-instance-attributes elif self.settings.preview_images_method == "kitty": return KittyImageDisplayer() elif self.settings.preview_images_method == "kitty-network": - return KittyImageDisplayer(stream=True, resize_height=480) + return KittyImageDisplayer(stream=True) return ImageDisplayer() def _get_thisfile(self): diff --git a/ranger/ext/img_display.py b/ranger/ext/img_display.py index 09d3429c..f444e0f9 100644 --- a/ranger/ext/img_display.py +++ b/ranger/ext/img_display.py @@ -11,6 +11,7 @@ implementations, which are currently w3m, iTerm2 and urxvt. from __future__ import (absolute_import, division, print_function) +import math import base64 import curses import errno @@ -42,9 +43,9 @@ W3MIMGDISPLAY_PATHS = [ @contextmanager -def temporarly_moved_cursor(to_y, to_x): +def temporarily_moved_cursor(to_y, to_x): """Common boilerplate code to move the cursor to a drawing area. Use it as: - with temporarly_moved_cursor(dest_y, dest_x): + with temporarily_moved_cursor(dest_y, dest_x): your_func_here()""" curses.putp(curses.tigetstr("sc")) move_cur(to_y, to_x) @@ -236,7 +237,7 @@ class ITerm2ImageDisplayer(ImageDisplayer, FileManagerAware): """ def draw(self, path, start_x, start_y, width, height): - with temporarly_moved_cursor(start_y, start_x): + with temporarily_moved_cursor(start_y, start_x): sys.stdout.write(self._generate_iterm2_input(path, width, height)) def clear(self, start_x, start_y, width, height): @@ -346,7 +347,7 @@ class TerminologyImageDisplayer(ImageDisplayer, FileManagerAware): self.close_protocol = "\000" def draw(self, path, start_x, start_y, width, height): - with temporarly_moved_cursor(start_y, start_x): + with temporarily_moved_cursor(start_y, start_x): # Write intent sys.stdout.write("%s}ic#%d;%d;%s%s" % ( self.display_protocol, @@ -479,13 +480,12 @@ class KittyImageDisplayer(ImageDisplayer): protocol_start = b'\033_G' protocol_end = b'\033\\' - def __init__(self, stream=False, resize_height=720): + def __init__(self, stream=False): self.image_id = 0 self.temp_paths = [] # parameter deciding if we're going to send the picture data # in the command body, or save it to a temporary file self.stream = stream - self.max_height = resize_height if "screen" in os.environ['TERM']: # TODO: probably need to modify the preamble @@ -527,7 +527,7 @@ class KittyImageDisplayer(ImageDisplayer): # to spawn other processes, so it _should_ be faster import PIL.Image self.backend = PIL.Image - self.filter = PIL.Image.BILINEAR + self.filter = PIL.Image.LANCZOS except ImportError: sys.stderr.write("PIL not Found") # TODO: implement a wrapper class for Imagemagick process to @@ -543,24 +543,23 @@ class KittyImageDisplayer(ImageDisplayer): assert self.backend is not None # sanity check if we actually have a backend image = self.backend.open(path) - aspect = image.width / image.height - # first let's reduce the size of the image - if image.height > self.max_height: - image = image.resize((int(self.max_height * aspect), self.max_height), self.filter) - # since kitty streches the image to fill the view box # we need to resize the box to not get distortion - mismatch_ratio = aspect / (width * 0.5 / height) + mismatch_ratio = (image.width / image.height) / (width * 0.5 / height) if mismatch_ratio > 1.05: new_h = height / mismatch_ratio - start_y += int((height - new_h) / 2) + start_y += int((height - new_h) // 2) height = int(new_h) elif mismatch_ratio < 0.95: new_w = width * mismatch_ratio - start_x += int((width - new_w) / 2) + start_x += int((width - new_w) // 2) width = int(new_w) + # resize image to a smaller size. Ideally this should be + # image = self._resize_max_area(image, (480*960), self.filter) + if self.stream: + image = self._resize_max_area(image, (480 * 960), self.filter) # encode the whole image as base64 # TODO: implement z compression # to possibly increase resolution in sent image @@ -581,13 +580,14 @@ class KittyImageDisplayer(ImageDisplayer): # f: size of a pixel fragment (100 just mean that the file is png encoded, # the only format except raw RGB(A) bitmap that kitty understand) # c, r: size in cells of the viewbox - cmds.update({'t': 't', 'f': 100, 'c': width, 'r': height}) + cmds.update({'t': 't', 'f': 100, + 'c': width, 'r': height}) with NamedTemporaryFile(prefix='rgr_thumb_', suffix='.png', delete=False) as tmpf: image.save(tmpf, format='png', compress_level=0) self.temp_paths.append(tmpf.name) payload = base64.standard_b64encode(tmpf.name.encode(self.fsenc)) - with temporarly_moved_cursor(start_y, start_x): + with temporarily_moved_cursor(start_y, start_x): for cmd_str in self._format_cmd_str(cmds, payload=payload): sys.stdout.buffer.write(cmd_str) # catch kitty answer before the escape codes corrupt the console @@ -627,6 +627,15 @@ class KittyImageDisplayer(ImageDisplayer): else: yield self.protocol_start + central_blk + b';' + self.protocol_end + @staticmethod + def _resize_max_area(image, max_area, img_filter): + aspect = image.width / image.height + area = image.width * image.height + if area > max_area: + image = image.resize((int(math.sqrt(area * aspect)), + int(math.sqrt(area / aspect))), img_filter) + return image + def quit(self): # clear all remaining images, then check if all files went through or are orphaned while self.image_id >= 1: -- cgit 1.4.1-2-gfad0 From 5bde5d533557968deda1e37db49d9d8650925786 Mon Sep 17 00:00:00 2001 From: mark-dawn Date: Tue, 20 Feb 2018 02:46:42 +0100 Subject: Automatic network detection, python2 and Exception fixes Created late_init method to handle task dependent on late facilities Enabled automatic network detection (required stdin to be properly init) Fixed proper handling of import Errors (required ranger Exception handling) Fixed handling of binary stdio differnces between py2/3 Unified said handling aross the module --- doc/ranger.pod | 7 +-- ranger/config/rc.conf | 12 ++--- ranger/container/settings.py | 4 +- ranger/core/fm.py | 2 - ranger/ext/img_display.py | 110 ++++++++++++++++++++++++------------------- 5 files changed, 70 insertions(+), 65 deletions(-) (limited to 'doc') diff --git a/doc/ranger.pod b/doc/ranger.pod index a45ab2e4..887f704d 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -244,14 +244,11 @@ To enable this feature, set the option C to urxvt-full. =head3 kitty This only works on Kitty. It requires PIL (or pillow) to work. +It is able to automatically work over network, +by switching to a slower transfer method. To enable this feature, set the option C to kitty. -=head3 kitty-network - -The same as kitty, but uses a streaming method to allow previews remotely, -for example in an ssh session. However the system is more computationally taxing. - =head2 SELECTION The I is defined as "All marked files IF THERE ARE ANY, otherwise diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 7adbc239..305143c1 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -101,15 +101,11 @@ set preview_images false # * kitty: # Preview images in full color using kitty image protocol. # Requires python PIL or pillow library. +# If ranger does not share the local filesystem with kitty +# the transfer method is switched to encoding the whole image in +# the protocol that, while slower, allows remote previews, +# for example during an ssh session. # Tmux support is untested. -# -# * kitty-network -# Similar to base kitty, but instead of local storage it streams the whole image -# over standard input. More error prone, -# and more intensive since it base64 encodes entire images. -# However it makes possible to see previews from ranger over the network, -# so it makes sense to enable this on remote machines. -# Note that has been untested over an actual network. set preview_images_method w3m # Default iTerm2 font size (see: preview_images_method: iterm2) diff --git a/ranger/container/settings.py b/ranger/container/settings.py index b360cf20..b9695301 100644 --- a/ranger/container/settings.py +++ b/ranger/container/settings.py @@ -100,8 +100,8 @@ ALLOWED_VALUES = { 'confirm_on_delete': ['multiple', 'always', 'never'], 'line_numbers': ['false', 'absolute', 'relative'], 'one_indexed': [False, True], - 'preview_images_method': ['w3m', 'iterm2', 'terminology', 'urxvt', - 'urxvt-full', 'kitty', 'kitty-network'], + 'preview_images_method': ['w3m', 'iterm2', 'terminology', + 'urxvt', 'urxvt-full', 'kitty'], 'vcs_backend_bzr': ['disabled', 'local', 'enabled'], 'vcs_backend_git': ['enabled', 'disabled', 'local'], 'vcs_backend_hg': ['disabled', 'local', 'enabled'], diff --git a/ranger/core/fm.py b/ranger/core/fm.py index 5f4e141d..f3a19f0a 100644 --- a/ranger/core/fm.py +++ b/ranger/core/fm.py @@ -238,8 +238,6 @@ class FM(Actions, # pylint: disable=too-many-instance-attributes return URXVTImageFSDisplayer() elif self.settings.preview_images_method == "kitty": return KittyImageDisplayer() - elif self.settings.preview_images_method == "kitty-network": - return KittyImageDisplayer(stream=True) return ImageDisplayer() def _get_thisfile(self): diff --git a/ranger/ext/img_display.py b/ranger/ext/img_display.py index f444e0f9..387d61a3 100644 --- a/ranger/ext/img_display.py +++ b/ranger/ext/img_display.py @@ -57,10 +57,9 @@ def temporarily_moved_cursor(to_y, to_x): # this is excised since Terminology needs to move the cursor multiple times def move_cur(to_y, to_x): tparm = curses.tparm(curses.tigetstr("cup"), to_y, to_x) - if sys.version_info[0] < 3: - sys.stdout.write(tparm) - else: - sys.stdout.buffer.write(tparm) + # on python2 stdout is already in binary mode, in python3 is accessed via buffer + bin_stdout = getattr(sys.stdout, 'buffer', sys.stdout) + bin_stdout.write(tparm) class ImageDisplayError(Exception): @@ -479,60 +478,72 @@ class KittyImageDisplayer(ImageDisplayer): https://github.com/kovidgoyal/kitty/blob/master/graphics-protocol.asciidoc""" protocol_start = b'\033_G' protocol_end = b'\033\\' + # we are going to use stdio in binary mode a lot, so due to py2 -> py3 + # differnces is worth to do this: + stdbout = getattr(sys.stdout, 'buffer', sys.stdout) + stdbin = getattr(sys.stdin, 'buffer', sys.stdin) + # counter for image ids on kitty's end + image_id = 0 + # we need to find out the encoding for a path string, ascii won't cut it + try: + fsenc = sys.getfilesystemencoding() # returns None if standard utf-8 is used + # throws LookupError if can't find the codec, TypeError if fsenc is None + codecs.lookup(fsenc) + except (LookupError, TypeError): + fsenc = 'utf-8' - def __init__(self, stream=False): - self.image_id = 0 + def __init__(self): self.temp_paths = [] - # parameter deciding if we're going to send the picture data - # in the command body, or save it to a temporary file - self.stream = stream if "screen" in os.environ['TERM']: # TODO: probably need to modify the preamble pass - # we need to find out the encoding for a path string, ascii won't cut it - try: - self.fsenc = sys.getfilesystemencoding() # returns None if standard utf-8 is used - # throws LookupError if can't find the codec, TypeError if fsenc is None - codecs.lookup(self.fsenc) - except (LookupError, TypeError): - self.fsenc = 'utf-8' + # the rest of the initializations that require reading stdio or raising exceptions + # are delayed to the first draw call, since curses + # and ranger exception handler are not online at __init__() time + self.needs_late_init = True + # to init in _late_init() + self.backend = None + self.stream = None + def _late_init(self): # automatic check if we share the filesystem using a dummy file - # TODO: this doesn't work somehow, the response from kitty appears on - # the tty, and until a newline is inserted the data won't be sent - # to the stdin we have. This works just fine in draw. Something tells me that since this is - # called early the tubes are not set up correctly yet, but I have no idea how to fix it - # - # with NamedTemporaryFile() as tmpf: - # tmpf.write(bytearray([0xFA]*3)) - # tmpf.flush() - # for cmd in self._format_cmd_str({'i': 1, 'f': 24,'t': 'f', 's': 1, 'v': 1, 'S': 3}, - # payload=base64.standard_b64encode(tmpf.name.encode(self.fsenc))): - # sys.stdout.buffer.write(cmd) - # resp = [b''] - # sys.stdout.flush() - # for _ in range(5): - # while resp[-1] != b'\\': - # resp.append(sys.stdin.buffer.read(1)) - # if b''.join(resp[-4:-2]) == b'OK': - # self.stream = False - # else: - # self.stream = True + with NamedTemporaryFile() as tmpf: + tmpf.write(bytearray([0xFF] * 3)) + tmpf.flush() + for cmd in self._format_cmd_str( + {'a': 'q', 'i': 1, 'f': 24, 't': 'f', 's': 1, 'v': 1, 'S': 3}, + payload=base64.standard_b64encode(tmpf.name.encode(self.fsenc))): + self.stdbout.write(cmd) + sys.stdout.flush() + resp = [b''] + while resp[-1] != b'\\': + resp.append(self.stdbin.read(1)) + # set the transfer method based on the response + resp = str(b''.join(resp)) + if resp.find('OK') != -1: + self.stream = False + elif resp.find('EBADF') != -1: + self.stream = True + else: + raise ImgDisplayUnsupportedException( + 'kitty replied an unexpected response: {}' + .format(resp)) - self.backend = None + # get the image manipulation backend try: # pillow is the default since we are not going # to spawn other processes, so it _should_ be faster import PIL.Image self.backend = PIL.Image - self.filter = PIL.Image.LANCZOS except ImportError: - sys.stderr.write("PIL not Found") + raise ImageDisplayError("Images previews in kitty require PIL (pillow)") # TODO: implement a wrapper class for Imagemagick process to # replicate the functionality we use from im + self.needs_late_init = False + def draw(self, path, start_x, start_y, width, height): # pylint: disable=too-many-locals self.image_id += 1 # dictionary to store the command arguments for kitty @@ -541,7 +552,10 @@ class KittyImageDisplayer(ImageDisplayer): cmds = {'a': 'T', 'i': self.image_id} # sys.stderr.write('{}-{}@{}x{}\t'.format(start_x, start_y, width, height)) - assert self.backend is not None # sanity check if we actually have a backend + # finish initialization if it is the first call + if self.needs_late_init: + self._late_init() + image = self.backend.open(path) # since kitty streches the image to fill the view box # we need to resize the box to not get distortion @@ -556,10 +570,10 @@ class KittyImageDisplayer(ImageDisplayer): width = int(new_w) # resize image to a smaller size. Ideally this should be - # image = self._resize_max_area(image, (480*960), self.filter) + # image = self._resize_max_area(image, (), self.backend.LANCZOS) if self.stream: - image = self._resize_max_area(image, (480 * 960), self.filter) + image = self._resize_max_area(image, (480 * 960), self.backend.LANCZOS) # encode the whole image as base64 # TODO: implement z compression # to possibly increase resolution in sent image @@ -589,15 +603,15 @@ class KittyImageDisplayer(ImageDisplayer): with temporarily_moved_cursor(start_y, start_x): for cmd_str in self._format_cmd_str(cmds, payload=payload): - sys.stdout.buffer.write(cmd_str) + self.stdbout.write(cmd_str) # catch kitty answer before the escape codes corrupt the console resp = [b''] while resp[-1] != b'\\': - resp.append(sys.stdin.buffer.read(1)) - if b''.join(resp[-4:-2]) == b'OK': + resp.append(self.stdbin.read(1)) + if str(b''.join(resp)).find('OK'): return else: - raise ImageDisplayError + raise ImageDisplayError('kitty replied "{}"'.format(b''.join(resp))) def clear(self, start_x, start_y, width, height): # let's assume that every time ranger call this @@ -605,8 +619,8 @@ class KittyImageDisplayer(ImageDisplayer): # TODO: implement this using the actual x, y, since the protocol supports it cmds = {'a': 'd', 'i': self.image_id} for cmd_str in self._format_cmd_str(cmds): - sys.stdout.buffer.write(cmd_str) - sys.stdout.flush() + self.stdbout.write(cmd_str) + self.stdbout.flush() # kitty doesn't seem to reply on deletes, checking like we do in draw() # will slows down scrolling with timeouts from select self.image_id -= 1 -- cgit 1.4.1-2-gfad0 From d33cc0ff06f761a1919c9c7508d8c3ffe88364ad Mon Sep 17 00:00:00 2001 From: mark-dawn Date: Thu, 22 Feb 2018 05:23:46 +0100 Subject: Unstretched Image Previews Implemented a way to obtain unstretched image previews Fixed wording in ranger.pod --- doc/ranger.pod | 3 +-- ranger/config/rc.conf | 2 +- ranger/ext/img_display.py | 39 ++++++++++++++++++--------------------- 3 files changed, 20 insertions(+), 24 deletions(-) (limited to 'doc') diff --git a/doc/ranger.pod b/doc/ranger.pod index 887f704d..46ca920e 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -244,8 +244,7 @@ To enable this feature, set the option C to urxvt-full. =head3 kitty This only works on Kitty. It requires PIL (or pillow) to work. -It is able to automatically work over network, -by switching to a slower transfer method. +Allows remote image previews, for example in an ssh session. To enable this feature, set the option C to kitty. diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 305143c1..165e049b 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -102,7 +102,7 @@ set preview_images false # Preview images in full color using kitty image protocol. # Requires python PIL or pillow library. # If ranger does not share the local filesystem with kitty -# the transfer method is switched to encoding the whole image in +# the transfer method is switched to encode the whole image in # the protocol that, while slower, allows remote previews, # for example during an ssh session. # Tmux support is untested. diff --git a/ranger/ext/img_display.py b/ranger/ext/img_display.py index 387d61a3..925a4054 100644 --- a/ranger/ext/img_display.py +++ b/ranger/ext/img_display.py @@ -506,6 +506,7 @@ class KittyImageDisplayer(ImageDisplayer): # to init in _late_init() self.backend = None self.stream = None + self.pix_row, self.pix_col = (0, 0) def _late_init(self): # automatic check if we share the filesystem using a dummy file @@ -542,9 +543,14 @@ class KittyImageDisplayer(ImageDisplayer): # TODO: implement a wrapper class for Imagemagick process to # replicate the functionality we use from im + # get dimensions of a cell in pixels + ret = fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ, + struct.pack('HHHH', 0, 0, 0, 0)) + n_cols, n_rows, x_px_tot, y_px_tot = struct.unpack('HHHH', ret) + self.pix_row, self.pix_col = x_px_tot / n_rows, y_px_tot / n_cols self.needs_late_init = False - def draw(self, path, start_x, start_y, width, height): # pylint: disable=too-many-locals + def draw(self, path, start_x, start_y, width, height): self.image_id += 1 # dictionary to store the command arguments for kitty # a is the display command, with T going for immediate output @@ -557,23 +563,16 @@ class KittyImageDisplayer(ImageDisplayer): self._late_init() image = self.backend.open(path) - # since kitty streches the image to fill the view box - # we need to resize the box to not get distortion - mismatch_ratio = (image.width / image.height) / (width * 0.5 / height) - if mismatch_ratio > 1.05: - new_h = height / mismatch_ratio - start_y += int((height - new_h) // 2) - height = int(new_h) - elif mismatch_ratio < 0.95: - new_w = width * mismatch_ratio - start_x += int((width - new_w) // 2) - width = int(new_w) - - # resize image to a smaller size. Ideally this should be - # image = self._resize_max_area(image, (), self.backend.LANCZOS) + box = (width * self.pix_row, height * self.pix_col) + + if image.width > box[0] or image.height > box[1]: + scale = min(box[0] / image.width, box[1] / image.height) + image = image.resize((int(scale * image.width), int(scale * image.height)), + self.backend.LANCZOS) + start_x += ((box[0] - image.width) // 2) // self.pix_row + start_y += ((box[1] - image.height) // 2) // self.pix_col if self.stream: - image = self._resize_max_area(image, (480 * 960), self.backend.LANCZOS) # encode the whole image as base64 # TODO: implement z compression # to possibly increase resolution in sent image @@ -584,8 +583,7 @@ class KittyImageDisplayer(ImageDisplayer): # s, v: size of the image to recompose the flattened data # c, r: size in cells of the viewbox cmds.update({'t': 'd', 'f': len(image.getbands()) * 8, - 's': image.width, 'v': image.height, - 'c': width, 'r': height}) + 's': image.width, 'v': image.height, }) payload = base64.standard_b64encode( bytearray().join(map(bytes, image.getdata()))) else: @@ -594,14 +592,13 @@ class KittyImageDisplayer(ImageDisplayer): # f: size of a pixel fragment (100 just mean that the file is png encoded, # the only format except raw RGB(A) bitmap that kitty understand) # c, r: size in cells of the viewbox - cmds.update({'t': 't', 'f': 100, - 'c': width, 'r': height}) + cmds.update({'t': 't', 'f': 100, }) with NamedTemporaryFile(prefix='rgr_thumb_', suffix='.png', delete=False) as tmpf: image.save(tmpf, format='png', compress_level=0) self.temp_paths.append(tmpf.name) payload = base64.standard_b64encode(tmpf.name.encode(self.fsenc)) - with temporarily_moved_cursor(start_y, start_x): + with temporarily_moved_cursor(int(start_y), int(start_x)): for cmd_str in self._format_cmd_str(cmds, payload=payload): self.stdbout.write(cmd_str) # catch kitty answer before the escape codes corrupt the console -- cgit 1.4.1-2-gfad0 From 8730f1ec6e20048f04298f866d4ed8b23836db57 Mon Sep 17 00:00:00 2001 From: mark-dawn Date: Fri, 23 Feb 2018 23:55:54 +0100 Subject: Fixed manpages, tmux handling Updated manapages Corrections to rc.conf Silenced the warning from pillow about image sizes Tmux session with kitty raises ImgDisplayUnsupportedError changed pager.py to also notify on ImgDispalyUnsupported Error --- doc/ranger.1 | 20 ++++++-------------- doc/ranger.pod | 1 + doc/rifle.1 | 4 ++-- ranger/config/rc.conf | 6 +++--- ranger/ext/img_display.py | 22 ++++++++++++++++------ ranger/gui/widgets/pager.py | 3 ++- 6 files changed, 30 insertions(+), 26 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index a0fc79a1..8d373a64 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.9.1" "2018-05-14" "ranger manual" +.TH RANGER 1 "ranger-1.9.1" "05/29/2018" "ranger manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -310,7 +310,8 @@ width of 8 and height of 11 are used. To use other values, set the options \fIterminology\fR .IX Subsection "terminology" .PP -This only works in terminology. It can render vectors graphics, but works only locally. +This only works in terminology. It can render vector graphics, but works only locally. +.PP To enable this feature, set the option \f(CW\*(C`preview_images_method\*(C'\fR to terminology. .PP \fIurxvt\fR @@ -334,19 +335,10 @@ To enable this feature, set the option \f(CW\*(C`preview_images_method\*(C'\fR t \fIkitty\fR .IX Subsection "kitty" .PP -This only works on Kitty. -It requires \s-1PIL\s0 or pillow at the moment to work. A nasty bug that can -corrupt the terminal window when scrolling quicly many images, that can -be solved by with the \f(CW\*(C`redraw_window\*(C'\fR command. -.PP -To enable this feature, set the option \f(CW\*(C`preview_images_method\*(C'\fR to kitty -.PP -\fIkitty-network\fR -.IX Subsection "kitty-network" +This only works on Kitty. It requires \s-1PIL\s0 (or pillow) to work. +Allows remote image previews, for example in an ssh session. .PP -The same as kitty, but uses a streaming method to allow previews remotely, -for example in an ssh session. However the system is slighly more computationally taxing -and the quality of the preview is reduced for bandwidth considerations. +To enable this feature, set the option \f(CW\*(C`preview_images_method\*(C'\fR to kitty. .SS "\s-1SELECTION\s0" .IX Subsection "SELECTION" The \fIselection\fR is defined as \*(L"All marked files \s-1IF THERE ARE ANY,\s0 otherwise diff --git a/doc/ranger.pod b/doc/ranger.pod index 46ca920e..b262ad44 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -223,6 +223,7 @@ C and C to the desired values. =head3 terminology This only works in terminology. It can render vector graphics, but works only locally. + To enable this feature, set the option C to terminology. =head3 urxvt diff --git a/doc/rifle.1 b/doc/rifle.1 index ad32e4f4..c53a6f39 100644 --- a/doc/rifle.1 +++ b/doc/rifle.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RIFLE 1" -.TH RIFLE 1 "rifle-1.9.1" "05.03.2018" "rifle manual" +.TH RIFLE 1 "rifle-1.9.1" "05/29/2018" "rifle manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 165e049b..5317dff5 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -102,10 +102,10 @@ set preview_images false # Preview images in full color using kitty image protocol. # Requires python PIL or pillow library. # If ranger does not share the local filesystem with kitty -# the transfer method is switched to encode the whole image in -# the protocol that, while slower, allows remote previews, +# the transfer method is changed to encode the whole image; +# while slower, this allows remote previews, # for example during an ssh session. -# Tmux support is untested. +# Tmux is unsupported. set preview_images_method w3m # Default iTerm2 font size (see: preview_images_method: iterm2) diff --git a/ranger/ext/img_display.py b/ranger/ext/img_display.py index 925a4054..17c730df 100644 --- a/ranger/ext/img_display.py +++ b/ranger/ext/img_display.py @@ -20,6 +20,7 @@ import imghdr import os import struct import sys +import warnings from subprocess import Popen, PIPE import termios @@ -495,10 +496,6 @@ class KittyImageDisplayer(ImageDisplayer): def __init__(self): self.temp_paths = [] - if "screen" in os.environ['TERM']: - # TODO: probably need to modify the preamble - pass - # the rest of the initializations that require reading stdio or raising exceptions # are delayed to the first draw call, since curses # and ranger exception handler are not online at __init__() time @@ -509,6 +506,14 @@ class KittyImageDisplayer(ImageDisplayer): self.pix_row, self.pix_col = (0, 0) def _late_init(self): + # tmux + if "screen" in os.environ['TERM']: + # this doesn't seem to work, ranger freezes... + # commenting out the response check does nothing + # self.protocol_start = b'\033Ptmux;\033' + self.protocol_start + # self.protocol_end += b'\033\\' + raise ImgDisplayUnsupportedException('tmux support is not implemented with kitty') + # automatic check if we share the filesystem using a dummy file with NamedTemporaryFile() as tmpf: tmpf.write(bytearray([0xFF] * 3)) @@ -561,8 +566,13 @@ class KittyImageDisplayer(ImageDisplayer): # finish initialization if it is the first call if self.needs_late_init: self._late_init() - - image = self.backend.open(path) + with warnings.catch_warnings(record=True): # as warn: + warnings.simplefilter('ignore', self.backend.DecompressionBombWarning) + image = self.backend.open(path) + # TODO: find a way to send a message to the user that + # doesn't stop the image from displaying + # if warn: + # raise ImageDisplayError(str(warn[-1].message)) box = (width * self.pix_row, height * self.pix_col) if image.width > box[0] or image.height > box[1]: diff --git a/ranger/gui/widgets/pager.py b/ranger/gui/widgets/pager.py index 42adf1e9..9afbfd15 100644 --- a/ranger/gui/widgets/pager.py +++ b/ranger/gui/widgets/pager.py @@ -109,8 +109,9 @@ class Pager(Widget): # pylint: disable=too-many-instance-attributes try: self.fm.image_displayer.draw(self.image, self.x, self.y, self.wid, self.hei) - except ImgDisplayUnsupportedException: + except ImgDisplayUnsupportedException as ex: self.fm.settings.preview_images = False + self.fm.notify(ex, bad=True) except Exception as ex: # pylint: disable=broad-except self.fm.notify(ex, bad=True) else: -- cgit 1.4.1-2-gfad0 From 0045755469b253436c847e0e0d600941252f4a5f Mon Sep 17 00:00:00 2001 From: Wojciech Siewierski Date: Fri, 1 Jun 2018 22:14:06 +0200 Subject: Make the w3m delay configurable --- doc/ranger.pod | 5 +++++ ranger/config/rc.conf | 4 ++++ ranger/container/settings.py | 1 + ranger/ext/img_display.py | 7 ++++--- 4 files changed, 14 insertions(+), 3 deletions(-) (limited to 'doc') diff --git a/doc/ranger.pod b/doc/ranger.pod index 4cac8ef9..7da4478b 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -1017,6 +1017,11 @@ Sets the view mode, which can be B to display the files in the traditional miller column view that shows multiple levels of the hierarchy, or B to use multiple panes (one per tab) similar to midnight-commander. +=item w3m_delay [float] + +Delay in seconds before displaying an image with the w3m method. +Increase it in case of experiencing display corruption. + =item wrap_scroll [bool] Enable scroll wrapping - moving down while on the last item will wrap around to diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 1296f1ca..58d6d243 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -95,6 +95,10 @@ set preview_images false # whole terminal window. set preview_images_method w3m +# Delay in seconds before displaying an image with the w3m method. +# Increase it in case of experiencing display corruption. +set w3m_delay 0.02 + # Default iTerm2 font size (see: preview_images_method: iterm2) set iterm2_font_width 8 set iterm2_font_height 11 diff --git a/ranger/container/settings.py b/ranger/container/settings.py index a7707ff0..11097cec 100644 --- a/ranger/container/settings.py +++ b/ranger/container/settings.py @@ -91,6 +91,7 @@ ALLOWED_SETTINGS = { 'vcs_backend_hg': str, 'vcs_backend_svn': str, 'viewmode': str, + 'w3m_delay': float, 'wrap_scroll': bool, 'xterm_alt_key': bool, } diff --git a/ranger/ext/img_display.py b/ranger/ext/img_display.py index f423830f..4f447f39 100644 --- a/ranger/ext/img_display.py +++ b/ranger/ext/img_display.py @@ -60,7 +60,7 @@ class ImageDisplayer(object): pass -class W3MImageDisplayer(ImageDisplayer): +class W3MImageDisplayer(ImageDisplayer, FileManagerAware): """Implementation of ImageDisplayer using w3mimgdisplay, an utilitary program from w3m (a text-based web browser). w3mimgdisplay can display images either in virtual tty (using linux framebuffer) or in a Xorg session. @@ -123,8 +123,9 @@ class W3MImageDisplayer(ImageDisplayer): # Mitigate the issue with the horizontal black bars when # selecting some images on some systems. 2 milliseconds seems # enough. Adjust as necessary. - from time import sleep - sleep(0.02) + if self.fm.settings.w3m_delay > 0: + from time import sleep + sleep(self.fm.settings.w3m_delay) self.process.stdin.write(input_gen) self.process.stdin.flush() -- cgit 1.4.1-2-gfad0 From 536de704bafba18be78007d773d79f31c84c49db Mon Sep 17 00:00:00 2001 From: toonn Date: Wed, 6 Jun 2018 00:13:04 +0200 Subject: Update the release checklist about version bumps --- doc/howto-publish-a-release.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc') diff --git a/doc/howto-publish-a-release.md b/doc/howto-publish-a-release.md index 572a2eb7..e8d669ce 100644 --- a/doc/howto-publish-a-release.md +++ b/doc/howto-publish-a-release.md @@ -31,7 +31,7 @@ Test everything Make a release commit --------------------- * [ ] Update the number in the `README` -* [ ] Update `__version__` and `VERSION` in `ranger/__init__.py` +* [ ] Update `__version__` and `__release__` in `ranger/__init__.py` * [ ] Update `__version__` in `ranger/ext/rifle.py` * [ ] `make man` * [ ] Write changelog entry -- cgit 1.4.1-2-gfad0 From b77e033746fe9120f2083bf59164b9ff4c553aa1 Mon Sep 17 00:00:00 2001 From: Erez Shermer Date: Thu, 7 Jun 2018 09:59:02 +0300 Subject: Proper usage of the bidi setting --- doc/ranger.pod | 6 ++++++ ranger/config/rc.conf | 4 ++++ ranger/container/settings.py | 1 + ranger/gui/widgets/browsercolumn.py | 17 +++++++++++++++-- 4 files changed, 26 insertions(+), 2 deletions(-) (limited to 'doc') diff --git a/doc/ranger.pod b/doc/ranger.pod index 8599a1a6..a4e782b3 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -968,6 +968,12 @@ Abbreviate $HOME with ~ in the titlebar (first line) of ranger? Use a unicode "..." character instead of "~" to mark cut-off filenames? +=item bidi_support [bool] + +Try to properly display file names in RTL languages (Hebrew, Arabic) by using +a BIDI algorithm to reverse the relevant parts of the text. +Requires the python-bidi pip package. + =item update_title [bool] Set a window title? diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index fe00c7c0..5a7a9a6d 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -101,6 +101,10 @@ set iterm2_font_height 11 # Use a unicode "..." character to mark cut-off filenames? set unicode_ellipsis false +# BIDI support - try to properly display file names in RTL languages (Hebrew, Arabic). +# Requires the python-bidi pip package +set bidi_support false + # Show dotfiles in the bookmark preview box? set show_hidden_bookmarks true diff --git a/ranger/container/settings.py b/ranger/container/settings.py index 9f54f24d..9603401f 100644 --- a/ranger/container/settings.py +++ b/ranger/container/settings.py @@ -27,6 +27,7 @@ ALLOWED_SETTINGS = { 'automatically_count_files': bool, 'autosave_bookmarks': bool, 'autoupdate_cumulative_size': bool, + 'bidi_support': bool, 'cd_bookmarks': bool, 'cd_tab_case': str, 'cd_tab_fuzzy': bool, diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index b3272cbc..b38595c1 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -10,6 +10,12 @@ import stat from time import time from os.path import splitext +try: + from bidi.algorithm import get_display # pylint: disable=import-error + HAVE_BIDI = True +except ImportError: + HAVE_BIDI = False + from ranger.ext.widestring import WideString from ranger.core import linemode @@ -410,9 +416,16 @@ class BrowserColumn(Pager): # pylint: disable=too-many-instance-attributes def _total_len(predisplay): return sum([len(WideString(s)) for s, _ in predisplay]) + def _bidi_transpose(self, text): + if self.settings.bidi_support and HAVE_BIDI: + return get_display(text) + else: + return text + def _draw_text_display(self, text, space): - wtext = WideString(text) - wext = WideString(splitext(text)[1]) + bidi_text = self._bidi_transpose(text) + wtext = WideString(bidi_text) + wext = WideString(splitext(bidi_text)[1]) wellip = WideString(self.ellipsis[self.settings.unicode_ellipsis]) if len(wtext) > space: wtext = wtext[:max(1, space - len(wext) - len(wellip))] + wellip + wext -- cgit 1.4.1-2-gfad0 From 5e5c516dfcf52e8ea1cb206f433fafc87deb892d Mon Sep 17 00:00:00 2001 From: toonn Date: Thu, 7 Jun 2018 14:39:59 +0200 Subject: Regenerate man pages The `.pod`s were merged so I regenerated the man pages to be sure they're correct. --- doc/ranger.1 | 11 ++++++++++- doc/rifle.1 | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index 8d373a64..03791924 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.9.1" "05/29/2018" "ranger manual" +.TH RANGER 1 "ranger-1.9.1" "2018-06-07" "ranger manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -970,6 +970,11 @@ Abbreviate \f(CW$HOME\fR with ~ in the titlebar (first line) of ranger? .IP "unicode_ellipsis [bool]" 4 .IX Item "unicode_ellipsis [bool]" Use a unicode \*(L"...\*(R" character instead of \*(L"~\*(R" to mark cut-off filenames? +.IP "bidi_support [bool]" 4 +.IX Item "bidi_support [bool]" +Try to properly display file names in \s-1RTL\s0 languages (Hebrew, Arabic) by using +a \s-1BIDI\s0 algorithm to reverse the relevant parts of the text. +Requires the python-bidi pip package. .IP "update_title [bool]" 4 .IX Item "update_title [bool]" Set a window title? @@ -996,6 +1001,10 @@ Sets the state for the version control backend. The possible values are: Sets the view mode, which can be \fBmiller\fR to display the files in the traditional miller column view that shows multiple levels of the hierarchy, or \&\fBmultipane\fR to use multiple panes (one per tab) similar to midnight-commander. +.IP "w3m_delay [float]" 4 +.IX Item "w3m_delay [float]" +Delay in seconds before displaying an image with the w3m method. +Increase it in case of experiencing display corruption. .IP "wrap_scroll [bool]" 4 .IX Item "wrap_scroll [bool]" Enable scroll wrapping \- moving down while on the last item will wrap around to diff --git a/doc/rifle.1 b/doc/rifle.1 index c53a6f39..c8c679ec 100644 --- a/doc/rifle.1 +++ b/doc/rifle.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RIFLE 1" -.TH RIFLE 1 "rifle-1.9.1" "05/29/2018" "rifle manual" +.TH RIFLE 1 "rifle-1.9.1" "2018-06-07" "rifle manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l -- cgit 1.4.1-2-gfad0 From 835065f2819f2dde2426e203996c12862a97d3f8 Mon Sep 17 00:00:00 2001 From: Wojciech Siewierski Date: Sun, 17 Jun 2018 13:50:21 +0200 Subject: New setting: relative_current_zero Closes #1205. --- doc/ranger.1 | 4 ++++ doc/ranger.pod | 5 +++++ ranger/config/rc.conf | 7 ++++++- ranger/container/settings.py | 1 + ranger/gui/widgets/browsercolumn.py | 2 +- 5 files changed, 17 insertions(+), 2 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index 03791924..5b3afa73 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -908,6 +908,10 @@ to disable this feature. Which script should handle generating previews? If the file doesn't exist, or use_preview_script is off, ranger will handle previews itself by just printing the content. +.IP "relative_current_zero [bool]" 4 +.IX Item "relative_current_zero [bool]" +When line_numbers is set to relative, show 0 on the current line if +true or show the absolute number of the current line when false. .IP "save_backtick_bookmark [bool]" 4 .IX Item "save_backtick_bookmark [bool]" Save the \f(CW\*(C`\`\*(C'\fR bookmark to disk. This bookmark is used to switch to the last diff --git a/doc/ranger.pod b/doc/ranger.pod index 24df0fc9..fcee60aa 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -921,6 +921,11 @@ Which script should handle generating previews? If the file doesn't exist, or use_preview_script is off, ranger will handle previews itself by just printing the content. +=item relative_current_zero [bool] + +When line_numbers is set to relative, show 0 on the current line if +true or show the absolute number of the current line when false. + =item save_backtick_bookmark [bool] Save the C<`> bookmark to disk. This bookmark is used to switch to the last diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 37a570b5..62331e22 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -261,9 +261,14 @@ set metadata_deep_search false # Clear all existing filters when leaving a directory set clear_filters_on_dir_change false -# Disable displaying line numbers in main column +# Disable displaying line numbers in main column. +# Possible values: false, absolute, relative. set line_numbers false +# When line_numbers=relative show the absolute line number in the +# current line. +set relative_current_zero false + # Start line numbers from 1 instead of 0 set one_indexed false diff --git a/ranger/container/settings.py b/ranger/container/settings.py index 9002fded..94e455a5 100644 --- a/ranger/container/settings.py +++ b/ranger/container/settings.py @@ -66,6 +66,7 @@ ALLOWED_SETTINGS = { 'preview_images_method': str, 'preview_max_size': int, 'preview_script': (str, type(None)), + 'relative_current_zero': bool, 'save_backtick_bookmark': bool, 'save_console_history': bool, 'save_tabs_on_exit': bool, diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index f85e1646..95260813 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -212,7 +212,7 @@ class BrowserColumn(Pager): # pylint: disable=too-many-instance-attributes line_number = i if self.settings.line_numbers == 'relative': line_number = abs(selected_i - i) - if line_number == 0: + if not self.settings.relative_current_zero and line_number == 0: if self.settings.one_indexed: line_number = selected_i + 1 else: -- cgit 1.4.1-2-gfad0 From b74360cd4a55e9f6e4b594c84d442339edeff86e Mon Sep 17 00:00:00 2001 From: Saturnus Numerius Date: Tue, 3 Jul 2018 11:31:49 -0400 Subject: Change formatting of colorscheme doc to markdown Makes the file easier to read in github while still maintaining the current easy-to-read format found in the raw file --- doc/colorschemes.md | 77 +++++++++++++++++++++++++++++++++++++++++++ doc/colorschemes.txt | 92 ---------------------------------------------------- 2 files changed, 77 insertions(+), 92 deletions(-) create mode 100644 doc/colorschemes.md delete mode 100644 doc/colorschemes.txt (limited to 'doc') diff --git a/doc/colorschemes.md b/doc/colorschemes.md new file mode 100644 index 00000000..eb8bdef0 --- /dev/null +++ b/doc/colorschemes.md @@ -0,0 +1,77 @@ +# Colorschemes + +This text explains colorschemes and how they work. + +## Context Tags + +Context Tags provide information about the context. If the tag `in_titlebar` is +set, you probably want to know about the color of a part of the titlebar now. + +There are a number of context tags, specified in /ranger/gui/context.py in the +constant `CONTEXT_KEYS`. + +A Context object, defined in the same file, contains attributes with the names +of all tags, whose values are either True or False. + +## Implementation in the GUI Classes + +The class CursesShortcuts in the file `/ranger/gui/curses_shortcuts.py` defines +the methods `color(*tags)`, `color_at(y, x, wid, *tags)` and `color_reset()`. +This class is a superclass of Displayable, so these methods are available almost +everywhere. + +Something like `color("in_titlebar", "directory")` will be called to get the +color of directories in the titlebar. This creates a `ranger.gui.context.Context` +object, sets its attributes `in_titlebar` and `directory` to True, leaves the +others as False, and passes it to the colorscheme's `use(context)` method. + +## The Color Scheme + +A colorscheme should be a subclass of `ranger.gui.ColorScheme` and define the +method `use(context)`. By looking at the context, this use-method has to +determine a 3-tuple of integers: `(foreground, background, attribute)` and return +it. + +`foreground` and `background` are integers representing colors, `attribute` is +another integer with each bit representing one attribute. These integers are +interpreted by the used terminal emulator. + +Abbreviations for colors and attributes are defined in `ranger.gui.color`. Two +attributes can be combined via bitwise OR: bold | reverse + +Once the color for a set of tags is determined, it will be cached by default. If +you want more dynamic colorschemes (such as a different color for very large +files), you will need to dig into the source code, perhaps add an own tag and +modify the draw-method of the widget to use that tag. + +Run `tc_colorscheme` to check if your colorschemes are valid. + +## Specify a Colorscheme + +Colorschemes are searched for in these directories: + +- `~/.config/ranger/colorschemes/` +- `/path/to/ranger/colorschemes/` + +To specify which colorscheme to use, change the option `colorscheme` in your +rc.conf: `set colorscheme default`. + +This means, use the colorscheme contained in either +`~/.config/ranger/colorschemes/default.py` or +`/path/to/ranger/colorschemes/default.py`. + +## Adapt a colorscheme + +You may want to adapt a colorscheme to your needs without having a complete copy +of it, but rather the changes only. Say, you want the exact same colors as in +the default colorscheme, but the directories to be green rather than blue, +because you find the blue hard to read. + +This is done in the jungle colorscheme `ranger/colorschemes/jungle`, check it +out for implementation details. In short, I made a subclass of the default +scheme, set the initial colors to the result of the default `use()` method and +modified the colors how I wanted. + +This has the obvious advantage that you need to write less, which results in +less maintenance work and a greater chance that your colorscheme will work with +future versions of ranger. diff --git a/doc/colorschemes.txt b/doc/colorschemes.txt deleted file mode 100644 index 145cc94e..00000000 --- a/doc/colorschemes.txt +++ /dev/null @@ -1,92 +0,0 @@ -Colorschemes -============ - -This text explains colorschemes and how they work. - - -Context Tags ------------- - -Context Tags provide information about the context. If the tag -"in_titlebar" is set, you probably want to know about the color -of a part of the titlebar now. - -There are a number of context tags, specified in /ranger/gui/context.py -in the constant CONTEXT_KEYS. - -A Context object, defined in the same file, contains attributes with -the names of all tags, whose values are either True or False. - - -Implementation in the GUI Classes ---------------------------------- - -The class CursesShortcuts in the file /ranger/gui/curses_shortcuts.py -defines the methods color(*tags), color_at(y, x, wid, *tags) and -color_reset(). This class is a superclass of Displayable, so these -methods are available almost everywhere. - -Something like color("in_titlebar", "directory") will be called to -get the color of directories in the titlebar. This creates a -ranger.gui.context.Context object, sets its attributes "in_titlebar" and -"directory" to True, leaves the others as False, and passes it to the -colorscheme's use(context) method. - - -The Color Scheme ----------------- - -A colorscheme should be a subclass of ranger.gui.ColorScheme and -define the method use(context). By looking at the context, this use-method -has to determine a 3-tuple of integers: (foreground, background, attribute) -and return it. - -foreground and background are integers representing colors, -attribute is another integer with each bit representing one attribute. -These integers are interpreted by the used terminal emulator. - -Abbreviations for colors and attributes are defined in ranger.gui.color. -Two attributes can be combined via bitwise OR: bold | reverse - -Once the color for a set of tags is determined, it will be cached by -default. If you want more dynamic colorschemes (such as a different -color for very large files), you will need to dig into the source code, -perhaps add an own tag and modify the draw-method of the widget to use -that tag. - -Run tc_colorscheme to check if your colorschemes are valid. - - -Specify a Colorscheme ---------------------- - -Colorschemes are searched for in these directories: -~/.config/ranger/colorschemes/ -/path/to/ranger/colorschemes/ - -To specify which colorscheme to use, change the option "colorscheme" -in your rc.conf: -set colorscheme default - -This means, use the colorscheme contained in -either ~/.config/ranger/colorschemes/default.py or -/path/to/ranger/colorschemes/default.py. - - -Adapt a colorscheme -------------------- - -You may want to adapt a colorscheme to your needs without having -a complete copy of it, but rather the changes only. Say, you -want the exact same colors as in the default colorscheme, but -the directories to be green rather than blue, because you find the -blue hard to read. - -This is done in the jungle colorscheme ranger/colorschemes/jungle, -check it out for implementation details. In short, I made a subclass -of the default scheme, set the initial colors to the result of the -default use() method and modified the colors how I wanted. - -This has the obvious advantage that you need to write less, which -results in less maintenance work and a greater chance that your colorscheme -will work with future versions of ranger. -- cgit 1.4.1-2-gfad0 From 3c10cc590d7f0374177e21a75b8e763c3c161128 Mon Sep 17 00:00:00 2001 From: Saturnus Numerius Date: Wed, 4 Jul 2018 10:05:58 -0400 Subject: Made changes requested by @toonn Helps readability. --- doc/colorschemes.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'doc') diff --git a/doc/colorschemes.md b/doc/colorschemes.md index eb8bdef0..4116a843 100644 --- a/doc/colorschemes.md +++ b/doc/colorschemes.md @@ -1,19 +1,21 @@ -# Colorschemes +Colorschemes +============ This text explains colorschemes and how they work. -## Context Tags +Context Tags +------------ Context Tags provide information about the context. If the tag `in_titlebar` is set, you probably want to know about the color of a part of the titlebar now. -There are a number of context tags, specified in /ranger/gui/context.py in the +There are a number of context tags, specified in `/ranger/gui/context.py` in the constant `CONTEXT_KEYS`. A Context object, defined in the same file, contains attributes with the names -of all tags, whose values are either True or False. +of all tags, whose values are either `True` or `False`. -## Implementation in the GUI Classes +Implementation in the GUI Classes The class CursesShortcuts in the file `/ranger/gui/curses_shortcuts.py` defines the methods `color(*tags)`, `color_at(y, x, wid, *tags)` and `color_reset()`. @@ -25,7 +27,8 @@ color of directories in the titlebar. This creates a `ranger.gui.context.Context object, sets its attributes `in_titlebar` and `directory` to True, leaves the others as False, and passes it to the colorscheme's `use(context)` method. -## The Color Scheme +The Color Scheme +---------------- A colorscheme should be a subclass of `ranger.gui.ColorScheme` and define the method `use(context)`. By looking at the context, this use-method has to @@ -37,7 +40,7 @@ another integer with each bit representing one attribute. These integers are interpreted by the used terminal emulator. Abbreviations for colors and attributes are defined in `ranger.gui.color`. Two -attributes can be combined via bitwise OR: bold | reverse +attributes can be combined via bitwise OR: `bold | reverse` Once the color for a set of tags is determined, it will be cached by default. If you want more dynamic colorschemes (such as a different color for very large @@ -46,7 +49,8 @@ modify the draw-method of the widget to use that tag. Run `tc_colorscheme` to check if your colorschemes are valid. -## Specify a Colorscheme +Specify a Colorscheme +--------------------- Colorschemes are searched for in these directories: @@ -60,7 +64,8 @@ This means, use the colorscheme contained in either `~/.config/ranger/colorschemes/default.py` or `/path/to/ranger/colorschemes/default.py`. -## Adapt a colorscheme +Adapt a colorscheme +------------------- You may want to adapt a colorscheme to your needs without having a complete copy of it, but rather the changes only. Say, you want the exact same colors as in -- cgit 1.4.1-2-gfad0 From 7b8087a24da8aa08347d3556c421a00351bf6419 Mon Sep 17 00:00:00 2001 From: Saturnus Numerius Date: Wed, 4 Jul 2018 15:58:14 -0400 Subject: Make more changes --- doc/colorschemes.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'doc') diff --git a/doc/colorschemes.md b/doc/colorschemes.md index 4116a843..c7600700 100644 --- a/doc/colorschemes.md +++ b/doc/colorschemes.md @@ -6,7 +6,7 @@ This text explains colorschemes and how they work. Context Tags ------------ -Context Tags provide information about the context. If the tag `in_titlebar` is +Context tags provide information about the context. If the tag `in_titlebar` is set, you probably want to know about the color of a part of the titlebar now. There are a number of context tags, specified in `/ranger/gui/context.py` in the @@ -16,16 +16,17 @@ A Context object, defined in the same file, contains attributes with the names of all tags, whose values are either `True` or `False`. Implementation in the GUI Classes +--------------------------------- -The class CursesShortcuts in the file `/ranger/gui/curses_shortcuts.py` defines +The class `CursesShortcuts` in the file `/ranger/gui/curses_shortcuts.py` defines the methods `color(*tags)`, `color_at(y, x, wid, *tags)` and `color_reset()`. -This class is a superclass of Displayable, so these methods are available almost +This class is a superclass of `Displayable`, so these methods are available almost everywhere. Something like `color("in_titlebar", "directory")` will be called to get the color of directories in the titlebar. This creates a `ranger.gui.context.Context` object, sets its attributes `in_titlebar` and `directory` to True, leaves the -others as False, and passes it to the colorscheme's `use(context)` method. +others as `False`, and passes it to the colorscheme's `use(context)` method. The Color Scheme ---------------- @@ -37,14 +38,14 @@ it. `foreground` and `background` are integers representing colors, `attribute` is another integer with each bit representing one attribute. These integers are -interpreted by the used terminal emulator. +interpreted by the terminal emulator in use. Abbreviations for colors and attributes are defined in `ranger.gui.color`. Two attributes can be combined via bitwise OR: `bold | reverse` Once the color for a set of tags is determined, it will be cached by default. If you want more dynamic colorschemes (such as a different color for very large -files), you will need to dig into the source code, perhaps add an own tag and +files), you will need to dig into the source code, perhaps add a custom tag and modify the draw-method of the widget to use that tag. Run `tc_colorscheme` to check if your colorschemes are valid. -- cgit 1.4.1-2-gfad0 From 6a70583077425bbe165196cf09f49aca3cb222b8 Mon Sep 17 00:00:00 2001 From: Saturnus Numerius Date: Sat, 7 Jul 2018 12:09:26 -0400 Subject: Revamped context section of the colorscheme doc Added basic instruction on how to add a context key with a working example. --- doc/colorschemes.md | 69 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 6 deletions(-) (limited to 'doc') diff --git a/doc/colorschemes.md b/doc/colorschemes.md index c7600700..eaf90174 100644 --- a/doc/colorschemes.md +++ b/doc/colorschemes.md @@ -6,14 +6,71 @@ This text explains colorschemes and how they work. Context Tags ------------ -Context tags provide information about the context. If the tag `in_titlebar` is -set, you probably want to know about the color of a part of the titlebar now. +Context tags provide information about the context and are Boolean values (`True` +or `False`). For example, if the tag `in_titlebar` is set, you probably want to +know about the color of a part of the titlebar now. -There are a number of context tags, specified in `/ranger/gui/context.py` in the -constant `CONTEXT_KEYS`. +The default context tags are specified in `/ranger/gui/context.py` in the +constant `CONTEXT_KEYS`. Custom tags can be specified in a custom plugin file in +`~/.config/ranger/plugins/`. The code to use follows. -A Context object, defined in the same file, contains attributes with the names -of all tags, whose values are either `True` or `False`. +```python +# Import the class +import ranger.gui.context + +# Add your key names +ranger.gui.context.CONTEXT_KEYS.append('my_key') + +# Set it to false (the default value) +ranger.gui.context.Context.my_key = False + +# Or use an array for multiple names +my_keys = ['key_one', 'key_two'] +ranger.gui.context.CONTEXT_KEYS.append(my_keys) + +# Set them to False +for key in my_keys: + code = 'ranger.gui.context.Context.' + key + ' = False' + exec(code) +``` + +As you may or may not have guessed, this only tells ranger that they exist, not +what they mean. To do this, you'll have to dig around in the source code. As an +example, let's walk through adding a key that highlights `README.md` files +differently. All the following code will be written in a standalone plugin file. + +First, from above, we'll add the key `readme` and set it to `False`. + +```python +import ranger.gui.context + +ranger.gui.context.CONTEXT_KEYS.append('readme') +ranger.gui.context.Context.readme = False +``` + +Then we'll use the hook `hook_before_drawing` to tell ranger that our key is +talking about `README.md` files. + +```python +import ranger.gui.widgets.browsercolumn + +OLD_HOOK_BEFORE_DRAWING = ranger.gui.widgets.browsercolumn.hook_before_drawing + +def new_hook_before_drawing(fsobject, color_list): + if fsobject.basename === 'README.md': + color_list.append('readme') + + return OLD_HOOK_BEFORE_DRAWING(fsobject, color_list) + +ranger.gui.widgets.browsercolumn.hook_before_drawing = new_hook_before_drawing +``` + +Notice we call the old `hook_before_drawing`. This makes sure that we don't +overwrite another plugin's code, we just append our own to it. + +To highlight it a different color, just [add it to your colorscheme][1] + +[1]:#adapt-a-colorscheme Implementation in the GUI Classes --------------------------------- -- cgit 1.4.1-2-gfad0 From 2a8565d175a58172983d410b36e8644d484c1cc8 Mon Sep 17 00:00:00 2001 From: Saturnus Numerius Date: Sat, 7 Jul 2018 12:22:19 -0400 Subject: Fixed some capitalization issues --- doc/colorschemes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc') diff --git a/doc/colorschemes.md b/doc/colorschemes.md index eaf90174..458cfc53 100644 --- a/doc/colorschemes.md +++ b/doc/colorschemes.md @@ -21,7 +21,7 @@ import ranger.gui.context # Add your key names ranger.gui.context.CONTEXT_KEYS.append('my_key') -# Set it to false (the default value) +# Set it to False (the default value) ranger.gui.context.Context.my_key = False # Or use an array for multiple names -- cgit 1.4.1-2-gfad0 From 4f0cb1333be76c888089c17ca508e7ef17f3400f Mon Sep 17 00:00:00 2001 From: Wojciech Siewierski Date: Sun, 15 Jul 2018 23:04:47 +0200 Subject: Fix a typo in the manpage --- doc/ranger.1 | 4 ++-- doc/ranger.pod | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index 5b3afa73..e141011f 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.9.1" "2018-06-07" "ranger manual" +.TH RANGER 1 "ranger-1.9.1" "2018-07-15" "ranger manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -690,7 +690,7 @@ scrolling to switch directories. .SH "SETTINGS" .IX Header "SETTINGS" This section lists all built-in settings of ranger. The valid types for the -value are in [brackets]. The hotkey to toggle the setting is in , if +value are in [brackets]. The hotkey to toggle the setting is in , if a hotkey exists. .PP Settings can be changed in the file \fI~/.config/ranger/rc.conf\fR or on the diff --git a/doc/ranger.pod b/doc/ranger.pod index fcee60aa..3062fef5 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -675,7 +675,7 @@ scrolling to switch directories. =head1 SETTINGS This section lists all built-in settings of ranger. The valid types for the -value are in [brackets]. The hotkey to toggle the setting is in , if +value are in [brackets]. The hotkey to toggle the setting is in , if a hotkey exists. Settings can be changed in the file F<~/.config/ranger/rc.conf> or on the -- cgit 1.4.1-2-gfad0 From 4d66aff45c036d085d09cdcfb03c3f51e1641b19 Mon Sep 17 00:00:00 2001 From: Wojciech Siewierski Date: Sun, 15 Jul 2018 23:01:47 +0200 Subject: Add the filter stack docs --- doc/ranger.1 | 29 ++++++++++++++++++++++++++++- doc/ranger.pod | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index 5b3afa73..509fc53c 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.9.1" "2018-06-07" "ranger manual" +.TH RANGER 1 "ranger-1.9.1" "2018-07-15" "ranger manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -657,6 +657,33 @@ Close the current tab. The last tab cannot be closed this way. A key chain that allows you to quickly change the line mode of all the files of the current directory. For a more permanent solution, use the command \&\*(L"default_linemode\*(R" in your rc.conf. +.IP ".n" 14 +.IX Item ".n" +Apply a new filename filter. +.IP ".d" 14 +.IX Item ".d" +Apply the typefilter \*(L"directory\*(R". +.IP ".f" 14 +.IX Item ".f" +Apply the typefilter \*(L"file\*(R". +.IP ".l" 14 +.IX Item ".l" +Apply the typefilter \*(L"symlink\*(R". +.IP ".|" 14 +Combine te two topmost filters from the filter stack in the \*(L"\s-1OR\*(R"\s0 +relationship, instead of the \*(L"\s-1AND\*(R"\s0 used implicitly. +.IP ".!" 14 +Negate the topmost filter. +.IP ".c" 14 +.IX Item ".c" +Clear the filter stack. +.IP ".*" 14 +Decompose the topmost filter combinator (e.g. \f(CW\*(C`.!\*(C'\fR, \f(CW\*(C`.|\*(C'\fR). +.IP ".p" 14 +.IX Item ".p" +Pop the topmost filter from the filter stack. +.IP ".." 14 +Show the current filter stack state. .SS "READLINE-LIKE \s-1BINDINGS IN THE CONSOLE\s0" .IX Subsection "READLINE-LIKE BINDINGS IN THE CONSOLE" .IP "^B, ^F" 14 diff --git a/doc/ranger.pod b/doc/ranger.pod index fcee60aa..6d7d5a00 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -620,6 +620,47 @@ A key chain that allows you to quickly change the line mode of all the files of the current directory. For a more permanent solution, use the command "default_linemode" in your rc.conf. +=item .n + +Apply a new filename filter. + +=item .d + +Apply the typefilter "directory". + +=item .f + +Apply the typefilter "file". + +=item .l + +Apply the typefilter "symlink". + +=item .| + +Combine te two topmost filters from the filter stack in the "OR" +relationship, instead of the "AND" used implicitly. + +=item .! + +Negate the topmost filter. + +=item .c + +Clear the filter stack. + +=item .* + +Decompose the topmost filter combinator (e.g. C<.!>, C<.|>). + +=item .p + +Pop the topmost filter from the filter stack. + +=item .. + +Show the current filter stack state. + =back =head2 READLINE-LIKE BINDINGS IN THE CONSOLE -- cgit 1.4.1-2-gfad0 From 712ec67e1426fe601e99c63ac078d215378299c7 Mon Sep 17 00:00:00 2001 From: Wojciech Siewierski Date: Sun, 19 Aug 2018 15:48:45 +0200 Subject: Implement the filter stack rotation Tested to work both ways, so one can rotate by negative number to undo the previous positive rotation. --- doc/ranger.1 | 6 +++++- doc/ranger.pod | 7 ++++++- ranger/config/commands.py | 7 +++++++ ranger/config/rc.conf | 1 + 4 files changed, 19 insertions(+), 2 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index 4ed1e584..8423d068 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -670,10 +670,14 @@ Apply the typefilter \*(L"file\*(R". .IX Item ".l" Apply the typefilter \*(L"symlink\*(R". .IP ".|" 14 -Combine te two topmost filters from the filter stack in the \*(L"\s-1OR\*(R"\s0 +Combine the two topmost filters from the filter stack in the \*(L"\s-1OR\*(R"\s0 relationship, instead of the \*(L"\s-1AND\*(R"\s0 used implicitly. .IP ".!" 14 Negate the topmost filter. +.IP ".r" 14 +.IX Item ".r" +Rotate the filter stack by N elements. Just confirm with enter to +rotate by 1, i.e. move the topmost element to the bottom of the stack. .IP ".c" 14 .IX Item ".c" Clear the filter stack. diff --git a/doc/ranger.pod b/doc/ranger.pod index 849acbb2..6e7075a7 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -638,13 +638,18 @@ Apply the typefilter "symlink". =item .| -Combine te two topmost filters from the filter stack in the "OR" +Combine the two topmost filters from the filter stack in the "OR" relationship, instead of the "AND" used implicitly. =item .! Negate the topmost filter. +=item .r + +Rotate the filter stack by N elements. Just confirm with enter to +rotate by 1, i.e. move the topmost element to the bottom of the stack. + =item .c Clear the filter stack. diff --git a/ranger/config/commands.py b/ranger/config/commands.py index 35aa3ffb..c136db56 100755 --- a/ranger/config/commands.py +++ b/ranger/config/commands.py @@ -1554,6 +1554,7 @@ class filter_stack(Command): filter_stack add FILTER_TYPE ARGS... filter_stack pop filter_stack decompose + filter_stack rotate [N=1] filter_stack clear filter_stack show """ @@ -1577,6 +1578,12 @@ class filter_stack(Command): self.fm.thisdir.filter_stack.extend(inner_filters) elif subcommand == "clear": self.fm.thisdir.filter_stack = [] + elif subcommand == "rotate": + rotate_by = int(self.arg(2) or 1) + self.fm.thisdir.filter_stack = ( + self.fm.thisdir.filter_stack[-rotate_by:] + + self.fm.thisdir.filter_stack[:-rotate_by] + ) elif subcommand == "show": stack = map(str, self.fm.thisdir.filter_stack) pager = self.fm.ui.open_pager() diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 4d8f1f54..14706dce 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -564,6 +564,7 @@ map .f filter_stack add type f map .l filter_stack add type l map .| filter_stack add or map .! filter_stack add not +map .r console filter_stack rotate map .c filter_stack clear map .* filter_stack decompose map .p filter_stack pop -- cgit 1.4.1-2-gfad0 From 7d2e57b7a693dd7e8dfc00cb1e52116108b60e9a Mon Sep 17 00:00:00 2001 From: Wojciech Siewierski Date: Sun, 19 Aug 2018 21:40:13 +0200 Subject: Add an explicit "AND" filter combinator Closes #1268. --- doc/ranger.1 | 4 ++++ doc/ranger.pod | 6 ++++++ ranger/config/rc.conf | 1 + ranger/core/filter_stack.py | 20 ++++++++++++++++++++ 4 files changed, 31 insertions(+) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index 8423d068..060686b8 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -672,6 +672,10 @@ Apply the typefilter \*(L"symlink\*(R". .IP ".|" 14 Combine the two topmost filters from the filter stack in the \*(L"\s-1OR\*(R"\s0 relationship, instead of the \*(L"\s-1AND\*(R"\s0 used implicitly. +.IP ".&" 14 +Explicitly combine the two topmost filters in the \*(L"\s-1AND\*(R"\s0 +relationship. Usually not needed though might be useful in more +complicated scenarios. .IP ".!" 14 Negate the topmost filter. .IP ".r" 14 diff --git a/doc/ranger.pod b/doc/ranger.pod index 6e7075a7..48e6a41e 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -641,6 +641,12 @@ Apply the typefilter "symlink". Combine the two topmost filters from the filter stack in the "OR" relationship, instead of the "AND" used implicitly. +=item .& + +Explicitly combine the two topmost filters in the "AND" +relationship. Usually not needed though might be useful in more +complicated scenarios. + =item .! Negate the topmost filter. diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 14706dce..b112dc2c 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -563,6 +563,7 @@ map .d filter_stack add type d map .f filter_stack add type f map .l filter_stack add type l map .| filter_stack add or +map .& filter_stack add and map .! filter_stack add not map .r console filter_stack rotate map .c filter_stack clear diff --git a/ranger/core/filter_stack.py b/ranger/core/filter_stack.py index f5b00014..ff9f4080 100644 --- a/ranger/core/filter_stack.py +++ b/ranger/core/filter_stack.py @@ -98,6 +98,26 @@ class OrFilter(BaseFilter): return self.subfilters +@filter_combinator("and") +class AndFilter(BaseFilter): + def __init__(self, stack): + self.subfilters = [stack[-2], stack[-1]] + + stack.pop() + stack.pop() + + stack.append(self) + + def __call__(self, fobj): + return accept_file(fobj, self.subfilters) + + def __str__(self): + return "".format(" and ".join(map(str, self.subfilters))) + + def decompose(self): + return self.subfilters + + @filter_combinator("not") class NotFilter(BaseFilter): def __init__(self, stack): -- cgit 1.4.1-2-gfad0 From 66b8e2740c53c21839a08dc2b36cd3289cf12f1f Mon Sep 17 00:00:00 2001 From: Leo Vivier Date: Sun, 26 Aug 2018 10:08:26 +0200 Subject: Add word-movement commands in console to man-page --- doc/ranger.1 | 30 ++++++++++++++++++++---------- doc/ranger.pod | 8 ++++++++ 2 files changed, 28 insertions(+), 10 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index 060686b8..380a48dc 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" @@ -703,6 +707,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" 14 +.IX Item "Alt-B" +Move backwards by words. +.IP "Alt-F" 14 +.IX Item "Alt-F" +Move forwards by words. .IP "^D" 14 .IX Item "^D" Delete the current character. @@ -1632,7 +1642,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: diff --git a/doc/ranger.pod b/doc/ranger.pod index 48e6a41e..1b1af68e 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -690,6 +690,14 @@ Move up and down (P for previous, N for Next) Move to the start or to the end +=item Alt-B + +Move backwards by words. + +=item Alt-F + +Move forwards by words. + =item ^D Delete the current character. -- cgit 1.4.1-2-gfad0 From e10321b9f8020bdf4c05a1cddc9f989154de8adf Mon Sep 17 00:00:00 2001 From: Leo Vivier Date: Sun, 26 Aug 2018 10:09:22 +0200 Subject: Fix punctuation in READLINE-LIKE BINDINGS IN THE CONSOLE Adds full-stops at the end of every entry. --- doc/ranger.1 | 6 +++--- doc/ranger.pod | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index 380a48dc..936b10bd 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -700,13 +700,13 @@ Show the current filter stack state. .IX Subsection "READLINE-LIKE BINDINGS IN THE CONSOLE" .IP "^B, ^F" 14 .IX Item "^B, ^F" -Move left and right (B for back, F for forward) +Move left and right (B for back, F for forward). .IP "^P, ^N" 14 .IX Item "^P, ^N" -Move up and down (P for previous, N for Next) +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 +Move to the start or to the end. .IP "Alt-B" 14 .IX Item "Alt-B" Move backwards by words. diff --git a/doc/ranger.pod b/doc/ranger.pod index 1b1af68e..6411292c 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -680,15 +680,15 @@ Show the current filter stack state. =item ^B, ^F -Move left and right (B for back, F for forward) +Move left and right (B for back, F for forward). =item ^P, ^N -Move up and down (P for previous, N for Next) +Move up and down (P for previous, N for Next). =item ^A, ^E -Move to the start or to the end +Move to the start or to the end. =item Alt-B -- cgit 1.4.1-2-gfad0 From 499fb0421b0af276a4c971c0e73f4eb0024a7379 Mon Sep 17 00:00:00 2001 From: Leo Vivier Date: Sun, 26 Aug 2018 13:05:57 +0200 Subject: Revert "Fix punctuation in READLINE-LIKE BINDINGS IN THE CONSOLE" This reverts commit dedbabb8eb6035bcbd44c6163834247f1a0415cd. --- doc/ranger.1 | 6 +++--- doc/ranger.pod | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index 936b10bd..380a48dc 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -700,13 +700,13 @@ Show the current filter stack state. .IX Subsection "READLINE-LIKE BINDINGS IN THE CONSOLE" .IP "^B, ^F" 14 .IX Item "^B, ^F" -Move left and right (B for back, F for forward). +Move left and right (B for back, F for forward) .IP "^P, ^N" 14 .IX Item "^P, ^N" -Move up and down (P for previous, N for Next). +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. +Move to the start or to the end .IP "Alt-B" 14 .IX Item "Alt-B" Move backwards by words. diff --git a/doc/ranger.pod b/doc/ranger.pod index 6411292c..1b1af68e 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -680,15 +680,15 @@ Show the current filter stack state. =item ^B, ^F -Move left and right (B for back, F for forward). +Move left and right (B for back, F for forward) =item ^P, ^N -Move up and down (P for previous, N for Next). +Move up and down (P for previous, N for Next) =item ^A, ^E -Move to the start or to the end. +Move to the start or to the end =item Alt-B -- cgit 1.4.1-2-gfad0 From 442c846f1c4f2f1c1e012008eb15ad57e01d765e Mon Sep 17 00:00:00 2001 From: Leo Vivier Date: Sat, 1 Sep 2018 10:49:23 +0200 Subject: Add Alt-LEFT and Alt-RIGHT for moving between words in man --- doc/ranger.1 | 8 ++++---- doc/ranger.pod | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index 380a48dc..0c55638a 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -707,11 +707,11 @@ 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" 14 -.IX Item "Alt-B" +.IP "Alt-B, Alt-LEFT" 14 +.IX Item "Alt-B, Alt-LEFT" Move backwards by words. -.IP "Alt-F" 14 -.IX Item "Alt-F" +.IP "Alt-F, Alt-RIGHT" 14 +.IX Item "Alt-F, Alt-RIGHT" Move forwards by words. .IP "^D" 14 .IX Item "^D" diff --git a/doc/ranger.pod b/doc/ranger.pod index 1b1af68e..3e269261 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -690,11 +690,11 @@ Move up and down (P for previous, N for Next) Move to the start or to the end -=item Alt-B +=item Alt-B, Alt-LEFT Move backwards by words. -=item Alt-F +=item Alt-F, Alt-RIGHT Move forwards by words. -- cgit 1.4.1-2-gfad0 From 3e2cbfe12c760776c66e6b042a5e288a6ee21f26 Mon Sep 17 00:00:00 2001 From: Leo Vivier Date: Sun, 2 Sep 2018 10:03:25 +0200 Subject: Update man --- doc/ranger.1 | 3 +++ doc/ranger.pod | 4 ++++ 2 files changed, 7 insertions(+) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index 0c55638a..d31b6548 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -643,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 content of the last 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 diff --git a/doc/ranger.pod b/doc/ranger.pod index 3e269261..a4f6c7df 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 content of the last command. + =item Alt-I Open a tab. N has to be a number from 0 to 9. If the tab doesn't exist yet, it -- cgit 1.4.1-2-gfad0 From d84a0f10b2a979cb90fb667612cd718d469a549b Mon Sep 17 00:00:00 2001 From: Leo Vivier Date: Sun, 2 Sep 2018 15:46:28 +0200 Subject: Update man with a clearer entry --- doc/ranger.1 | 2 +- doc/ranger.pod | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index d31b6548..ea010eac 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -645,7 +645,7 @@ to use to open the current file selection. Open the console with the content \*(L"cd \*(R" .IP "^P" 14 .IX Item "^P" -Open the console with the content of the last command. +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 diff --git a/doc/ranger.pod b/doc/ranger.pod index a4f6c7df..5c668235 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -599,7 +599,7 @@ Open the console with the content "cd " =item ^P -Open the console with the content of the last command. +Open the console with the most recent command. =item Alt-I -- cgit 1.4.1-2-gfad0 From d9a8bb1cea1f42f694ef65877db73e1d80409846 Mon Sep 17 00:00:00 2001 From: toonn Date: Sat, 8 Sep 2018 14:37:46 +0200 Subject: Fix documentation Remove a setting that no longer exists from the man page. Reformat the comment in `rc.conf`. Use lower case `'none'` for consistency --- doc/ranger.1 | 31 ++++++++++++++++--------------- doc/ranger.pod | 4 ---- ranger/config/rc.conf | 5 ++++- ranger/container/settings.py | 2 +- 4 files changed, 21 insertions(+), 21 deletions(-) (limited to 'doc') diff --git a/doc/ranger.1 b/doc/ranger.1 index 21665bbf..052f06e9 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) +.\" 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. @@ -129,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.9.0b6" "01/04/2018" "ranger manual" +.TH RANGER 1 "ranger-1.9.0b6" "2018-09-08" "ranger manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -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 "OPTIONS" @@ -599,7 +603,7 @@ Toggle the mark-status of all files .IP "V" 14 .IX Item "V" Starts the visual mode, which selects all files between the starting point and -the cursor until you press \s-1ESC. \s0 To unselect files in the same way, use \*(L"uV\*(R". +the cursor until you press \s-1ESC.\s0 To unselect files in the same way, use \*(L"uV\*(R". .IP "/" 14 Search for files in the current directory. .IP ":" 14 @@ -776,9 +780,6 @@ Draw borders around or between the columns? Possible values are: \& separators draw only vertical lines between columns \& both both of the above .Ve -.IP "draw_separators [bool]" 4 -.IX Item "draw_separators [bool]" -Draw vertical separators between columns? .IP "draw_progress_bar_in_status_bar [bool]" 4 .IX Item "draw_progress_bar_in_status_bar [bool]" Draw a progress bar in the status bar which displays the average state of all @@ -1524,7 +1525,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: diff --git a/doc/ranger.pod b/doc/ranger.pod index c54b6dfb..ff042fc7 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -764,10 +764,6 @@ Draw borders around or between the columns? Possible values are: separators draw only vertical lines between columns both both of the above -=item draw_separators [bool] - -Draw vertical separators between columns? - =item draw_progress_bar_in_status_bar [bool] Draw a progress bar in the status bar which displays the average state of all diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 3fd46d38..cd0ac45b 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -123,7 +123,10 @@ set status_bar_on_top false # currently running tasks which support progress bars? set draw_progress_bar_in_status_bar true -# Draw borders around columns? (separators, outline, both, or none. Separators are vertical lines between columsn. Outline draws a box around all the columns. Both combines the two) +# Draw borders around columns? (separators, outline, both, or none) +# Separators are vertical lines between columns. +# Outline draws a box around all the columns. +# Both combines the two. set draw_borders none # Display the directory name in tabs? diff --git a/ranger/container/settings.py b/ranger/container/settings.py index f07c85a6..3e742926 100644 --- a/ranger/container/settings.py +++ b/ranger/container/settings.py @@ -96,7 +96,7 @@ ALLOWED_SETTINGS = { ALLOWED_VALUES = { 'cd_tab_case': ['sensitive', 'insensitive', 'smart'], 'confirm_on_delete': ['multiple', 'always', 'never'], - 'draw_borders': ['None', 'both', 'outline', 'separators'], + 'draw_borders': ['none', 'both', 'outline', 'separators'], 'line_numbers': ['false', 'absolute', 'relative'], 'one_indexed': [False, True], 'preview_images_method': ['w3m', 'iterm2', 'urxvt', 'urxvt-full'], -- cgit 1.4.1-2-gfad0 From 2485dd705e84fb64e3f04f5b4f6956968a5b9708 Mon Sep 17 00:00:00 2001 From: Wojciech Siewierski Date: Sat, 8 Sep 2018 23:33:01 +0200 Subject: New filter type for matching mimetypes --- doc/ranger.pod | 4 ++++ ranger/config/rc.conf | 1 + ranger/core/filter_stack.py | 17 +++++++++++++++++ 3 files changed, 22 insertions(+) (limited to 'doc') diff --git a/doc/ranger.pod b/doc/ranger.pod index 4fac5d50..772107e0 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -628,6 +628,10 @@ the current directory. For a more permanent solution, use the command Apply a new filename filter. +=item .m + +Apply a new mimetype filter. + =item .d Apply the typefilter "directory". diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 4da1ffc0..a32ab494 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -566,6 +566,7 @@ copymap zf zz # Filter stack map .n console filter_stack add name%space +map .m console filter_stack add mime%space map .d filter_stack add type d map .f filter_stack add type f map .l filter_stack add type l diff --git a/ranger/core/filter_stack.py b/ranger/core/filter_stack.py index ff9f4080..2ca2b1c5 100644 --- a/ranger/core/filter_stack.py +++ b/ranger/core/filter_stack.py @@ -6,6 +6,7 @@ from __future__ import (absolute_import, division, print_function) import re +import mimetypes from ranger.container.directory import accept_file, InodeFilterConstants @@ -48,6 +49,22 @@ class NameFilter(BaseFilter): return "".format(self.pattern) +@stack_filter("mime") +class MimeFilter(BaseFilter): + def __init__(self, pattern): + self.pattern = pattern + self.regex = re.compile(pattern) + + def __call__(self, fobj): + mimetype, _ = mimetypes.guess_type(fobj.relative_path) + if mimetype is None: + return False + return self.regex.search(mimetype) + + def __str__(self): + return "".format(self.pattern) + + @stack_filter("type") class TypeFilter(BaseFilter): type_to_function = { -- cgit 1.4.1-2-gfad0