Simple, fast & configurable tool to open and preview files.
Ideal for use with terminal file managers (ranger, lf, nnn, etc.). Can also be used as a general alternative to xdg-open
and its various clones.
If you spend most time in a terminal, and are unsatisfied by current solutions to associate file types with handler programs, this tool may be for you.
- Start program to view/edit file according to extension or MIME type
- Provides 4 commands (all symlinks to a single
rsop
binary):rso
: open filerse
: edit file (similar torso
in most cases, except when open to view or edit have a different handler)rsp
: preview files in terminal, to be used for example in terminal file managers orfzf
preview panelrsi
: to identify MIME type
- Supports opening and previewing from data piped on stdin (very handy for advanced shell scripting, see below)
- Supports chainable filters to preprocess data (for example to transparently handle
.log.xz
files) - Simple config file (no regex or funky conditionals) to describe file formats, handlers, and associate both
xdg-open
compatibility mode
Compared to other xdg-open
alternatives:
rsop
is consistent and accurate, unlike say rangerrsop
does not rely on.desktop
files (see section Why no .desktop support)rsop
does opening and previewing with a single self contained tool and config filersop
is not tied to a file manager or a runtime environment, you only need thersop
binary and your config file and can use it in interactive terminal sessions, file managers,fzf
invocations...rsop
is taylored for terminal users (especially the preview feature)rsop
is very fast (see performance section)
You need a Rust build environment for example from rustup.
cargo build --release
install -Dm 755 -t /usr/local/bin target/release/rsop
ln -rsv /usr/local/bin/rs{op,p}
ln -rsv /usr/local/bin/rs{op,o}
ln -rsv /usr/local/bin/rs{op,e}
ln -rsv /usr/local/bin/rs{op,i}
# to replace system xdg-open:
ln -rsv /usr/local/bin/{rsop,xdg-open}
Arch Linux users can install the rsop-open AUR package.
When first started, rsop
will create a minimal configuration file usually in ~/.config/rsop/config.toml
.
See comments and example in that file to set up file types and handlers for your needs.
A more advanced example configuration file is also available here.
Warning: because ranger is built on Python's old ncurses version, the preview panel only supports 8bit colors (see ranger/ranger#690 (comment)), so if the output seems wrong you may need to tweak handlers to generate 8bit colors instead of 24.
In rifle.conf
:
= rso "$@"
In scope.sh
:
#!/bin/sh
COLUMNS="$2" LINES="$3" exec rsp "$1"
Dont forget to make it executable with chmod +x ~/.config/ranger/scope.sh
.
Add in lfrc
:
set filesep "\n"
set ifs "\n"
set previewer ~/.config/lf/preview
cmd open ${{
for f in ${fx[@]}; do rso "${f}"; done
lf -remote "send $id redraw"
}}
And create ~/.config/lf/preview
with:
#!/bin/sh
COLUMNS="$2" LINES="$3" exec rsp "$1"
- Simple file explorer with fuzzy searching, using fd and fzf, using
rso
to preview files andrsp
to open them:
fd . | fzf --preview='rsp {}' | xargs -r rso
- Preview files inside an archive, without decompressing it entirely, select one and open it (uses
bsdtar
,fzf
andrso
/rsp
):
# preview archive (.tar, .tar.gz, .zip, .7z, etc.)
# usage: pa <archive file path>
pa() {
local -r archive="${1:?}"
bsdtar -tf "${archive}" |
grep -v '/$' |
fzf --preview="bsdtar -xOf \"${archive}\" {} | rsp" |
xargs -r bsdtar -xOf "${archive}" |
rso
}
This is now integrated in the advanced config example, so you can just run rso <archive>
and get the same result.
rsop
is quite fast. In practice it rarely matters because choosing with which program to open or preview files is usually so quick it is not perceptible. However performance can matter if for example you are decompressing a huge tar.gz
archive to preview its content.
To help with that, rsop
uses the splice
system call if available on your platform. In the .tar.gz
example this allows decompressing data with gzip
or pigz
and passing it to tar (or whatever you have configured to handle application/x-tar
MIME type), without wasting time to copy data in user space between the two programs. This was previously done using a custom code path, but is now done transparently by the standard library.
Other stuff rsop
does to remain quick:
- it is written in Rust (setting aside the RiiR memes, this avoid the 20-50ms startup time of for example Python interpreters)
- it uses hashtables to search for handlers from MIME types or extensions in constant time
- it uses the great tree_magic_mini crate for fast MIME identification
Why no .desktop
support?
.desktop
do not provide a preview action separate from open.- One may need to pipe several programs to get to desired behavior,
.desktop
files does not help with this. - Many programs do not ship one, especially command line tools, so this would be incomplete anyway.
- On a philosophical level, with
.desktop
files, the program's author (or packager) decides which MIME types to support, and which arguments to pass to the program. This is a wrong paradidm, as this is fundamentally a user's decision.
"Really Simple Opener/Previewer" or "Reliable Simple Opener/Previewer" or "RuSt Opener/Previewer"
I haven't really decided yet...
Each action has customizable handlers, so they only do what you set them to do.
However the philosophy is the following :
- preview is non interactive, typically with only terminal UI, and a maximum number of lines in the output
- open can be interactive or not, and can open graphical windows or not
- edit is interactive, defaults to the open handler if no edit handler is set, and only makes sense if you need an action separate from open, for example to edit images with GIMP versus to view them with just an image viewer