专为 Ranger、Lf 设计的通用文件预览器,以消除 scope.sh 的重复性
ifdef::env-github[] = Pistol :toc: endif::[] ifndef::env-github[] // If processed locally, the README will be processed as a manpage = pistol(1) :doctype: manpage :manmanual: Pistol :mansource: Pistol :man-linkstyle: pass:[blue R ]
== Name
pistol - General purpose file previewer designed for Ranger, Lf to make scope.sh redundant. endif::[]
== Introduction
ifdef::env-github[]
Pistol is a file previewer for command line file managers such as https://ranger.github.io/[Ranger], https://github.com/gokcehan/lf[Lf] and https://github.com/jarun/nnn[nnn], intended to replace the file previewer shell script https://github.com/ranger/ranger/blob/v1.9.2/ranger/data/scope.sh[`scope.sh`] commonly used with Ranger and other previewing methods.
scope.sh is a Bash script that uses case switches and external
programs to decide how to preview every file it encounters. It knows how
to handle every file according to its
https://en.wikipedia.org/wiki/Media_type[MIME type] and/or file
extension using case switches and external programs. This design makes
it hard to configure / maintain and it makes it slow for startup and
heavy when running.
Pistol is a Go program (with (almost) 0 dependencies) and its MIME type
detection is internal. Moreover, it features native preview support for
almost any archive file and for text files along with syntax
highlighting while scope.sh relies on external programs to do these
basic tasks.
endif::[] ifndef::env-github[]
Pistol features native preview support for almost any archive file and text files along with syntax highlighting.
endif::[]
The following table lists Pistol’s native previewing support:
[cols=",",options="header",]
|===
|File/MIME Type |Notes on implementation
|text/* |Prints text files with syntax highlighting thanks to
https://github.com/alecthomas/chroma[`chroma`].
|Archives |Prints the contents of archive files using https://github.com/mholt/archives[`archives`]. |===
In case Pistol encounters a MIME type it doesn't know how to handle natively and you haven’t configured a program to handle it, it’ll print a general description of the file type it encountered. For example, the preview for an executable might be:
.... ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=a34861a1ae5358dc1079bc239df9dfe4830a8403, for GNU/Linux 3.2.0, not stripped ....
This feature is available out of the box just like the previews for the common mime types mentioned above.
ifdef::env-github[] See also the WiKi article: https://github.com/doronbehar/pistol/wiki/Pistol-out-in-the-wild[Pistol out in the Wild]. endif::[]
ifdef::env-github[]
=== A Note on MIME type Detection
Some pure Go libraries provide MIME type detection. Here are the top search results I got using a common web search engine:
Pistol uses the last one which leverages the well known C library http://linux.die.net/man/3/libmagic[libmagic(3)]. I made this choice after experimenting with the other candidates and due to their lack of an extensive database such as http://linux.die.net/man/3/libmagic[libmagic(3)] has, I chose https://github.com/rakyll/magicmime[magicmime].
Note that this choice also features compatibility with the standard
command file which is available by default on most GNU/Linux
distributions.footnote:[Considering Pistol’s indirect dependence on
http://linux.die.net/man/3/libmagic[libmagic(3)], I will never take the
trouble to personally try and make it work on Windows natively. If
you’ll succeed in the heroic task of compiling libmagic for Windows and
teach https://github.com/rakyll/magicmime[magicmime] to use it, please
let me know.]
=== A Note on Archive Previews
Pistol previews all archive / compression formats supported by the Go library https://github.com/mholt/archiver[`archiver`]. Some formats do nothing but compression, meaning they operate on 1 file alone and some files are a combination of archive, compressed in a certain algorithm.
For example, a .gz file is a single file compressed with gzip. A
.tar file is an uncompressed archive (collection) of files. A
.tar.gz is a .tar file compressed using gzip.
When pistol encounters a single file compressed using a known
compression algorithm, it doesn't know how to handle its content, it
displays the type of the archive. If a known compression algorithm has
compressed a .tar file, Pistol lists the files themselves.
https://en.wikipedia.org/wiki/Brotli[brotli] compressed archives,
(.tar.br) and Brotli compressed files (.br) are not detected by
libmagic so Pistol doesn't know how to handle them.footnote:[https://bugs.astron.com/view.php?id=111[`file` bug report];
https://github.com/google/brotli/issues/727[`brotli` bug report].]
== Install
If someone has packaged Pistol for your distribution, you might find a package for of it linked https://github.com/doronbehar/pistol/wiki/Distributions'-Packages[in the WiKi].
If not, use the following instructions, or grab a statically compiled version
of it from https://github.com/doronbehar/pistol/releases[the releases page],
available since version 0.3.1. The releases assets include also the manual
page pistol.1.gz.
WARNING: Currently, Darwin compatible binaries are not available there, but it
should be possible to generate them via CI. All other binaries were cross
compiled from my own x86_64 linux machine, using Nix' superb
https://nix.dev/tutorials/cross-compilation[cross compilation support].
NOTE: For a statically compiled Pistol to be functional, it needs to read a libmagic database
(usually found in /usr/share/misc/magic.mgc) and the static executable
includes the contents of this database found on https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/tools/misc/file/default.nix[Nixpkgs'
file]
package. The content of the magic.mgc database is copied to
~/.local/share/pistol/${libmagic-version}.mgc when you first run the executable.
Hence using this executable might not be desirable due to this behaviour which
a regular compilation of pistol does not include. This behaviour is compiled
into pistol if you use go {build,install} with -tags EMBED_MAGIC_DB.
=== From Source
Since Pistol depends on https://github.com/rakyll/magicmime[magicmime],
you’ll need a libmagic package installed. Please refer to
https://github.com/rakyll/magicmime/tree/v0.1.0#prerequisites[this section in
Magicmime's README] for the appropriate commands for every OS. In particular,
if you installed libmagic using brew on a Darwin system, you may need to
use the CGO_FLAGS environment variable to compile pistol. See
https://github.com/doronbehar/pistol/issues/6#issuecomment-1576673173[#6] for
more details.
Assuming you've installed libmagic properly and you have
https://golang.org/doc/install[setup a Go environment], Use the
following command to install Pistol to $GOPATH/bin/pistol:
==== Go 1.16 or later
==== Go 1.15 or earlier
footnote:[env GO111MODULE=on is needed due to a recent bug / issue
https://github.com/golang/go/issues/31529[with Go], see
https://github.com/doronbehar/pistol/issues/6[#6] for more details.
CGO_ENABLED=1 is needed for https://github.com/rakyll/magicmime[magicmime],
see https://github.com/doronbehar/pistol/issues/76[#76].]
Besides libmagic,
https://repology.org/project/asciidoctor/information[`asciidoctor`] is also
recommended, in order to compile the README as a manpage and install it. NixOS
For instance, does it like this:
nativeBuildInputs = [ installShellFiles asciidoctor ]; postInstall = '' asciidoctor -b manpage -d manpage README.adoc installManPage pistol.1 '';
https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/misc/pistol/default.nix[Link to currently evaluated file on NixOS]. Packagers for other distros should do something similar.
endif::[]
== Usage
.... $ pistol --help Usage: pistol OPTIONS [ ...]
OPTIONS
-V, --version Print version date and exit -c, --config configuration file to use (defaults to ~/.config/pistol/pistol.conf on Linux) -h, --help print help and exit
ARGUMENTS
file the file to preview extras extra arguments passed to the command ....
=== Integrations
==== Ranger / Lf
You can use Pistol as a file previewer in
https://ranger.github.io/[Ranger] and
https://github.com/gokcehan/lf[Lf]. For Ranger, set your
preview_script in your rc.conf as follows:
.... set preview_script ~/.go/bin/pistol ....
The same goes for Lf, but in lfrc:
.... set previewer ~/.go/bin/pistol ....
==== fzf
If you use https://github.com/junegunn/fzf[fzf] to search for files, you
can tell it to use pistol as the previewer. For example, the following
command edits with your $EDITOR selected python file(s) using pistol
as a previewer:
== Configuration
Although Pistol previews files of certain MIME types by default, it
doesn't force you to use these internal previewers for these MIME types.
You can change this behaviour by writing a configuration file in
~/.config/pistol/pistol.conf (or $XDG_CONFIG_HOME/pistol/pistol.conf) On
GNU systems, with the syntax as explained below.
NOTE: On OS X, this location defaults to:
~/Library/Application Support/pistol/pistol.conf, as the XDG specification
imposes.
=== Syntax
You can configure preview commands according to file path or mime type
regex. The 1st word may is always interpreted first as a mime type regex
such as: text/*.
If a line is not matched but the 1st word is exactly fpath, then the
2nd argument is interpreted as a file path regex, such as:
/var/src/.*/README.md.
On every line, whether you used fpath or not, the next arguments are
the command’s arguments, where %pistol-filename% is substituted by
pistol to the file at question. You’ll see more examples in the
following sections.
Both regular expressions (for file paths and for mime types) are
interpreted by the https://golang.org/pkg/regexp/#Match[built-in
library’s regexp.match]. Please refer to
https://golang.org/pkg/regexp/syntax[this link] for the full reference
regarding syntax.
==== Matching Mime Types
You can inspect the MIME type of any file on a GNU/Linux OS and on Mac
OS with the command file --mime-type .
For example, say you wish to replace Pistol’s internal text previewer
with that of https://github.com/sharkdp/bat[bat]’s, you’d put the
following in your pistol.conf:
.... text/* bat --paging=never --color=always %pistol-filename% ....
Naturally, your configuration file overrides the internal previewers.
Here’s another example which features http://w3m.sourceforge.net/[w3m] as an HTML previewer:
.... text/html w3m -T text/html -dump %pistol-filename% ....
And here’s an example that leverages ls for printing directories’
contents:
.... inode/directory ls -l --color %pistol-filename% ....
==== Matching File Path
For example, say you wish to preview all files that reside in a certain
./bin directory with https://github.com/sharkdp/bat[bat]’s syntax
highlighting for bash. You could use:
.... fpath /var/src/my-bash-project/bin/[^/]+$ bat --map-syntax :bash --paging=never --color=always %pistol-filename% ....
==== A Note on RegEx matching
When Pistol parses your configuration file, as soon as it finds a match
be it a file path match or a mime type match, it stops parsing it and it
invokes the command written on the rest of the line. Therefor, if you
wish to use the examples from above which use w3m a
暂无开放 Issues,或尚未同步最近议题。