diff options
-rw-r--r-- | .github/workflows/doctest.yml | 30 | ||||
-rw-r--r-- | .github/workflows/py37.yml | 30 | ||||
-rw-r--r-- | .github/workflows/python.yml | 30 | ||||
-rw-r--r-- | .github/workflows/shellcheck.yml | 22 | ||||
-rw-r--r-- | Makefile | 18 | ||||
-rw-r--r-- | README.md | 48 | ||||
-rw-r--r-- | doc/ranger.1 | 142 | ||||
-rw-r--r-- | doc/ranger.desktop | 1 | ||||
-rw-r--r-- | doc/ranger.pod | 136 | ||||
-rw-r--r-- | doc/rifle.1 | 22 | ||||
-rw-r--r-- | examples/rc_emacs.conf | 8 | ||||
-rwxr-xr-x | ranger/config/commands.py | 120 | ||||
-rw-r--r-- | ranger/config/rc.conf | 10 | ||||
-rw-r--r-- | ranger/config/rifle.conf | 26 | ||||
-rw-r--r-- | ranger/container/fsobject.py | 6 | ||||
-rw-r--r-- | ranger/container/settings.py | 5 | ||||
-rw-r--r-- | ranger/core/actions.py | 8 | ||||
-rw-r--r-- | ranger/core/fm.py | 25 | ||||
-rw-r--r-- | ranger/core/main.py | 10 | ||||
-rw-r--r-- | ranger/core/runner.py | 4 | ||||
-rw-r--r-- | ranger/data/mime.types | 4 | ||||
-rwxr-xr-x | ranger/data/scope.sh | 1 | ||||
-rw-r--r-- | ranger/ext/img_display.py | 35 | ||||
-rwxr-xr-x | ranger/ext/rifle.py | 7 | ||||
-rw-r--r-- | ranger/gui/widgets/statusbar.py | 6 |
25 files changed, 571 insertions, 183 deletions
diff --git a/.github/workflows/doctest.yml b/.github/workflows/doctest.yml new file mode 100644 index 00000000..f12cb926 --- /dev/null +++ b/.github/workflows/doctest.yml @@ -0,0 +1,30 @@ +name: Python doctest and pytest + +on: + push: + paths: + - '.github/workflows/doctest.yml' + - '*.py' + +jobs: + test_py: + runs-on: ubuntu-latest + strategy: + max-parallel: 4 + matrix: + python-version: [2.7, 3.5, 3.6] + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 1 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: doctest + run: | + make test_doctest test_other diff --git a/.github/workflows/py37.yml b/.github/workflows/py37.yml new file mode 100644 index 00000000..ca8210a2 --- /dev/null +++ b/.github/workflows/py37.yml @@ -0,0 +1,30 @@ +name: Python 3.7 lints and tests + +on: + push: + paths: + - '.github/workflows/py37.yml' + - '*.py' + +jobs: + test_py: + runs-on: ubuntu-latest + strategy: + max-parallel: 4 + matrix: + python-version: [3.7] + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 1 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r <(sed 's/<2//' requirements.txt) + - name: Lint and test with pylint, flake8, doctest, pytest + run: | + make test_py diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml new file mode 100644 index 00000000..1daba84c --- /dev/null +++ b/.github/workflows/python.yml @@ -0,0 +1,30 @@ +name: Python lints and tests + +on: + push: + paths: + - '.github/workflows/python.yml' + - '*.py' + +jobs: + test_py: + runs-on: ubuntu-latest + strategy: + max-parallel: 4 + matrix: + python-version: [2.7, 3.5, 3.6] + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 1 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Lint and test with pylint, flake8, -d-o-c-t-e-s-t-, -p-y-t-e-s-t- + run: | + make test_pylint test_flake8 test_pytest diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml new file mode 100644 index 00000000..0d10cf61 --- /dev/null +++ b/.github/workflows/shellcheck.yml @@ -0,0 +1,22 @@ +name: Shellcheck scope.sh + +on: + push: + paths: + - '.github/workflows/shellcheck.yml' + - 'ranger/data/scope.sh' + +jobs: + test_shellcheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 1 + - name: Install newer shellcheck (0.7.0 rather than 0.4.6) + run: | + curl -LO "https://storage.googleapis.com/shellcheck/shellcheck-stable.linux.x86_64.tar.xz" + tar xf shellcheck-stable.linux.x86_64.tar.xz + - name: Shellcheck scope.sh + run: | + env PATH=shellcheck-stable:$PATH make test_shellcheck diff --git a/Makefile b/Makefile index 87c5ff1b..15dbb9db 100644 --- a/Makefile +++ b/Makefile @@ -125,11 +125,19 @@ test_other: test: test_py test_shellcheck @echo "Finished testing: All tests passed!" -man: - pod2man --stderr --center='ranger manual' --date='$(NAME)-$(VERSION)' \ - --release=$(shell date +%x) doc/ranger.pod doc/ranger.1 - pod2man --stderr --center='rifle manual' --date='$(NAME_RIFLE)-$(VERSION_RIFLE)' \ - --release=$(shell date +%x) doc/rifle.pod doc/rifle.1 +doc/ranger.1: doc/ranger.pod + pod2man --stderr --center='ranger manual' \ + --date='$(NAME)-$(VERSION)' \ + --release=$(shell date -u '+%Y-%m-%d') \ + doc/ranger.pod doc/ranger.1 + +doc/rifle.1: doc/rifle.pod + pod2man --stderr --center='rifle manual' \ + --date='$(NAME_RIFLE)-$(VERSION_RIFLE)' \ + --release=$(shell date -u '+%Y-%m-%d') \ + doc/rifle.pod doc/rifle.1 + +man: doc/ranger.1 doc/rifle.1 manhtml: pod2html doc/ranger.pod --outfile=doc/ranger.1.html diff --git a/README.md b/README.md index be17f0f9..85f6137e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ ranger 1.9.2 ============ +<img src="https://ranger.github.io/ranger_logo.png" width="150"> + [![Build Status](https://travis-ci.org/ranger/ranger.svg?branch=master)](https://travis-ci.org/ranger/ranger) <a href="https://repology.org/metapackage/ranger/versions"> <img src="https://repology.org/badge/latest-versions/ranger.svg" alt="latest packaged version(s)"> @@ -73,26 +75,36 @@ Dependencies and (optionally) wide-unicode support * A pager (`less` by default) -Optional: +### Optional dependencies + +For general usage: -* The `file` program for determining file types -* The Python module `chardet`, in case of encoding detection problems +* `file` for determining file types +* `chardet` (Python package) for improved encoding detection of text files * `sudo` to use the "run as root" feature -* `w3m` for the `w3mimgdisplay` program to preview images -* `python-bidi` for correct display of RTL file names (Hebrew, Arabic) +* `python-bidi` to display right-to-left file names correctly (Hebrew, Arabic) -Optional, for enhanced file previews (with `scope.sh`): +For enhanced file previews (with `scope.sh`): * `img2txt` (from `caca-utils`) for ASCII-art image previews +* `w3mimgdisplay`, `ueberzug`, `kitty`, `terminology` or `urxvt` for image + previews +* `convert` (from `imagemagick`) to auto-rotate images and for SVG previews +* `ffmpegthumbnailer` for video thumbnails * `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` or `mutool` for `pdf` previews +* `atool`, `bsdtar`, `unrar` and/or `7z` to preview archives +* `bsdtar`, `tar`, `unrar` and/or `unzip` to preview archives as their first + image +* `lynx`, `w3m` or `elinks` to preview html pages +* `pdftotext` or `mutool` for textual `pdf` previews, `pdftoppm` to preview as + image +* `djvutxt` for textual DjVu previews, `ddjvu` to preview as image +* `calibre` or `epub-thumbnailer` for image previews of ebooks * `transmission-show` for viewing BitTorrent information * `mediainfo` or `exiftool` for viewing information about media files * `odt2txt` for OpenDocument text files (`odt`, `ods`, `odp` and `sxw`) -* `chardet` (Python package) for improved encoding detection of text files - +* `python` or `jq` for JSON files +* `fontimage` for font previews Installing ---------- @@ -141,3 +153,17 @@ Ranger can automatically copy default configuration files to `~/.config/ranger` if you run it with the switch `--copy-config=( rc | scope | ... | all )`. See `ranger --help` for a description of that switch. Also check `ranger/config/` for the default configuration. + + +Going Further +--------------- +* To get the most out of ranger, read the [Official User Guide](https://github.com/ranger/ranger/wiki/Official-user-guide). +* For frequently asked questions, see the [FAQ](https://github.com/ranger/ranger/wiki/FAQ%3A-Frequently-Asked-Questions). +* For more information on customization, see the [wiki](https://github.com/ranger/ranger/wiki). + + +Community +--------------- +For help, support, or if you just want to hang out with us, you can find us here: +* **IRC**: channel **#ranger** on [freenode](https://freenode.net/kb/answer/chat) +* **Reddit**: [r/ranger](https://www.reddit.com/r/ranger/) diff --git a/doc/ranger.1 b/doc/ranger.1 index 2f233c95..a6e20b4c 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -133,12 +133,11 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.9.2" "2019-06-18" "ranger manual" +.TH RANGER 1 "ranger-1.9.2" "2019-10-02" "ranger manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh -.SH "NAME" ranger \- visual file manager .SH "SYNOPSIS" .IX Header "SYNOPSIS" @@ -290,18 +289,6 @@ Independently of the preview script, there is a feature to preview images by drawing them directly into the terminal. To enable this feature, set the option \f(CW\*(C`preview_images\*(C'\fR to true and enable one of the image preview modes: .PP -\fIw3m\fR -.IX Subsection "w3m" -.PP -This does not work over ssh, requires certain terminals (tested on \*(L"xterm\*(R" and -\&\*(L"urxvt\*(R") and is incompatible with tmux, although it works with screen. -.PP -To enable this feature, install the program \*(L"w3m\*(R" and set the option -\&\f(CW\*(C`preview_images_method\*(C'\fR to w3m. -.PP -When using a terminal with a nonzero border which is not automatically detected, the w3m preview will be misaligned. -Use the \f(CW\*(C`w3m_offset\*(C'\fR option to manually adjust the image offset. This should be the same value as the terminal's border value. -.PP \fIiTerm2\fR .IX Subsection "iTerm2" .PP @@ -314,6 +301,14 @@ 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 +\fIkitty\fR +.IX Subsection "kitty" +.PP +This only works in Kitty. It requires \s-1PIL\s0 (or pillow) to work. +Allows remote image previews, for example in an ssh session. +.PP +To enable this feature, set the option \f(CW\*(C`preview_images_method\*(C'\fR to kitty. +.PP \fIterminology\fR .IX Subsection "terminology" .PP @@ -321,6 +316,16 @@ This only works in terminology. It can render vector graphics, but works only lo .PP To enable this feature, set the option \f(CW\*(C`preview_images_method\*(C'\fR to terminology. .PP +\fIueberzug\fR +.IX Subsection "ueberzug" +.PP +U\*:berzug is a command line utility which draws images on terminals using child +windows. It requires \s-1PIL\s0 (or pillow) and relies on X11. This makes it +compatible (in a limited way, i.e., tmux splits are not supported) with many +terminals and tmux but not the Linux console or Wayland. +.PP +To enable this feature, set the option \f(CW\*(C`preview_images_method\*(C'\fR to ueberzug. +.PP \fIurxvt\fR .IX Subsection "urxvt" .PP @@ -339,13 +344,17 @@ 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" +\fIw3m\fR +.IX Subsection "w3m" .PP -This only works on Kitty. It requires \s-1PIL\s0 (or pillow) to work. -Allows remote image previews, for example in an ssh session. +This does not work over ssh, requires certain terminals (tested on \*(L"xterm\*(R" and +\&\*(L"urxvt\*(R") and is incompatible with tmux, although it works with screen. .PP -To enable this feature, set the option \f(CW\*(C`preview_images_method\*(C'\fR to kitty. +To enable this feature, install the program \*(L"w3m\*(R" and set the option +\&\f(CW\*(C`preview_images_method\*(C'\fR to w3m. +.PP +When using a terminal with a nonzero border which is not automatically detected, the w3m preview will be misaligned. +Use the \f(CW\*(C`w3m_offset\*(C'\fR option to manually adjust the image offset. This should be the same value as the terminal's border value. .SS "\s-1SELECTION\s0" .IX Subsection "SELECTION" The \fIselection\fR is defined as \*(L"All marked files \s-1IF THERE ARE ANY,\s0 otherwise @@ -432,6 +441,10 @@ the end of a command when needed, while preventing editors to strip spaces off the end of the line automatically. .PP To write a literal %, you need to escape it by writing %%. +.PP +Note that macros are expanded twice when using chain. For example, to insert +a space character in a chained command, you would write %%space: + chain command1; command2%%space .SS "\s-1BOOKMARKS\s0" .IX Subsection "BOOKMARKS" Type \fBm<key>\fR to bookmark the current directory. You can re-enter this @@ -687,6 +700,9 @@ Open the console with the most recent command. .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 will be created. +.IP "Alt-l, Alt-r" 14 +.IX Item "Alt-l, Alt-r" +Shift a tab left, respectively right. .IP "gn, ^N" 14 .IX Item "gn, ^N" Create a new tab. @@ -967,6 +983,13 @@ all directories above the current one as well? .IP "mouse_enabled [bool] <zm>" 4 .IX Item "mouse_enabled [bool] <zm>" Enable mouse input? +.IP "nested_ranger_warning [string]" 4 +.IX Item "nested_ranger_warning [string]" +Warn at startup if \f(CW\*(C`RANGER_LEVEL\*(C'\fR is greater than 0, in other words give a +warning when you nest ranger in a subshell started by ranger. Allowed values +are \f(CW\*(C`true\*(C'\fR, \f(CW\*(C`false\*(C'\fR and \f(CW\*(C`error\*(C'\fR. The special value \f(CW\*(C`error\*(C'\fR promotes the +warning to an error, this is usually shown as red text but will crash ranger +when run with the \f(CW\*(C`\-\-debug\*(C'\fR flag. .IP "one_indexed [bool]" 4 .IX Item "one_indexed [bool]" Start line numbers from 1. Possible values are: @@ -1104,6 +1127,10 @@ Sets the state for the version control backend. The possible values are: \& local display only local state. \& enabled display both, local and remote state. May be slow for hg and bzr. .Ve +.IP "vcs_msg_length [int]" 4 +.IX Item "vcs_msg_length [int]" +Length to truncate first line of the commit messages to when shown in +the statusbar. Defaults to 50. .IP "viewmode [string]" 4 .IX Item "viewmode [string]" Sets the view mode, which can be \fBmiller\fR to display the files in the @@ -1188,6 +1215,7 @@ ranger. For your convenience, this is a list of the \*(L"public\*(R" commands i \& terminal \& tmap key command \& touch filename +\& trash \& travel pattern \& tunmap keys... \& unmap keys... @@ -1233,33 +1261,27 @@ example, \fB+ar\fR allows reading for everyone, \-ow forbids others to write and 777= allows everything. .Sp See also: man 1 chmod -.IP "cmap \fIkey\fR \fIcommand\fR" 2 -.IX Item "cmap key command" -Binds keys for the console. Works like the \f(CW\*(C`map\*(C'\fR command. .IP "console [\-p\fIN\fR] \fIcommand\fR" 2 .IX Item "console [-pN] command" Opens the console with the command already typed in. The cursor is placed at \&\fIN\fR. +.IP "copymap \fIkey\fR \fInewkey\fR [\fInewkey2\fR ...]" 2 +.IX Item "copymap key newkey [newkey2 ...]" +.PD 0 .IP "copycmap \fIkey\fR \fInewkey\fR [\fInewkey2\fR ...]" 2 .IX Item "copycmap key newkey [newkey2 ...]" -See \f(CW\*(C`copymap\*(C'\fR -.IP "copymap \fIkey\fR \fInewkey\fR [\fInewkey2\fR ...]" 2 -.IX Item "copymap key newkey [newkey2 ...]" -Copies the keybinding \fIkey\fR to \fInewkey\fR in the \*(L"browser\*(R" context. This is a -deep copy, so if you change the new binding (or parts of it) later, the old one -is not modified. -.Sp -To copy key bindings of the console, taskview, or pager use \*(L"copycmap\*(R", -\&\*(L"copytmap\*(R" or \*(L"copypmap\*(R". .IP "copypmap \fIkey\fR \fInewkey\fR [\fInewkey2\fR ...]" 2 .IX Item "copypmap key newkey [newkey2 ...]" -See \f(CW\*(C`copymap\*(C'\fR .IP "copytmap \fIkey\fR \fInewkey\fR [\fInewkey2\fR ...]" 2 .IX Item "copytmap key newkey [newkey2 ...]" -See \f(CW\*(C`copymap\*(C'\fR -.IP "cunmap [\fIkeys...\fR]" 2 -.IX Item "cunmap [keys...]" -Removes key mappings of the console. Works like the \f(CW\*(C`unmap\*(C'\fR command. +.PD +Copies the keybinding \fIkey\fR to \fInewkey\fR in the \*(L"browser\*(R" context. This is a +deep copy, so if you change the new binding (or parts of it) later, the old one +is not modified. For example, \fIcopymap j down\fR will make the key sequence +\&\*(L"down\*(R" move the cursor down one item. +.Sp +To copy key bindings of the console, pager or taskview use \*(L"copycmap\*(R", +\&\*(L"copypmap\*(R" or \*(L"copytmap\*(R" respectively. .IP "default_linemode [\fIpath=regexp\fR | \fItag=tags\fR] \fIlinemodename\fR" 2 .IX Item "default_linemode [path=regexp | tag=tags] linemodename" Sets the default linemode. See \fIlinemode\fR command. @@ -1365,16 +1387,24 @@ See the \fIranger.core.linemode\fR module for some examples. .IX Item "load_copy_buffer" Load the copy buffer from \fI~/.config/ranger/copy_buffer\fR. This can be used to pass the list of copied files to another ranger instance. -.IP "map \fIkey\fR \fIcommand\fR" 2 +.IP "map \fIkey\fR \fIcommand\fR" 2 .IX Item "map key command" +.PD 0 +.IP "cmap \fIkey\fR \fIcommand\fR" 2 +.IX Item "cmap key command" +.IP "pmap \fIkey\fR \fIcommand\fR" 2 +.IX Item "pmap key command" +.IP "tmap \fIkey\fR \fIcommand\fR" 2 +.IX Item "tmap key command" +.PD Assign the key combination to the given command. Whenever you type the key/keys, the command will be executed. Additionally, if you use a quantifier when typing the key, like 5j, it will be passed to the command as the attribute \&\*(L"self.quantifier\*(R". .Sp The keys you bind with this command are accessible in the file browser only, -not in the console, task view or pager. To bind keys there, use the commands -\&\*(L"cmap\*(R", \*(L"tmap\*(R" or \*(L"pmap\*(R". +not in the console, pager or taskview. To bind keys there, use the commands +\&\*(L"cmap\*(R", \*(L"pmap\*(R" or \*(L"tmap\*(R". .IP "mark \fIpattern\fR" 2 .IX Item "mark pattern" Mark all files matching the regular expression pattern. @@ -1408,16 +1438,10 @@ of applications is generated by the external file opener \*(L"rifle\*(R" and can displayed when pressing \*(L"r\*(R" in ranger. .Sp Note that if you specify an application, the mode is ignored. -.IP "pmap \fIkey\fR \fIcommand\fR" 2 -.IX Item "pmap key command" -Binds keys for the pager. Works like the \f(CW\*(C`map\*(C'\fR command. .IP "prompt_metadata [\fIkeys ...\fR]" 2 .IX Item "prompt_metadata [keys ...]" Prompt the user to input metadata with the \f(CW\*(C`meta\*(C'\fR command for multiple keys in a row. -.IP "punmap [\fIkeys ...\fR]" 2 -.IX Item "punmap [keys ...]" -Removes key mappings of the pager. Works like the \f(CW\*(C`unmap\*(C'\fR command. .IP "quit" 2 .IX Item "quit" Closes the current tab, if there's only one tab. Otherwise quits if there are no tasks in progress. @@ -1544,12 +1568,19 @@ Scroll the file preview by \fIvalue\fR lines. .IP "terminal" 2 .IX Item "terminal" Spawns the \fIx\-terminal-emulator\fR starting in the current directory. -.IP "tmap \fIkey\fR \fIcommand\fR" 2 -.IX Item "tmap key command" -Binds keys for the taskview. Works like the \f(CW\*(C`map\*(C'\fR command. .IP "touch \fIfilename\fR" 2 .IX Item "touch filename" Creates an empty file with the name \fIfilename\fR, unless it already exists. +.IP "trash" 2 +.IX Item "trash" +Move all files in the selection to the trash using rifle. Rifle tries to use a +trash manager like \fItrash-cli\fR if available but will fall back to moving files +to either \fI\f(CI$XDG_DATA_HOME\fI/ranger\-trash\fR or \fI~/.ranger/ranger\-trash\fR. This is +a less permanent version of \fIdelete\fR, relying on the user to clear out the +trash whenever it's convenient. While having the possibility of restoring +trashed files until this happens. ranger will ask for a confirmation if you +attempt to trash multiple (marked) files or non-empty directories. This can be +changed by modifying the setting \*(L"confirm_on_delete\*(R". .IP "travel \fIpattern\fR" 2 .IX Item "travel pattern" Filters the current directory for files containing the letters in the @@ -1559,13 +1590,18 @@ is automatically reopened, allowing for fast travel. To close the console, press \s-1ESC\s0 or execute a file. .Sp This command is based on the \fIscout\fR command and supports all of its options. -.IP "tunmap [\fIkeys ...\fR]" 2 -.IX Item "tunmap [keys ...]" -Removes key mappings of the taskview. Works like the \f(CW\*(C`unmap\*(C'\fR command. -.IP "unmap [\fIkeys\fR ...]" 2 +.IP "unmap [\fIkeys\fR ...]" 2 .IX Item "unmap [keys ...]" +.PD 0 +.IP "cunmap [\fIkeys\fR ...]" 2 +.IX Item "cunmap [keys ...]" +.IP "punmap [\fIkeys\fR ...]" 2 +.IX Item "punmap [keys ...]" +.IP "tunmap [\fIkeys\fR ...]" 2 +.IX Item "tunmap [keys ...]" +.PD Removes the given key mappings in the \*(L"browser\*(R" context. To unmap key bindings -in the console, taskview, or pager use \*(L"cunmap\*(R", \*(L"tunmap\*(R" or \*(L"punmap\*(R". +in the console, pager, or taskview use \*(L"cunmap\*(R", \*(L"punmap\*(R" or \*(L"tunmap\*(R". .IP "unmark \fIpattern\fR" 2 .IX Item "unmark pattern" Unmark all files matching a regular expression pattern. diff --git a/doc/ranger.desktop b/doc/ranger.desktop index 9c140185..55d68ed8 100644 --- a/doc/ranger.desktop +++ b/doc/ranger.desktop @@ -7,3 +7,4 @@ Terminal=true Exec=ranger Categories=ConsoleOnly;System;FileTools;FileManager MimeType=inode/directory; +Keywords=File;Manager;Browser;Explorer;Launcher;Vi;Vim;Python diff --git a/doc/ranger.pod b/doc/ranger.pod index 3b59c9e5..852afcdc 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -1,3 +1,4 @@ +=encoding utf8 =head1 NAME ranger - visual file manager @@ -201,17 +202,6 @@ Independently of the preview script, there is a feature to preview images by drawing them directly into the terminal. To enable this feature, set the option C<preview_images> to true and enable one of the image preview modes: -=head3 w3m - -This does not work over ssh, requires certain terminals (tested on "xterm" and -"urxvt") and is incompatible with tmux, although it works with screen. - -To enable this feature, install the program "w3m" and set the option -C<preview_images_method> to w3m. - -When using a terminal with a nonzero border which is not automatically detected, the w3m preview will be misaligned. -Use the C<w3m_offset> option to manually adjust the image offset. This should be the same value as the terminal's border value. - =head3 iTerm2 This only works in iTerm2 compiled with image preview support, but works over @@ -223,12 +213,28 @@ 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<iterm2_font_width> and C<iterm2_font_height> to the desired values. +=head3 kitty + +This only works in Kitty. It requires PIL (or pillow) to work. +Allows remote image previews, for example in an ssh session. + +To enable this feature, set the option C<preview_images_method> to kitty. + =head3 terminology This only works in terminology. It can render vector graphics, but works only locally. To enable this feature, set the option C<preview_images_method> to terminology. +=head3 ueberzug + +Ćberzug is a command line utility which draws images on terminals using child +windows. It requires PIL (or pillow) and relies on X11. This makes it +compatible (in a limited way, i.e., tmux splits are not supported) with many +terminals and tmux but not the Linux console or Wayland. + +To enable this feature, set the option C<preview_images_method> to ueberzug. + =head3 urxvt This only works in urxvt compiled with pixbuf support. Does not work over ssh. @@ -245,12 +251,16 @@ window. To enable this feature, set the option C<preview_images_method> to urxvt-full. -=head3 kitty +=head3 w3m -This only works on Kitty. It requires PIL (or pillow) to work. -Allows remote image previews, for example in an ssh session. +This does not work over ssh, requires certain terminals (tested on "xterm" and +"urxvt") and is incompatible with tmux, although it works with screen. -To enable this feature, set the option C<preview_images_method> to kitty. +To enable this feature, install the program "w3m" and set the option +C<preview_images_method> to w3m. + +When using a terminal with a nonzero border which is not automatically detected, the w3m preview will be misaligned. +Use the C<w3m_offset> option to manually adjust the image offset. This should be the same value as the terminal's border value. =head2 SELECTION @@ -328,6 +338,10 @@ the end of the line automatically. To write a literal %, you need to escape it by writing %%. +Note that macros are expanded twice when using chain. For example, to insert +a space character in a chained command, you would write %%space: + chain command1; command2%%space + =head2 BOOKMARKS Type B<m<keyE<gt>> to bookmark the current directory. You can re-enter this @@ -635,6 +649,10 @@ Open the console with the most recent command. Open a tab. N has to be a number from 0 to 9. If the tab doesn't exist yet, it will be created. +=item Alt-l, Alt-r + +Shift a tab left, respectively right. + =item gn, ^N Create a new tab. @@ -981,6 +999,14 @@ all directories above the current one as well? Enable mouse input? +=item nested_ranger_warning [string] + +Warn at startup if C<RANGER_LEVEL> is greater than 0, in other words give a +warning when you nest ranger in a subshell started by ranger. Allowed values +are C<true>, C<false> and C<error>. The special value C<error> promotes the +warning to an error, this is usually shown as red text but will crash ranger +when run with the C<--debug> flag. + =item one_indexed [bool] Start line numbers from 1. Possible values are: @@ -1148,6 +1174,11 @@ Sets the state for the version control backend. The possible values are: local display only local state. enabled display both, local and remote state. May be slow for hg and bzr. +=item vcs_msg_length [int] + +Length to truncate first line of the commit messages to when shown in +the statusbar. Defaults to 50. + =item viewmode [string] Sets the view mode, which can be B<miller> to display the files in the @@ -1239,6 +1270,7 @@ ranger. For your convenience, this is a list of the "public" commands including terminal tmap key command touch filename + trash travel pattern tunmap keys... unmap keys... @@ -1291,39 +1323,26 @@ example, B<+ar> allows reading for everyone, -ow forbids others to write and See also: man 1 chmod -=item cmap I<key> I<command> - -Binds keys for the console. Works like the C<map> command. - =item console [-pI<N>] I<command> Opens the console with the command already typed in. The cursor is placed at I<N>. -=item copycmap I<key> I<newkey> [I<newkey2> ...] - -See C<copymap> - -=item copymap I<key> I<newkey> [I<newkey2> ...] +=item copymap I<key> I<newkey> [I<newkey2> ...] -Copies the keybinding I<key> to I<newkey> in the "browser" context. This is a -deep copy, so if you change the new binding (or parts of it) later, the old one -is not modified. - -To copy key bindings of the console, taskview, or pager use "copycmap", -"copytmap" or "copypmap". +=item copycmap I<key> I<newkey> [I<newkey2> ...] =item copypmap I<key> I<newkey> [I<newkey2> ...] -See C<copymap> - =item copytmap I<key> I<newkey> [I<newkey2> ...] -See C<copymap> - -=item cunmap [I<keys...>] +Copies the keybinding I<key> to I<newkey> in the "browser" context. This is a +deep copy, so if you change the new binding (or parts of it) later, the old one +is not modified. For example, I<copymap j down> will make the key sequence +"down" move the cursor down one item. -Removes key mappings of the console. Works like the C<unmap> command. +To copy key bindings of the console, pager or taskview use "copycmap", +"copypmap" or "copytmap" respectively. =item default_linemode [I<path=regexp> | I<tag=tags>] I<linemodename> @@ -1442,7 +1461,13 @@ See the I<ranger.core.linemode> module for some examples. Load the copy buffer from F<~/.config/ranger/copy_buffer>. This can be used to pass the list of copied files to another ranger instance. -=item map I<key> I<command> +=item map I<key> I<command> + +=item cmap I<key> I<command> + +=item pmap I<key> I<command> + +=item tmap I<key> I<command> Assign the key combination to the given command. Whenever you type the key/keys, the command will be executed. Additionally, if you use a quantifier @@ -1450,8 +1475,8 @@ when typing the key, like 5j, it will be passed to the command as the attribute "self.quantifier". The keys you bind with this command are accessible in the file browser only, -not in the console, task view or pager. To bind keys there, use the commands -"cmap", "tmap" or "pmap". +not in the console, pager or taskview. To bind keys there, use the commands +"cmap", "pmap" or "tmap". =item mark I<pattern> @@ -1489,19 +1514,11 @@ displayed when pressing "r" in ranger. Note that if you specify an application, the mode is ignored. -=item pmap I<key> I<command> - -Binds keys for the pager. Works like the C<map> command. - =item prompt_metadata [I<keys ...>] Prompt the user to input metadata with the C<meta> command for multiple keys in a row. -=item punmap [I<keys ...>] - -Removes key mappings of the pager. Works like the C<unmap> command. - =item quit Closes the current tab, if there's only one tab. Otherwise quits if there are no tasks in progress. @@ -1640,14 +1657,21 @@ Scroll the file preview by I<value> lines. Spawns the I<x-terminal-emulator> starting in the current directory. -=item tmap I<key> I<command> - -Binds keys for the taskview. Works like the C<map> command. - =item touch I<filename> Creates an empty file with the name I<filename>, unless it already exists. +=item trash + +Move all files in the selection to the trash using rifle. Rifle tries to use a +trash manager like I<trash-cli> if available but will fall back to moving files +to either F<$XDG_DATA_HOME/ranger-trash> or F<~/.ranger/ranger-trash>. This is +a less permanent version of I<delete>, relying on the user to clear out the +trash whenever it's convenient. While having the possibility of restoring +trashed files until this happens. ranger will ask for a confirmation if you +attempt to trash multiple (marked) files or non-empty directories. This can be +changed by modifying the setting "confirm_on_delete". + =item travel I<pattern> Filters the current directory for files containing the letters in the @@ -1658,14 +1682,16 @@ To close the console, press ESC or execute a file. This command is based on the I<scout> command and supports all of its options. -=item tunmap [I<keys ...>] +=item unmap [I<keys> ...] + +=item cunmap [I<keys> ...] -Removes key mappings of the taskview. Works like the C<unmap> command. +=item punmap [I<keys> ...] -=item unmap [I<keys> ...] +=item tunmap [I<keys> ...] Removes the given key mappings in the "browser" context. To unmap key bindings -in the console, taskview, or pager use "cunmap", "tunmap" or "punmap". +in the console, pager, or taskview use "cunmap", "punmap" or "tunmap". =item unmark I<pattern> diff --git a/doc/rifle.1 b/doc/rifle.1 index a42734d2..114cc5d0 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.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 "RIFLE 1" -.TH RIFLE 1 "rifle-1.9.2" "2019-04-03" "rifle manual" +.TH RIFLE 1 "rifle-1.9.2" "08/18/2019" "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/examples/rc_emacs.conf b/examples/rc_emacs.conf index ac3937bf..ba8eaaeb 100644 --- a/examples/rc_emacs.conf +++ b/examples/rc_emacs.conf @@ -59,6 +59,9 @@ set vcs_backend_git enabled set vcs_backend_hg disabled set vcs_backend_bzr disabled +# Truncate the long commit messages to this length when shown in the statusbar. +set vcs_msg_length 50 + # Use one of the supported image preview protocols set preview_images false @@ -209,6 +212,11 @@ set idle_delay 2000 # check all directories above the current one as well? set metadata_deep_search false +# Warn at startup if RANGER_LEVEL env var is greater than 0, in other words +# give a warning when you nest ranger in a subshell started by ranger. +# Special value "error" makes the warning more visible. +set nested_ranger_warning true + # =================================================================== # == Local Options # =================================================================== diff --git a/ranger/config/commands.py b/ranger/config/commands.py index 2b1f4940..cb6fa132 100755 --- a/ranger/config/commands.py +++ b/ranger/config/commands.py @@ -572,7 +572,7 @@ class default_linemode(Command): class quit(Command): # pylint: disable=redefined-builtin """:quit - Closes the current tab, if there's only one tab. + Closes the current tab, if there's more than one tab. Otherwise quits if there are no tasks in progress. """ def _exit_no_work(self): @@ -591,7 +591,7 @@ class quit(Command): # pylint: disable=redefined-builtin class quit_bang(Command): """:quit! - Closes the current tab, if there's only one tab. + Closes the current tab, if there's more than one tab. Otherwise force quits immediately. """ name = 'quit!' @@ -699,6 +699,64 @@ class delete(Command): self.fm.delete(files) +class trash(Command): + """:trash + + Tries to move the selection or the files passed in arguments (if any) to + the trash, using rifle rules with label "trash". + The arguments use a shell-like escaping. + + "Selection" is defined as all the "marked files" (by default, you + can mark files with space or v). If there are no marked files, + use the "current file" (where the cursor is) + + When attempting to trash non-empty directories or multiple + marked files, it will require a confirmation. + """ + + allow_abbrev = False + escape_macros_for_shell = True + + def execute(self): + import shlex + from functools import partial + + def is_directory_with_files(path): + return os.path.isdir(path) and not os.path.islink(path) and len(os.listdir(path)) > 0 + + if self.rest(1): + files = shlex.split(self.rest(1)) + many_files = (len(files) > 1 or is_directory_with_files(files[0])) + else: + cwd = self.fm.thisdir + tfile = self.fm.thisfile + if not cwd or not tfile: + self.fm.notify("Error: no file selected for deletion!", bad=True) + return + + # relative_path used for a user-friendly output in the confirmation. + files = [f.relative_path for f in self.fm.thistab.get_selection()] + many_files = (cwd.marked_items or is_directory_with_files(tfile.path)) + + confirm = self.fm.settings.confirm_on_delete + if confirm != 'never' and (confirm != 'multiple' or many_files): + self.fm.ui.console.ask( + "Confirm deletion of: %s (y/N)" % ', '.join(files), + partial(self._question_callback, files), + ('n', 'N', 'y', 'Y'), + ) + else: + # no need for a confirmation, just delete + self.fm.execute_file(files, label='trash') + + def tab(self, tabnum): + return self._tab_directory_content() + + def _question_callback(self, files, answer): + if answer == 'y' or answer == 'Y': + self.fm.execute_file(files, label='trash') + + class jump_non(Command): """:jump_non [-FLAGS...] @@ -1244,7 +1302,7 @@ class copycmap(copymap): class copytmap(copymap): - """:copycmap <keys> <newkeys1> [<newkeys2>...] + """:copytmap <keys> <newkeys1> [<newkeys2>...] Copies a "taskview" keybinding from <keys> to <newkeys> """ @@ -1263,30 +1321,69 @@ class unmap(Command): self.fm.ui.keymaps.unbind(self.context, arg) -class cunmap(unmap): +class uncmap(unmap): + """:uncmap <keys> [<keys2>, ...] + + Remove the given "console" mappings + """ + context = 'console' + + +class cunmap(uncmap): """:cunmap <keys> [<keys2>, ...] Remove the given "console" mappings + + DEPRECATED in favor of uncmap. """ - context = 'browser' + def execute(self): + self.fm.notify("cunmap is deprecated in favor of uncmap!") + super(cunmap, self).execute() -class punmap(unmap): - """:punmap <keys> [<keys2>, ...] + +class unpmap(unmap): + """:unpmap <keys> [<keys2>, ...] Remove the given "pager" mappings """ context = 'pager' -class tunmap(unmap): - """:tunmap <keys> [<keys2>, ...] +class punmap(unpmap): + """:punmap <keys> [<keys2>, ...] + + Remove the given "pager" mappings + + DEPRECATED in favor of unpmap. + """ + + def execute(self): + self.fm.notify("punmap is deprecated in favor of unpmap!") + super(punmap, self).execute() + + +class untmap(unmap): + """:untmap <keys> [<keys2>, ...] Remove the given "taskview" mappings """ context = 'taskview' +class tunmap(untmap): + """:tunmap <keys> [<keys2>, ...] + + Remove the given "taskview" mappings + + DEPRECATED in favor of untmap. + """ + + def execute(self): + self.fm.notify("tunmap is deprecated in favor of untmap!") + super(tunmap, self).execute() + + class map_(Command): """:map <keysequence> <command> @@ -1827,11 +1924,14 @@ class yank(Command): ['xsel'], ['xsel', '-b'], ], + 'wl-copy': [ + ['wl-copy'], + ], 'pbcopy': [ ['pbcopy'], ], } - ordered_managers = ['pbcopy', 'xclip', 'xsel'] + ordered_managers = ['pbcopy', 'wl-copy', 'xclip', 'xsel'] executables = get_executables() for manager in ordered_managers: if manager in executables: diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index b4bb4bfc..23601fb6 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -67,6 +67,9 @@ set vcs_backend_hg disabled set vcs_backend_bzr disabled set vcs_backend_svn disabled +# Truncate the long commit messages to this length when shown in the statusbar. +set vcs_msg_length 50 + # Use one of the supported image preview protocols set preview_images false @@ -304,6 +307,11 @@ set freeze_files false # Print file sizes in bytes instead of the default human-readable format. set size_in_bytes false +# Warn at startup if RANGER_LEVEL env var is greater than 0, in other words +# give a warning when you nest ranger in a subshell started by ranger. +# Special value "error" makes the warning more visible. +set nested_ranger_warning true + # =================================================================== # == Local Options # =================================================================== @@ -399,6 +407,7 @@ map <F5> copy map <F6> cut map <F7> console mkdir%space map <F8> console delete +#map <F8> console trash map <F10> exit # In case you work on a keyboard with dvorak layout @@ -486,6 +495,7 @@ map p`<any> paste dest=%any_path map p'<any> paste dest=%any_path map dD console delete +map dT console trash map dd cut map ud uncut diff --git a/ranger/config/rifle.conf b/ranger/config/rifle.conf index a90646e2..86f53fd1 100644 --- a/ranger/config/rifle.conf +++ b/ranger/config/rifle.conf @@ -26,7 +26,7 @@ # directory | $1 is a directory # number <n> | change the number of this command to n # terminal | stdin, stderr and stdout are connected to a terminal -# X | $DISPLAY is not empty (i.e. Xorg runs) +# X | A graphical environment is available (darwin, Xorg, or Wayland) # # There are also pseudo-conditions which have a "side effect": # flag <flags> | Change how the program is run. See below. @@ -66,13 +66,13 @@ ext x?html?, has uzbl-tabbed, X, flag f = uzbl-tabbed -- "$@" ext x?html?, has uzbl-browser, X, flag f = uzbl-browser -- "$@" ext x?html?, has uzbl-core, X, flag f = uzbl-core -- "$@" ext x?html?, has midori, X, flag f = midori -- "$@" -ext x?html?, has chromium-browser, X, flag f = chromium-browser -- "$@" -ext x?html?, has chromium, X, flag f = chromium -- "$@" -ext x?html?, has google-chrome, X, flag f = google-chrome -- "$@" ext x?html?, has opera, X, flag f = opera -- "$@" ext x?html?, has firefox, X, flag f = firefox -- "$@" ext x?html?, has seamonkey, X, flag f = seamonkey -- "$@" ext x?html?, has iceweasel, X, flag f = iceweasel -- "$@" +ext x?html?, has chromium-browser, X, flag f = chromium-browser -- "$@" +ext x?html?, has chromium, X, flag f = chromium -- "$@" +ext x?html?, has google-chrome, X, flag f = google-chrome -- "$@" ext x?html?, has epiphany, X, flag f = epiphany -- "$@" ext x?html?, has konqueror, X, flag f = konqueror -- "$@" ext x?html?, has elinks, terminal = elinks "$@" @@ -259,10 +259,26 @@ label wallpaper, number 12, mime ^image, has feh, X = feh --bg-tile "$1" label wallpaper, number 13, mime ^image, has feh, X = feh --bg-center "$1" label wallpaper, number 14, mime ^image, has feh, X = feh --bg-fill "$1" +#------------------------------------------- +# Generic file openers +#------------------------------------------- +label open, has xdg-open = xdg-open -- "$@" +label open, has open = open -- "$@" + # Define the editor for non-text files + pager as last action !mime ^text, !ext xml|json|csv|tex|py|pl|rb|js|sh|php = ask label editor, !mime ^text, !ext xml|json|csv|tex|py|pl|rb|js|sh|php = ${VISUAL:-$EDITOR} -- "$@" label pager, !mime ^text, !ext xml|json|csv|tex|py|pl|rb|js|sh|php = "$PAGER" -- "$@" -# The very last action, so that it's never triggered accidentally, is to execute a program: + +###################################################################### +# The actions below are left so low down in this file on purpose, so # +# they are never triggered accidentally. # +###################################################################### + +# Execute a file as program/script. mime application/x-executable = "$1" + +# Move the file to trash using trash-cli. +label trash, has trash-put = trash-put -- "$@" +label trash = mkdir -p -- ${XDG_DATA_DIR:-$HOME/.ranger}/ranger-trash; mv -- "$@" ${XDG_DATA_DIR:-$HOME/.ranger}/ranger-trash diff --git a/ranger/container/fsobject.py b/ranger/container/fsobject.py index 4fb47354..7de889bf 100644 --- a/ranger/container/fsobject.py +++ b/ranger/container/fsobject.py @@ -342,10 +342,10 @@ class FileSystemObject( # pylint: disable=too-many-instance-attributes,too-many if self.permissions is not None: return self.permissions - if self.is_directory: - perms = ['d'] - elif self.is_link: + if self.is_link: perms = ['l'] + elif self.is_directory: + perms = ['d'] else: perms = ['-'] diff --git a/ranger/container/settings.py b/ranger/container/settings.py index 3075aadf..5f0c528b 100644 --- a/ranger/container/settings.py +++ b/ranger/container/settings.py @@ -58,6 +58,7 @@ ALLOWED_SETTINGS = { 'max_history_size': (int, type(None)), 'metadata_deep_search': bool, 'mouse_enabled': bool, + 'nested_ranger_warning': str, 'one_indexed': bool, 'open_all_images': bool, 'padding_right': bool, @@ -94,6 +95,7 @@ ALLOWED_SETTINGS = { 'vcs_backend_git': str, 'vcs_backend_hg': str, 'vcs_backend_svn': str, + 'vcs_msg_length': int, 'viewmode': str, 'w3m_delay': float, 'w3m_offset': int, @@ -106,6 +108,7 @@ ALLOWED_VALUES = { 'confirm_on_delete': ['multiple', 'always', 'never'], 'draw_borders': ['none', 'both', 'outline', 'separators'], 'line_numbers': ['false', 'absolute', 'relative'], + 'nested_ranger_warning': ['true', 'false', 'error'], 'one_indexed': [False, True], 'preview_images_method': ['w3m', 'iterm2', 'terminology', 'urxvt', 'urxvt-full', 'kitty', @@ -277,7 +280,7 @@ class Settings(SignalDispatcher, FileManagerAware): if path: if path not in self._localsettings: try: - regex = re.compile(path) + regex = re.compile(re.escape(path)) except re.error: # Bad regular expression return self._localregexes[path] = regex diff --git a/ranger/core/actions.py b/ranger/core/actions.py index 435fcf13..18302431 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -1597,20 +1597,22 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m Paste the selected items into the current directory or to dest if provided. """ - if dest is None or isdir(dest): + if dest is None: + dest = self.thistab.path + if isdir(dest): loadable = CopyLoader(self.copy_buffer, self.do_cut, overwrite, dest) self.loader.add(loadable, append=append) self.do_cut = False else: - self.notify('Failed to paste. The given path is invalid.', bad=True) + self.notify('Failed to paste. The destination is invalid.', bad=True) def delete(self, files=None): # XXX: warn when deleting mount points/unseen marked files? - self.notify("Deleting!") # COMPAT: old command.py use fm.delete() without arguments if files is None: files = (fobj.path for fobj in self.thistab.get_selection()) + self.notify("Deleting {}!".format(", ".join(files))) files = [os.path.abspath(path) for path in files] for path in files: # Untag the deleted files. diff --git a/ranger/core/fm.py b/ranger/core/fm.py index 43001e8b..7d23c9b6 100644 --- a/ranger/core/fm.py +++ b/ranger/core/fm.py @@ -22,11 +22,7 @@ from ranger.container.tags import Tags, TagsDummy from ranger.gui.ui import UI from ranger.container.bookmarks import Bookmarks from ranger.core.runner import Runner -from ranger.ext.img_display import (W3MImageDisplayer, ITerm2ImageDisplayer, - TerminologyImageDisplayer, - URXVTImageDisplayer, URXVTImageFSDisplayer, - KittyImageDisplayer, UeberzugImageDisplayer, - ImageDisplayer) +from ranger.ext.img_display import get_image_displayer from ranger.core.metadata import MetadataManager from ranger.ext.rifle import Rifle from ranger.container.directory import Directory @@ -104,7 +100,7 @@ class FM(Actions, # pylint: disable=too-many-instance-attributes def set_image_displayer(): if self.image_displayer: self.image_displayer.quit() - self.image_displayer = self._get_image_displayer() + self.image_displayer = get_image_displayer(self.settings.preview_images_method) set_image_displayer() self.settings.signal_bind('setopt.preview_images_method', set_image_displayer, priority=settings.SIGNAL_PRIORITY_AFTER_SYNC) @@ -227,23 +223,6 @@ class FM(Actions, # pylint: disable=too-many-instance-attributes for line in entry.splitlines(): yield line - def _get_image_displayer(self): # pylint: disable=too-many-return-statements - if self.settings.preview_images_method == "w3m": - return W3MImageDisplayer() - elif self.settings.preview_images_method == "iterm2": - return ITerm2ImageDisplayer() - elif self.settings.preview_images_method == "terminology": - return TerminologyImageDisplayer() - elif self.settings.preview_images_method == "urxvt": - return URXVTImageDisplayer() - elif self.settings.preview_images_method == "urxvt-full": - return URXVTImageFSDisplayer() - elif self.settings.preview_images_method == "kitty": - return KittyImageDisplayer() - elif self.settings.preview_images_method == "ueberzug": - return UeberzugImageDisplayer() - return ImageDisplayer() - def _get_thisfile(self): return self.thistab.thisfile diff --git a/ranger/core/main.py b/ranger/core/main.py index 23648677..aefaacbc 100644 --- a/ranger/core/main.py +++ b/ranger/core/main.py @@ -180,6 +180,16 @@ def main( for command in args.cmd: fm.execute_console(command) + if int(os.environ[level]) > 1: + warning = 'Warning:' + nested_warning = "You're in a nested ranger instance!" + warn_when_nested = fm.settings.nested_ranger_warning.lower() + if warn_when_nested == 'true': + fm.notify(' '.join((warning, nested_warning)), bad=False) + elif warn_when_nested == 'error': + fm.notify(' '.join((warning.upper(), nested_warning + '!!')), + bad=True) + if ranger.args.profile: import cProfile import pstats diff --git a/ranger/core/runner.py b/ranger/core/runner.py index f38b026a..d465f070 100644 --- a/ranger/core/runner.py +++ b/ranger/core/runner.py @@ -214,7 +214,9 @@ class Runner(object): # pylint: disable=too-few-public-methods toggle_ui = True context.wait = True if 't' in context.flags: - if 'DISPLAY' not in os.environ: + if not ('WAYLAND_DISPLAY' in os.environ + or sys.platform == 'darwin' + or 'DISPLAY' in os.environ): return self._log("Can not run with 't' flag, no display found!") term = get_term() if isinstance(action, str): diff --git a/ranger/data/mime.types b/ranger/data/mime.types index 900cb7d9..abee11f6 100644 --- a/ranger/data/mime.types +++ b/ranger/data/mime.types @@ -12,11 +12,13 @@ audio/flac flac audio/musepack mpc mpp mp+ -audio/ogg oga ogg spx +audio/ogg oga ogg spx opus audio/wavpack wv wvc audio/webm weba audio/x-ape ape +image/webp webp + video/mkv mkv video/webm webm video/flash flv diff --git a/ranger/data/scope.sh b/ranger/data/scope.sh index 306eeed0..eb09b2bf 100755 --- a/ranger/data/scope.sh +++ b/ranger/data/scope.sh @@ -45,7 +45,6 @@ HIGHLIGHT_STYLE=${HIGHLIGHT_STYLE:-pablo} HIGHLIGHT_OPTIONS="--replace-tabs=${HIGHLIGHT_TABWIDTH} --style=${HIGHLIGHT_STYLE} ${HIGHLIGHT_OPTIONS:-}" PYGMENTIZE_STYLE=${PYGMENTIZE_STYLE:-autumn} - handle_extension() { case "${FILE_EXTENSION_LOWER}" in ## Archive diff --git a/ranger/ext/img_display.py b/ranger/ext/img_display.py index 2cce5c7a..7e911848 100644 --- a/ranger/ext/img_display.py +++ b/ranger/ext/img_display.py @@ -23,6 +23,7 @@ import warnings import json import threading from subprocess import Popen, PIPE +from collections import defaultdict import termios from contextlib import contextmanager @@ -72,6 +73,33 @@ class ImgDisplayUnsupportedException(Exception): pass +def fallback_image_displayer(): + """Simply makes some noise when chosen. Temporary fallback behavior.""" + + raise ImgDisplayUnsupportedException + + +IMAGE_DISPLAYER_REGISTRY = defaultdict(fallback_image_displayer) + + +def register_image_displayer(nickname=None): + """Register an ImageDisplayer by nickname if available.""" + + def decorator(image_displayer_class): + if nickname: + registry_key = nickname + else: + registry_key = image_displayer_class.__name__ + IMAGE_DISPLAYER_REGISTRY[registry_key] = image_displayer_class + return image_displayer_class + return decorator + + +def get_image_displayer(registry_key): + image_displayer_class = IMAGE_DISPLAYER_REGISTRY[registry_key] + return image_displayer_class() + + class ImageDisplayer(object): """Image display provider functions for drawing images in the terminal""" @@ -90,6 +118,7 @@ class ImageDisplayer(object): pass +@register_image_displayer("w3m") class W3MImageDisplayer(ImageDisplayer, FileManagerAware): """Implementation of ImageDisplayer using w3mimgdisplay, an utilitary program from w3m (a text-based web browser). w3mimgdisplay can display @@ -243,6 +272,7 @@ class W3MImageDisplayer(ImageDisplayer, FileManagerAware): # ranger-independent libraries. +@register_image_displayer("iterm2") class ITerm2ImageDisplayer(ImageDisplayer, FileManagerAware): """Implementation of ImageDisplayer using iTerm2 image display support (http://iterm2.com/images.html). @@ -351,6 +381,7 @@ class ITerm2ImageDisplayer(ImageDisplayer, FileManagerAware): return width, height +@register_image_displayer("terminology") class TerminologyImageDisplayer(ImageDisplayer, FileManagerAware): """Implementation of ImageDisplayer using terminology image display support (https://github.com/billiob/terminology). @@ -390,6 +421,7 @@ class TerminologyImageDisplayer(ImageDisplayer, FileManagerAware): self.clear(0, 0, 0, 0) +@register_image_displayer("urxvt") class URXVTImageDisplayer(ImageDisplayer, FileManagerAware): """Implementation of ImageDisplayer working by setting the urxvt background image "under" the preview pane. @@ -474,6 +506,7 @@ class URXVTImageDisplayer(ImageDisplayer, FileManagerAware): self.clear(0, 0, 0, 0) # dummy assignments +@register_image_displayer("urxvt-full") class URXVTImageFSDisplayer(URXVTImageDisplayer): """URXVTImageDisplayer that utilizes the whole terminal.""" @@ -486,6 +519,7 @@ class URXVTImageFSDisplayer(URXVTImageDisplayer): return self._get_centered_offsets() +@register_image_displayer("kitty") class KittyImageDisplayer(ImageDisplayer, FileManagerAware): """Implementation of ImageDisplayer for kitty (https://github.com/kovidgoyal/kitty/) terminal. It uses the built APC to send commands and data to kitty, @@ -681,6 +715,7 @@ class KittyImageDisplayer(ImageDisplayer, FileManagerAware): # continue +@register_image_displayer("ueberzug") class UeberzugImageDisplayer(ImageDisplayer): """Implementation of ImageDisplayer using ueberzug. Ueberzug can display images in a Xorg session. diff --git a/ranger/ext/rifle.py b/ranger/ext/rifle.py index a55e14c7..a73a188b 100755 --- a/ranger/ext/rifle.py +++ b/ranger/ext/rifle.py @@ -237,7 +237,9 @@ class Rifle(object): # pylint: disable=too-many-instance-attributes self._app_flags = argument return True elif function == 'X': - return sys.platform == 'darwin' or 'DISPLAY' in os.environ + return ('WAYLAND_DISPLAY' in os.environ + or sys.platform == 'darwin' + or 'DISPLAY' in os.environ) elif function == 'env': return bool(os.environ.get(argument)) elif function == 'else': @@ -293,6 +295,9 @@ class Rifle(object): # pylint: disable=too-many-instance-attributes self._app_flags = '' self._app_label = None if skip_ask and cmd == ASK_COMMAND: + # TODO(vifon): Fix properly, see + # https://github.com/ranger/ranger/pull/1341#issuecomment-537264495 + count += 1 continue for test in tests: if not self._eval_condition(test, files, None): diff --git a/ranger/gui/widgets/statusbar.py b/ranger/gui/widgets/statusbar.py index 71064ed4..fd44613e 100644 --- a/ranger/gui/widgets/statusbar.py +++ b/ranger/gui/widgets/statusbar.py @@ -212,7 +212,11 @@ class StatusBar(Widget): # pylint: disable=too-many-instance-attributes left.add_space() left.add(directory.vcs.rootvcs.head['date'].strftime(self.timeformat), 'vcsdate') left.add_space() - left.add(directory.vcs.rootvcs.head['summary'], 'vcscommit') + summary_length = self.settings.vcs_msg_length or 50 + left.add( + directory.vcs.rootvcs.head['summary'][:summary_length], + 'vcscommit' + ) def _get_owner(self, target): uid = target.stat.st_uid |