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.
rsop
binary):
rso
: open filerse
: edit file (similar to rso
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 or fzf
preview panelrsi
: to identify MIME type.log.xz
files)xdg-open
compatibility modeCompared 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 the rsop
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 https://github.com/ranger/ranger/issues/690#issuecomment-255590479), 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"
rsop
can dorso
to preview files and rsp
to open them:fd . | fzf --preview='rsp {}' | xargs -r rso
bsdtar
, fzf
and rso
/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:
.desktop
support?.desktop
do not provide a preview action separate from open..desktop
files does not help with this..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.rsop
stands for?"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 :