summaryrefslogtreecommitdiff
path: root/.config/nnn/plugins
diff options
context:
space:
mode:
Diffstat (limited to '.config/nnn/plugins')
-rwxr-xr-x.config/nnn/plugins/.cbcp51
-rwxr-xr-x.config/nnn/plugins/.iconlookup428
-rwxr-xr-x.config/nnn/plugins/.nmv180
-rw-r--r--.config/nnn/plugins/.nnn-plugin-helper38
-rwxr-xr-x.config/nnn/plugins/.ntfy22
-rwxr-xr-x.config/nnn/plugins/preview-tui481
6 files changed, 1200 insertions, 0 deletions
diff --git a/.config/nnn/plugins/.cbcp b/.config/nnn/plugins/.cbcp
new file mode 100755
index 0000000..70f9b75
--- /dev/null
+++ b/.config/nnn/plugins/.cbcp
@@ -0,0 +1,51 @@
+#!/usr/bin/env sh
+
+# Description: Copy selection to system clipboard as newline-separated entries
+# Dependencies:
+# - tr
+# - xclip/xsel (Linux)
+# - pbcopy (macOS)
+# - termux-clipboard-set (Termux)
+# - clip.exe (WSL)
+# - clip (Cygwin)
+# - wl-copy (Wayland)
+# - clipboard (Haiku)
+#
+# Limitation: breaks if a filename has newline in it
+#
+# Note: For a space-separated list:
+# xargs -0 < "$SELECTION"
+#
+# Shell: POSIX compliant
+# Author: Arun Prakash Jana
+
+IFS="$(printf '%b_' '\n')"; IFS="${IFS%_}" # protect trailing \n
+
+selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
+[ -s "$selection" ] || { echo "plugin .cbcp error: empty selection" >&2 ; exit 1; }
+
+if type xsel >/dev/null 2>&1; then
+ # Linux
+ tr '\0' '\n' < "$selection" | xsel -bi
+elif type xclip >/dev/null 2>&1; then
+ # Linux
+ tr '\0' '\n' < "$selection" | xclip -sel clip
+elif type pbcopy >/dev/null 2>&1; then
+ # macOS
+ tr '\0' '\n' < "$selection" | pbcopy
+elif type termux-clipboard-set >/dev/null 2>&1; then
+ # Termux
+ tr '\0' '\n' < "$selection" | termux-clipboard-set
+elif type clip.exe >/dev/null 2>&1; then
+ # WSL
+ tr '\0' '\n' < "$selection" | clip.exe
+elif type clip >/dev/null 2>&1; then
+ # Cygwin
+ tr '\0' '\n' < "$selection" | clip
+elif type wl-copy >/dev/null 2>&1; then
+ # Wayland
+ tr '\0' '\n' < "$selection" | wl-copy
+elif type clipboard >/dev/null 2>&1; then
+ # Haiku
+ tr '\0' '\n' < "$selection" | clipboard --stdin
+fi
diff --git a/.config/nnn/plugins/.iconlookup b/.config/nnn/plugins/.iconlookup
new file mode 100755
index 0000000..d48d676
--- /dev/null
+++ b/.config/nnn/plugins/.iconlookup
@@ -0,0 +1,428 @@
+#!/usr/bin/env sh
+
+# Description: Print icons in front of list of directories/files
+
+# Dependencies: awk
+
+# Usage
+# 1. Set colors and/or icons to your liking
+# 2. Pipe any directory listing to iconlookup and it will output prepended icons
+# 3. preview-tui uses the script to prepend icon to directory listings
+# 4. Aditionally you can consider adding it to your PATH and/or FZF_DEFAULT_COMMAND to
+# make it work with various fzf plugins (make sure you also add --ansi to your FZF_DEFAULT_OPTS)
+
+# Shell: POSIX compliant
+
+# Author: Luuk van Baal (https://github.com/luukvbaal/iconlookup)
+
+icon_lookup() {
+awk 'BEGIN {
+# Set your ANSI colorscheme below (https://en.wikipedia.org/wiki/ANSI_escape_code#Colors).
+# Default uses standard nnn icon colors, 8 and 24-bit nord themes are commented out.
+ colordepth=8 #colordepth=8 #colordepth=24
+ color_dirtxt=39 #color_dirtxt=111 #color_dirtxt="129;161;193"
+ color_filetxt=15 #color_filetxt=111 #color_filetxt="129;161;193"
+ color_default=39 #color_default=111 #color_default="129;161;193"
+ color_video=93 #color_video=110 #color_video="136;192;208"
+ color_audio=220 #color_audio=150 #color_audio="163;190;140"
+ color_image=82 #color_image=150 #color_image="163;190;140"
+ color_docs=202 #color_docs=173 #color_docs="208;135;112"
+ color_archive=209 #color_archive=179 #color_archive="235;203;139"
+ color_c=81 #color_c=150 #color_c="163;190;140"
+ color_java=32 #color_java=139 #color_java="180;142;173"
+ color_js=47 #color_js=109 #color_js="143;188;187"
+ color_react=39 #color_react=111 #color_react="129;161;193"
+ color_css=199 #color_css=110 #color_css="136;192;208"
+ color_python=227 #color_python=68 #color_python="94;129;172"
+ color_lua=19 #color_lua=167 #color_lua="191;97;106"
+ color_document=15 #color_document=173 #color_document="208;135;112"
+ color_fsharp=31 #color_fsharp=179 #color_fsharp="180;142;173"
+ color_ruby=160 #color_ruby=150 #color_ruby="163;190;140"
+ color_scala=196 #color_scala=139 #color_scala="143;188;187"
+ color_shell=47 #color_shell=109 #color_shell="143;188;187"
+ color_vim=28 #color_vim=109 #color_vim="143;188;187"
+
+# icons[][1] contains icon and icons[][2] contains color
+ icons["directory"][1] = ""; icons["directory"][2] = color_default
+ icons["file"][1] = ""; icons["file"][2] = color_default
+ icons["exec"][1] = ""; icons["exec"][2] = color_default
+ icons["manual"][1] = ""; icons["manual"][2] = color_docs
+ icons["pipe"][1] = "ﳣ"; icons["pipe"][2] = color_default
+ icons["socket"][1] = "ﳧ"; icons["socket"][2] = color_default
+ icons["door"][1] = "➡"; icons["door"][2] = color_default
+
+# top level and common icons
+ icons[".git"][1] = ""; icons[".git"][2] = color_default
+ icons["desktop"][1] = "ﲾ"; icons["desktop"][2] = color_default
+ icons["briefcase"][1] = ""; icons["briefcase"][2] = color_default
+ icons["document"][1] = ""; icons["document"][2] = color_default
+ icons["downloads"][1] = ""; icons["downloads"][2] = color_default
+ icons["music"][1] = ""; icons["music"][2] = color_default
+ icons["musicfile"][1] = ""; icons["musicfile"][2] = color_audio
+ icons["pictures"][1] = ""; icons["pictures"][2] = color_default
+ icons["picturefile"][1] = ""; icons["picturefile"][2] = color_image
+ icons["public"][1] = ""; icons["public"][2] = color_default
+ icons["templates"][1] = "陼"; icons["templates"][2] = color_default
+ icons["videos"][1] = ""; icons["videos"][2] = color_default
+ icons["videofile"][1] = "ﳜ"; icons["videofile"][2] = color_video
+ icons["changelog"][1] = ""; icons["changelog"][2] = color_docs
+ icons["configure"][1] = ""; icons["configure"][2] = color_default
+ icons["license"][1] = ""; icons["license"][2] = color_docs
+ icons["makefile"][1] = ""; icons["makefile"][2] = color_default
+ icons["archive"][1] = ""; icons["archive"][2] = color_archive
+ icons["script"][1] = ""; icons["script"][2] = color_shell
+ icons["cplusplus"][1] = ""; icons["cplusplus"][2] = color_c
+ icons["java"][1] = ""; icons["java"][2] = color_java
+ icons["clojure"][1] = ""; icons["clojure"][2] = color_default
+ icons["js"][1] = ""; icons["js"][2] = color_js
+ icons["linux"][1] = ""; icons["linux"][2] = color_default
+ icons["fsharp"][1] = ""; icons["fsharp"][2] = color_fsharp
+ icons["ruby"][1] = ""; icons["ruby"][2] = color_ruby
+ icons["c"][1] = ""; icons["c"][2] = color_c
+ icons["chess"][1] = ""; icons["chess"][2] = color_default
+ icons["haskell"][1] = ""; icons["haskell"][2] = color_vim
+ icons["html"][1] = ""; icons["html"][2] = color_default
+ icons["react"][1] = ""; icons["react"][2] = color_react
+ icons["python"][1] = ""; icons["python"][2] = color_python
+ icons["database"][1] = ""; icons["database"][2] = color_default
+ icons["worddoc"][1] = ""; icons["worddoc"][2] = color_document
+ icons["playlist"][1] = "蘿"; icons["playlist"][2] = color_audio
+ icons["opticaldisk"][1] = ""; icons["opticaldisk"][2] = color_archive
+
+# numbers
+ icons["1"][1] = icons["manual"][1]; icons["1"][2] = icons["manual"][2]
+ icons["7z"][1] = icons["archive"][1]; icons["7z"][2] = icons["archive"][2]
+
+# a
+ icons["a"][1] = icons["manual"][1]; icons["a"][2] = icons["manual"][2]
+ icons["apk"][1] = icons["archive"][1]; icons["apk"][2] = icons["archive"][2]
+ icons["asm"][1] = icons["file"][1]; icons["asm"][2] = icons["file"][2]
+ icons["aup"][1] = icons["musicfile"][1]; icons["aup"][2] = icons["musicfile"][2]
+ icons["avi"][1] = icons["videofile"][1]; icons["avi"][2] = icons["videofile"][2]
+
+# b
+ icons["bat"][1] = icons["script"][1]; icons["bat"][2] = icons["script"][2]
+ icons["bin"][1] = ""; icons["bin"][2] = color_default
+ icons["bmp"][1] = icons["picturefile"][1]; icons["bmp"][2] = icons["picturefile"][2]
+ icons["bz2"][1] = icons["archive"][1]; icons["bz2"][2] = icons["archive"][2]
+
+# c
+ icons["cplusplus"][1] = icons["cplusplus"][1]; icons["cplusplus"][2] = icons["cplusplus"][2]
+ icons["cabal"][1] = icons["haskell"][1]; icons["cab"][2] = icons["haskell"][2]
+ icons["cab"][1] = icons["archive"][1]; icons["cab"][2] = icons["archive"][2]
+ icons["cbr"][1] = icons["archive"][1]; icons["cbr"][2] = icons["archive"][2]
+ icons["cbz"][1] = icons["archive"][1]; icons["cbz"][2] = icons["archive"][2]
+ icons["cc"][1] = icons["cplusplus"][1]; icons["cc"][2] = icons["cplusplus"][2]
+ icons["class"][1] = icons["java"][1]; icons["class"][2] = icons["java"][2]
+ icons["clj"][1] = icons["clojure"][1]; icons["clj"][2] = icons["clojure"][2]
+ icons["cljc"][1] = icons["clojure"][1]; icons["cljc"][2] = icons["clojure"][2]
+ icons["cljs"][1] = icons["clojure"][1]; icons["cljs"][2] = icons["clojure"][2]
+ icons["cmake"][1] = icons["makefile"][1]; icons["cmake"][2] = icons["makefile"][2]
+ icons["coffee"][1] = ""; icons["coffee"][2] = color_default
+ icons["conf"][1] = icons["configure"][1]; icons["conf"][2] = icons["configure"][2]
+ icons["cpio"][1] = icons["archive"][1]; icons["cpio"][2] = icons["archive"][2]
+ icons["cpp"][1] = icons["cplusplus"][1]; icons["cpp"][2] = icons["cplusplus"][2]
+ icons["css"][1] = ""; icons["css"][2] = color_css
+ icons["cue"][1] = icons["playlist"][1]; icons["cue"][2] = icons["playlist"][2]
+ icons["cvs"][1] = icons["configure"][1]; icons["cvs"][2] = icons["configure"][2]
+ icons["cxx"][1] = icons["cplusplus"][1]; icons["cxx"][2] = icons["cplusplus"][2]
+
+# d
+ icons["db"][1] = icons["database"][1]; icons["db"][2] = icons["database"][2]
+ icons["deb"][1] = ""; icons["deb"][2] = color_archive
+ icons["diff"][1] = ""; icons["diff"][2] = color_default
+ icons["dll"][1] = icons["script"][1]; icons["dll"][2] = icons["script"][2]
+ icons["doc"][1] = icons["worddoc"][1]; icons["doc"][2] = icons["worddoc"][2]
+ icons["docx"][1] = icons["worddoc"][1]; icons["docx"][2] = icons["worddoc"][2]
+
+# e
+ icons["ejs"][1] = icons["js"][1]; icons["ejs"][2] = icons["js"][2]
+ icons["elf"][1] = icons["linux"][1]; icons["elf"][2] = icons["linux"][2]
+ icons["epub"][1] = icons["manual"][1]; icons["epub"][2] = icons["manual"][2]
+ icons["exe"][1] = icons["exec"][1]; icons["exe"][2] = icons["exec"][2]
+
+# f
+ icons["fsharp"][1] = icons["fsharp"][1]; icons["fsharp"][2] = icons["fsharp"][2]
+ icons["flac"][1] = icons["musicfile"][1]; icons["flac"][2] = icons["musicfile"][2]
+ icons["fen"][1] = icons["chess"][1]; icons["fen"][2] = icons["chess"][2]
+ icons["flv"][1] = icons["videofile"][1]; icons["flv"][2] = icons["videofile"][2]
+ icons["fs"][1] = icons["fsharp"][1]; icons["fs"][2] = icons["fsharp"][2]
+ icons["fsi"][1] = icons["fsharp"][1]; icons["fsi"][2] = icons["fsharp"][2]
+ icons["fsscript"][1] = icons["fsharp"][1]; icons["fsscript"][2] = icons["fsharp"][2]
+ icons["fsx"][1] = icons["fsharp"][1]; icons["fsx"][2] = icons["fsharp"][2]
+
+# g
+ icons["gem"][1] = icons["ruby"][1]; icons["gem"][2] = icons["ruby"][2]
+ icons["gif"][1] = icons["picturefile"][1]; icons["gif"][2] = icons["picturefile"][2]
+ icons["go"][1] = "ﳑ"; icons["go"][2] = color_default
+ icons["gz"][1] = icons["archive"][1]; icons["gz"][2] = icons["archive"][2]
+ icons["gzip"][1] = icons["archive"][1]; icons["gzip"][2] = icons["archive"][2]
+
+# h
+ icons["h"][1] = icons["c"][1]; icons["h"][2] = icons["c"][2]
+ icons["hh"][1] = icons["cplusplus"][1]; icons["hh"][2] = icons["cplusplus"][2]
+ icons["hpp"][1] = icons["cplusplus"][1]; icons["hpp"][2] = icons["cplusplus"][2]
+ icons["hs"][1] = icons["haskell"][1]; icons["hs"][2] = icons["haskell"][2]
+ icons["htaccess"][1] = icons["configure"][1]; icons["htaccess"][2] = icons["configure"][2]
+ icons["htpasswd"][1] = icons["configure"][1]; icons["htpasswd"][2] = icons["configure"][2]
+ icons["htm"][1] = icons["html"][1]; icons["htm"][2] = icons["html"][2]
+ icons["hxx"][1] = icons["cplusplus"][1]; icons["hxx"][2] = icons["cplusplus"][2]
+
+# i
+ icons["ico"][1] = icons["picturefile"][1]; icons["ico"][2] = icons["picturefile"][2]
+ icons["img"][1] = icons["opticaldisk"][1]; icons["img"][2] = icons["opticaldisk"][2]
+ icons["ini"][1] = icons["configure"][1]; icons["ini"][2] = icons["configure"][2]
+ icons["iso"][1] = icons["opticaldisk"][1]; icons["iso"][2] = icons["opticaldisk"][2]
+
+# j
+ icons["jar"][1] = icons["java"][1]; icons["jar"][2] = icons["java"][2]
+ icons["java"][1] = icons["java"][1]; icons["java"][2] = icons["java"][2]
+ icons["jl"][1] = icons["configure"][1]; icons["jl"][2] = icons["configure"][2]
+ icons["jpeg"][1] = icons["picturefile"][1]; icons["jpeg"][2] = icons["picturefile"][2]
+ icons["jpg"][1] = icons["picturefile"][1]; icons["jpg"][2] = icons["picturefile"][2]
+ icons["json"][1] = "ﬥ"; icons["json"][2] = color_js
+ icons["jsx"][1] = icons["react"][1]; icons["jsx"][2] = icons["react"][2]
+
+# k
+
+# l
+ icons["lha"][1] = icons["archive"][1]; icons["lha"][2] = icons["archive"][2]
+ icons["lhs"][1] = icons["haskell"][1]; icons["lhs"][2] = icons["haskell"][2]
+ icons["ilog"][1] = icons["document"][1]; icons["ilog"][2] = icons["document"][2]
+ icons["lua"][1] = ""; icons["lua"][2] = color_lua
+ icons["lzh"][1] = icons["archive"][1]; icons["lzh"][2] = icons["archive"][2]
+ icons["lzma"][1] = icons["archive"][1]; icons["lzma"][2] = icons["archive"][2]
+
+# m
+ icons["m"][1] = "ﴜ"; icons["mat"][2] = color_c
+ icons["m4a"][1] = icons["musicfile"][1]; icons["m4a"][2] = icons["musicfile"][2]
+ icons["m4v"][1] = icons["videofile"][1]; icons["m4v"][2] = icons["videofile"][2]
+ icons["mat"][1] = ""; icons["mat"][2] = color_c
+ icons["markdown"][1] = ""; icons["markdown"][2] = color_docs
+ icons["md"][1] = ""; icons["md"][2] = color_docs
+ icons["mk"][1] = icons["makefile"][1]; icons["mk"][2] = icons["makefile"][2]
+ icons["mkv"][1] = icons["videofile"][1]; icons["mkv"][2] = icons["videofile"][2]
+ icons["mov"][1] = icons["videofile"][1]; icons["mov"][2] = icons["videofile"][2]
+ icons["mp3"][1] = icons["musicfile"][1]; icons["mp3"][2] = icons["musicfile"][2]
+ icons["mp4"][1] = icons["videofile"][1]; icons["mp4"][2] = icons["videofile"][2]
+ icons["mpeg"][1] = icons["videofile"][1]; icons["mpeg"][2] = icons["videofile"][2]
+ icons["mpg"][1] = icons["videofile"][1]; icons["mpg"][2] = icons["videofile"][2]
+ icons["msi"][1] = ""; icons["msi"][2] = color_default
+
+# n
+ icons["nix"][1] = ""; icons["nix"][2] = color_fsharp
+
+# o
+ icons["o"][1] = icons["manual"][1]; icons["o"][2] = icons["manual"][2]
+ icons["ogg"][1] = icons["musicfile"][1]; icons["ogg"][2] = icons["musicfile"][2]
+ icons["odownload"][1] = icons["download"][1]; icons["odownload"][2] = icons["download"][2]
+ icons["out"][1] = icons["linux"][1]; icons["out"][2] = icons["linux"][2]
+
+# p
+ icons["part"][1] = icons["download"][1]; icons["part"][2] = icons["download"][2]
+ icons["patch"][1] = icons["diff"][1]; icons["patch"][2] = icons["diff"][2]
+ icons["pdf"][1] = ""; icons["pdf"][2] = color_docs
+ icons["pgn"][1] = icons["chess"][1]; icons["pgn"][2] = icons["chess"][2]
+ icons["php"][1] = ""; icons["php"][2] = color_default
+ icons["png"][1] = icons["picturefile"][1]; icons["png"][2] = icons["picturefile"][2]
+ icons["ppt"][1] = ""; icons["ppt"][2] = color_default
+ icons["pptx"][1] = ""; icons["pptx"][2] = color_default
+ icons["psb"][1] = ""; icons["psb"][2] = color_default
+ icons["psd"][1] = ""; icons["psd"][2] = color_default
+ icons["py"][1] = icons["python"][1]; icons["py"][2] = icons["python"][2]
+ icons["pyc"][1] = icons["python"][1]; icons["pyc"][2] = icons["python"][2]
+ icons["pyd"][1] = icons["python"][1]; icons["pyd"][2] = icons["python"][2]
+ icons["pyo"][1] = icons["python"][1]; icons["pyo"][2] = icons["python"][2]
+
+# q
+
+# r
+ icons["rar"][1] = icons["archive"][1]; icons["rar"][2] = icons["archive"][2]
+ icons["rc"][1] = icons["configure"][1]; icons["rc"][2] = icons["configure"][2]
+ icons["rom"][1] = ""; icons["rom"][2] = color_default
+ icons["rpm"][1] = icons["archive"][1]; icons["rpm"][2] = icons["archive"][2]
+ icons["rss"][1] = "參"; icons["rss"][2] = color_default
+ icons["rtf"][1] = ""; icons["rtf"][2] = color_default
+
+# s
+ icons["sass"][1] = ""; icons["sass"][2] = color_css
+ icons["scss"][1] = ""; icons["scss"][2] = color_css
+ icons["so"][1] = icons["manual"][1]; icons["so"][2] = icons["manual"][2]
+ icons["scala"][1] = ""; icons["scala"][2] = color_scala
+ icons["sh"][1] = icons["script"][1]; icons["sh"][2] = icons["script"][2]
+ icons["slim"][1] = icons["script"][1]; icons["slim"][2] = icons["script"][2]
+ icons["sln"][1] = ""; icons["sln"][2] = color_default
+ icons["sql"][1] = icons["database"][1]; icons["sql"][2] = icons["database"][2]
+ icons["srt"][1] = ""; icons["srt"][2] = color_default
+ icons["isub"][1] = ""; icons["isub"][2] = color_default
+ icons["svg"][1] = icons["picturefile"][1]; icons["svg"][2] = icons["picturefile"][2]
+
+# t
+ icons["tar"][1] = icons["archive"][1]; icons["tar"][2] = icons["archive"][2]
+ icons["tex"][1] = ""; icons["tex"][2] = color_default
+ icons["tgz"][1] = icons["archive"][1]; icons["tgz"][2] = icons["archive"][2]
+ icons["ts"][1] = ""; icons["ts"][2] = color_js
+ icons["tsx"][1] = icons["react"][1]; icons["tsx"][2] = icons["react"][2]
+ icons["txt"][1] = icons["document"][1]; icons["txt"][2] = icons["document"][2]
+ icons["txz"][1] = icons["archive"][1]; icons["txz"][2] = icons["archive"][2]
+
+# u
+
+# v
+ icons["vid"][1] = icons["videofile"][1]; icons["vid"][2] = icons["videofile"][2]
+ icons["vim"][1] = ""; icons["vim"][2] = color_vim
+ icons["vimrc"][1] = ""; icons["vimrc"][2] = color_vim
+ icons["vtt"][1] = ""; icons["vtt"][2] = color_default
+# w
+ icons["wav"][1] = icons["musicfile"][1]; icons["wav"][2] = icons["musicfile"][2]
+ icons["webm"][1] = icons["videofile"][1]; icons["webm"][2] = icons["videofile"][2]
+ icons["wma"][1] = icons["videofile"][1]; icons["wma"][2] = icons["videofile"][2]
+ icons["wmv"][1] = icons["videofile"][1]; icons["wmv"][2] = icons["videofile"][2]
+
+# x
+ icons["xbps"][1] = icons["archive"][1]; icons["xbps"][2] = color_archive
+ icons["xcf"][1] = icons["picturefile"][1]; icons["xcf"][2] = color_image
+ icons["xhtml"][1] = icons["html"][1]; icons["xhtml"][2] = icons["html"][2]
+ icons["xls"][1] = ""; icons["xls"][2] = color_default
+ icons["xlsx"][1] = ""; icons["xlsx"][2] = color_default
+ icons["xml"][1] = icons["html"][1]; icons["xml"][2] = icons["html"][2]
+ icons["xz"][1] = icons["archive"][1]; icons["xz"][2] = icons["archive"][2]
+
+# y
+ icons["yaml"][1] = icons["configure"][1]; icons["yaml"][2] = icons["configure"][2]
+ icons["yml"][1] = icons["configure"][1]; icons["yml"][2] = icons["configure"][2]
+# z
+ icons["zip"][1] = icons["archive"][1]; icons["zip"][2] = icons["archive"][2]
+ icons["zsh"][1] = icons["script"][1]; icons["zsh"][2] = icons["script"][2]
+ icons["zst"][1] = icons["archive"][1]; icons["zst"][2] = icons["archive"][2]
+
+ FS = "."
+ limit = ENVIRON["limit"]
+ switch (colordepth) {
+ case "4":
+ escape="\033["
+ break;
+ case "8":
+ escape="\033[38;5;"
+ break;
+ case "24":
+ escape="\033[38;2;"
+ break;
+ }
+ bstr = ENVIRON["beforestr"]
+}
+{
+ # dont print cwd . and leading ./ from tree -f
+ if ($0 ~/^\.$/)
+ next
+ ent = ($0 ~/^\.\//) ? substr($0, 3, length($0) - 2) : $0
+ ext = $NF
+
+ # Print icons, set color and bold directories by using ansi escape codes
+ if (ext in icons)
+ printcolor(icons[ext][1], icons[ext][2], color_filetxt, ent, "10")
+ else
+ switch (substr(ent, length(ent), 1)) {
+ case "/":
+ printcolor(icons["directory"][1], color_default, color_dirtxt, ent, "1")
+ break;
+ case "*":
+ printcolor(icons["exe"][1], color_default, color_filetxt, ent, "10")
+ break;
+ case "|":
+ printcolor(icons["pipe"][1], color_default, color_filetxt, ent, "10")
+ break;
+ case "=":
+ printcolor(icons["socket"][1], color_default, color_filetxt, ent, "10")
+ break;
+ case ">":
+ printcolor(icons["door"][1], color_default, color_filetxt, ent, "10")
+ break;
+ default:
+ printcolor(icons["file"][1], color_default, color_filetxt, ent, "10")
+ }
+}
+function printcolor(i, c, d, n, b) {
+ if (limit != "" && length(n) + 2 > limit)
+ n = substr(n, 1, limit - 2)
+ printf "\033[0m"
+ printf "%s%s%s;%sm%s %s%sm%s\n", bstr, escape, c, b, i, escape, d, n
+}'
+printf '\033[0m'
+}
+
+print_begin() {
+ printf '%s\n' "$1" | sed 's/\\n/\n/g'
+}
+
+print_end() {
+ printf '%s\n' "$1" | sed 's/\\n/\n/g'
+}
+
+print_help() {
+ printf 'Icon Lookup\n
+Usage:
+ iconlookup [options]
+ iconlookup [-bBe] [string]
+ iconlookup -l [number]
+ iconlookup (-h | --help)
+
+ Prepend icons to list of files based on extension or appended indicator by ls/tree "-F" flag ("/" for directory, "*" for executable etc.)
+
+Options:
+ -h --help -? Show this screen.
+ -b --before Prepend str before icon.
+ -B --begin Prepend str before output.
+ -e --end Append str after output.
+ -l --limit Limit line length to [number] characters.'
+}
+
+while :; do
+ case $1 in
+ -h|-\?|--help)
+ print_help
+ exit ;;
+ -B|--begin)
+ if [ -n "$2" ]; then
+ print_begin "$2"
+ fi
+ shift ;;
+ -e|--end)
+ if [ -n "$2" ]; then
+ end=1
+ endstr="$2"
+ fi
+ shift ;;
+ -b|--before)
+ if [ -n "$2" ]; then
+ export beforestr="$2"
+ fi
+ shift ;;
+ -l|--limit)
+ if [ -n "$2" ]; then
+ export limit="$2"
+ shift
+ else
+ printf 'ERROR: "--limit" requires a non-empty option argument.\n'
+ exit
+ fi ;;
+ --)
+ shift
+ break ;;
+ -?*)
+ printf 'WARNING: Unknown option ignored: %s\n' "$1" ;;
+ *) break ;;
+ esac
+ shift
+done
+
+if [ ! -t 0 ]; then
+ [ -n "$beforestr" ] && limit="$((limit - ${#beforestr}))"
+ icon_lookup
+else
+ printf 'ERROR: no data provided...\nExpecting a directory listing in stdin\n'
+fi
+
+if [ -n "$end" ]; then
+ print_end "$endstr"
+fi
diff --git a/.config/nnn/plugins/.nmv b/.config/nnn/plugins/.nmv
new file mode 100755
index 0000000..37e887d
--- /dev/null
+++ b/.config/nnn/plugins/.nmv
@@ -0,0 +1,180 @@
+#!/usr/bin/env bash
+
+# Description: An almost fully POSIX compliant batch file renamer
+#
+# Note: nnn auto-detects and invokes this plugin if available
+# Whitespace is used as delimiter for read.
+# The plugin doesn't support filenames with leading or trailing whitespace
+# To use NNN_LIST your shell must support readlink(1)
+#
+# Capabilities:
+# 1. Basic file rename
+# 2. Detects order change
+# 3. Can move files
+# 4. Can remove files
+# 5. Switch number pairs to swap filenames
+#
+# Shell: bash
+# Author: KlzXS
+
+EDITOR="${EDITOR:-vi}"
+TMPDIR="${TMPDIR:-/tmp}"
+NNN_INCLUDE_HIDDEN="${NNN_INCLUDE_HIDDEN:-0}"
+VERBOSE="${VERBOSE:-0}"
+RECURSIVE="${RECURSIVE:-0}"
+
+case "$NNN_TRASH" in
+ 1)
+ RM_UTIL="trash-put" ;;
+ 2)
+ RM_UTIL="gio trash" ;;
+ *)
+ RM_UTIL="rm -ri" ;;
+esac
+
+selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
+exit_status=0
+
+dst_file=$(mktemp "$TMPDIR/.nnnXXXXXX")
+
+if [ -s "$selection" ]; then
+ printf "Rename 'c'urrent / 's'election? "
+ read -r resp
+
+ if ! [ "$resp" = "c" ] && ! [ "$resp" = "s" ]; then
+ exit 1
+ fi
+fi
+
+if [ "$resp" = "s" ]; then
+ arr=$(tr '\0' '\n' < "$selection")
+else
+ findcmd="find . ! -name ."
+
+ if [ "$RECURSIVE" -eq 0 ]; then
+ findcmd="$findcmd -prune"
+ fi
+
+ if [ "$NNN_INCLUDE_HIDDEN" -eq 0 ]; then
+ findcmd="$findcmd ! -name \".*\""
+ fi
+
+ if [ -z "$NNN_LIST" ]; then
+ findcmd="$findcmd -print"
+ else
+ findcmd="$findcmd -printf "'"'"$NNN_LIST/%P\n"'"'
+ fi
+
+ arr=$(eval "$findcmd" | sort)
+fi
+
+lines=$(printf "%s\n" "$arr" | wc -l)
+width=${#lines}
+
+printf "%s" "$arr" | awk '{printf("%'"${width}"'d %s\n", NR, $0)}' > "$dst_file"
+
+items=("~")
+while IFS='' read -r line; do
+ if [ -n "$NNN_LIST" ]; then
+ line=$(readlink "$line" || printf "%s" "$line")
+ fi
+
+ items+=("$line");
+done < <(printf "%s\n" "$arr")
+
+$EDITOR "$dst_file"
+
+while read -r num name; do
+ if [ -z "$name" ]; then
+ if [ -z "$num" ]; then
+ continue
+ fi
+
+ printf "%s: unable to parse line, aborting\n" "$0"
+ exit 1
+ fi
+
+ # check if $num is an integer
+ if [ ! "$num" -eq "$num" ] 2> /dev/null; then
+ printf "%s: unable to parse line, aborting\n" "$0"
+ exit 1
+ fi
+
+ src=${items[$num]}
+
+ if [ -z "$src" ]; then
+ printf "%s: unknown item number %s\n" "$0" "$num" > /dev/stderr
+ continue
+ elif [ "$name" != "$src" ]; then
+ if [ -z "$name" ]; then
+ continue
+ fi
+
+ if [ ! -e "$src" ] && [ ! -L "$src" ]; then
+ printf "%s: %s does not exit\n" "$0" "$src" > /dev/stderr
+
+ unset "items[$num]"
+ continue
+ fi
+
+ # handle swaps
+ if [ -e "$name" ] || [ -L "$name" ]; then
+ tmp="$name~"
+ c=0
+
+ while [ -e "$tmp" ] || [ -L "$tmp" ]; do
+ c=$((c+1))
+ tmp="$tmp~$c"
+ done
+
+ if mv "$name" "$tmp"; then
+ if [ "$VERBOSE" -ne 0 ]; then
+ printf "'%s' -> '%s'\n" "$name" "$tmp"
+ fi
+ else
+ printf "%s: failed to rename %s to %s: %s\n" "$0" "$name" "$tmp" "$!" > /dev/stderr
+ exit_status=1
+ fi
+
+ for key in "${!items[@]}"; do
+ if [ "${items[$key]}" = "$name" ]; then
+ items[$key]="$tmp"
+ fi
+ done
+ fi
+
+ dir=$(dirname "$name")
+ if [ ! -d "$dir" ] && ! mkdir -p "$dir"; then
+ printf "%s: failed to create directory tree %s\n" "$0" "$dir" > /dev/stderr
+ exit_status=1
+ elif ! mv -i "$src" "$name"; then
+ printf "%s: failed to rename %s to %s: %s\n" "$0" "$name" "$tmp" "$!" > /dev/stderr
+ exit_status=1
+ else
+ if [ -d "$name" ]; then
+ for key in "${!items[@]}"; do
+ items[$key]=$(printf "%s" "${items[$key]}" | sed "s|^$src\(\$\|\/\)|$name\1|")
+ done
+
+ if [ "$VERBOSE" -ne 0 ]; then
+ printf "'%s' => '%s'\n" "$src" "$name"
+ fi
+ else
+ true
+ if [ "$VERBOSE" -ne 0 ]; then
+ printf "'%s' -> '%s'\n" "$src" "$name"
+ fi
+ fi
+ fi
+ fi
+
+ unset "items[$num]"
+done <"$dst_file"
+
+unset "items[0]"
+for item in "${items[@]}"; do
+ $RM_UTIL "$item"
+done
+
+rm "$dst_file"
+exit $exit_status
diff --git a/.config/nnn/plugins/.nnn-plugin-helper b/.config/nnn/plugins/.nnn-plugin-helper
new file mode 100644
index 0000000..a0377ac
--- /dev/null
+++ b/.config/nnn/plugins/.nnn-plugin-helper
@@ -0,0 +1,38 @@
+#!/usr/bin/env sh
+
+# Description: Helper script for plugins
+#
+# Shell: POSIX compliant
+# Author: Anna Arad
+
+selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
+export selection
+
+## Set CUR_CTX to 1 to open directory in current context
+CUR_CTX=0
+export CUR_CTX
+
+## Ask nnn to switch to directory $1 in context $2.
+## If $2 is not provided, the function asks explicitly.
+nnn_cd () {
+ dir="$1"
+
+ if [ -z "$NNN_PIPE" ]; then
+ echo "No pipe file found" 1>&2
+ return
+ fi
+
+ if [ -n "$2" ]; then
+ context=$2
+ elif [ $CUR_CTX -ne 1 ]; then
+ printf "Choose context 1-4 (blank for current): "
+ read -r context
+ fi
+
+ printf "%s" "${context:-0}c$dir" > "$NNN_PIPE"
+}
+
+cmd_exists () {
+ type "$1" > /dev/null 2>&1
+ echo $?
+}
diff --git a/.config/nnn/plugins/.ntfy b/.config/nnn/plugins/.ntfy
new file mode 100755
index 0000000..2a61478
--- /dev/null
+++ b/.config/nnn/plugins/.ntfy
@@ -0,0 +1,22 @@
+#!/usr/bin/env sh
+
+# Description: Show a notification
+#
+# Details: nnn invokes this plugin to show notification when a cp/mv/rm operation is complete.
+#
+# Dependencies: notify-send (Ubuntu)/ntfy (https://github.com/dschep/ntfy)/osascript (macOS)/notify (Haiku)
+#
+# Shell: POSIX compliant
+# Author: Anna Arad
+
+OS="$(uname)"
+
+if type notify-send >/dev/null 2>&1; then
+ notify-send nnn "Done!"
+elif [ "$OS" = "Darwin" ]; then
+ osascript -e 'display notification "Done!" with title "nnn"'
+elif type ntfy >/dev/null 2>&1; then
+ ntfy -t nnn send "Done!"
+elif [ "$OS" = "Haiku" ]; then
+ notify --title "nnn" "Done!"
+fi
diff --git a/.config/nnn/plugins/preview-tui b/.config/nnn/plugins/preview-tui
new file mode 100755
index 0000000..18791fd
--- /dev/null
+++ b/.config/nnn/plugins/preview-tui
@@ -0,0 +1,481 @@
+#!/usr/bin/env sh
+
+# Description: Terminal based file previewer
+#
+# Note: This plugin needs a "NNN_FIFO" to work. See man.
+#
+# Dependencies:
+# - Supports 5 independent methods to preview with:
+# - tmux (>=3.0), or
+# - kitty with allow_remote_control and listen_on set in kitty.conf, or
+# - QuickLook on WSL (https://github.com/QL-Win/QuickLook), or
+# - Windows Terminal (https://github.com/Microsoft/Terminal | https://aka.ms/terminal) with WSL, or
+# - $TERMINAL set to a terminal (it's xterm by default).
+# - less or $PAGER
+# - tree or exa or ls
+# - mediainfo or file
+# - mktemp
+# - unzip
+# - tar
+# - man
+# - optional: bsdtar or atool for additional archive preview
+# - optional: bat for code syntax highlighting
+# - optional: ueberzug, kitty terminal, viu or catimg for images
+# - optional: convert(ImageMagick) for playing gif preview (required for kitty image previews)
+# - optional: ffmpegthumbnailer for video thumbnails (https://github.com/dirkvdb/ffmpegthumbnailer)
+# - optional: ffmpeg for audio thumbnails
+# - optional: libreoffce for opendocument/officedocument preview
+# - optional: pdftoppm(poppler) for pdf thumbnails
+# - optional: gnome-epub-thumbnailer for epub thumbnails (https://gitlab.gnome.org/GNOME/gnome-epub-thumbnailer)
+# - optional: fontpreview for font preview (https://github.com/sdushantha/fontpreview)
+# - optional: djvulibre for djvu
+# - optional: glow or lowdown for markdown
+# - optional: w3m or lynx or elinks for html
+# - optional: set/export ICONLOOKUP as 1 to enable file icons in front of directory previews with .iconlookup
+# Icons and colors are configureable in .iconlookup
+# - optional: scope.sh file viewer from ranger.
+# 1. drop scope.sh executable in $PATH
+# 2. set/export $USE_SCOPE as 1
+# - optional: pistol file viewer (https://github.com/doronbehar/pistol).
+# 1. install pistol
+# 2. set/export $USE_PISTOL as 1
+#
+# Usage:
+# You need to set a NNN_FIFO path and a key for the plugin with NNN_PLUG,
+# then start `nnn`:
+#
+# $ nnn -a
+#
+# or
+#
+# $ NNN_FIFO=/tmp/nnn.fifo nnn
+#
+# Then launch the `preview-tui` plugin in `nnn`.
+#
+# If you provide the same NNN_FIFO to all nnn instances, there will be a
+# single common preview window. If you provide different FIFO path (e.g.
+# with -a), they will be independent.
+#
+# The previews will be shown in a tmux split. If that isn't possible, it
+# will try to use a kitty terminal split. And as a final fallback, a
+# different terminal window will be used ($TERMINAL).
+#
+# Tmux and kitty users can configure $SPLIT to either "h" or "v" to set a
+# 'h'orizontal split or a 'v'ertical split (as in, the line that splits the
+# windows will be horizontal or vertical).
+#
+# Kitty users need something similar to the following in their kitty.conf:
+# - `allow_remote_control yes`
+# - `listen_on unix:$TMPDIR/kitty`
+# - `enabled_layouts splits` (optional)
+# With ImageMagick installed, this terminal can use the icat kitten to display images.
+# Refer to kitty documentation for further details.
+#
+# Iterm2 users are recommended to use viu to view images without getting pixelated.
+#
+# Windows Terminal users can set "Profile termination behavior" under "Profile > Advanced" settings
+# to automaticaly close pane on quit when exit code is 0.
+#
+# Shell: POSIX compliant
+# Authors: Todd Yamakawa, Léo Villeveygoux, @Recidiviste, Mario Ortiz Manero, Luuk van Baal, @WanderLanz
+
+#SPLIT="$SPLIT" # you can set a permanent split here
+#TERMINAL="$TERMINAL" # same goes for the terminal
+SPLIT_SIZE="${SPLIT_SIZE:-50}" # split size in percentage for supported previewers
+USE_SCOPE="${USE_SCOPE:-0}"
+USE_PISTOL="${USE_PISTOL:-0}"
+ICONLOOKUP="${ICONLOOKUP:-0}"
+PAGER="${PAGER:-less -P?n -R}"
+TMPDIR="${TMPDIR:-/tmp}"
+BAT_STYLE="${BAT_STYLE:-numbers}"
+BAT_THEME="${BAT_THEME:-ansi}"
+# Consider setting NNN_PREVIEWDIR to $XDG_CACHE_HOME/nnn/previews if you want to keep previews on disk between reboots
+NNN_PREVIEWDIR="${NNN_PREVIEWDIR:-$TMPDIR/nnn/previews}"
+NNN_PREVIEWWIDTH="${NNN_PREVIEWWIDTH:-1920}"
+NNN_PREVIEWHEIGHT="${NNN_PREVIEWHEIGHT:-1080}"
+NNN_PARENT="${NNN_FIFO#*.}"
+[ "$NNN_PARENT" -eq "$NNN_PARENT" ] 2>/dev/null || NNN_PARENT=""
+FIFOPID="$TMPDIR/nnn-preview-tui-fifopid.$NNN_PARENT"
+PREVIEWPID="$TMPDIR/nnn-preview-tui-pagerpid.$NNN_PARENT"
+CURSEL="$TMPDIR/nnn-preview-tui-selection.$NNN_PARENT"
+FIFO_UEBERZUG="$TMPDIR/nnn-preview-tui-ueberzug-fifo.$NNN_PARENT"
+POSOFFSET="$TMPDIR/nnn-preview-tui-posoffset"
+
+exists() { type "$1" >/dev/null 2>&1 ;}
+pkill() { command pkill "$@" >/dev/null 2>&1 ;}
+pidkill() { [ -f "$1" ] && kill "$(cat "$1")" >/dev/null 2>&1 ;}
+prompt() { printf "%b" "$@"; cfg=$(stty -g); stty raw -echo; head -c 1; stty "$cfg" ;}
+
+start_preview() {
+ [ "$PAGER" = "most" ] && PAGER="less -R"
+
+ if [ -e "${TMUX%%,*}" ] && tmux -V | grep -q '[ -][3456789]\.'; then
+ TERMINAL=tmux
+ elif [ -n "$KITTY_LISTEN_ON" ]; then
+ TERMINAL=kitty
+ elif [ -z "$TERMINAL" ] && [ "$TERM_PROGRAM" = "iTerm.app" ]; then
+ TERMINAL=iterm
+ elif [ -n "$WT_SESSION" ]; then
+ TERMINAL=winterm
+ else
+ TERMINAL="${TERMINAL:-xterm}"
+ fi
+
+ if [ -z "$SPLIT" ] && [ $(($(tput lines) * 2)) -gt "$(tput cols)" ]; then
+ SPLIT='h'
+ elif [ "$SPLIT" != 'h' ]; then
+ SPLIT='v'
+ fi
+
+ case "$TERMINAL" in
+ tmux) # tmux splits are inverted
+ if [ "$SPLIT" = "v" ]; then DSPLIT="h"; else DSPLIT="v"; fi
+ tmux split-window -e "NNN_FIFO=$NNN_FIFO" -e "PREVIEW_MODE=1" -e "CURSEL=$CURSEL" \
+ -e "TMPDIR=$TMPDIR" -e "FIFOPID=$FIFOPID" -e "POSOFFSET=$POSOFFSET" \
+ -e "BAT_STYLE=$BAT_STYLE" -e "BAT_THEME=$BAT_THEME" -e "PREVIEWPID=$PREVIEWPID" \
+ -e "PAGER=$PAGER" -e "ICONLOOKUP=$ICONLOOKUP" -e "NNN_PREVIEWWIDTH=$NNN_PREVIEWWIDTH" \
+ -e "USE_SCOPE=$USE_SCOPE" -e "SPLIT=$SPLIT" -e "USE_PISTOL=$USE_PISTOL" \
+ -e "NNN_PREVIEWDIR=$NNN_PREVIEWDIR" -e "NNN_PREVIEWHEIGHT=$NNN_PREVIEWHEIGHT" \
+ -e "FIFO_UEBERZUG=$FIFO_UEBERZUG" -e "QLPATH=$2" -d"$DSPLIT" -p"$SPLIT_SIZE" "$0" "$1" ;;
+ kitty) # Setting the layout for the new window. It will be restored after the script ends.
+ kitty @ goto-layout splits
+ # Trying to use kitty's integrated window management as the split window. All
+ # environmental variables that will be used in the new window must be explicitly passed.
+ kitty @ launch --no-response --title "nnn preview" --keep-focus \
+ --cwd "$PWD" --env "PATH=$PATH" --env "NNN_FIFO=$NNN_FIFO" \
+ --env "PREVIEW_MODE=1" --env "PAGER=$PAGER" --env "TMPDIR=$TMPDIR" \
+ --env "USE_SCOPE=$USE_SCOPE" --env "SPLIT=$SPLIT" --env "TERMINAL=$TERMINAL"\
+ --env "PREVIEWPID=$PREVIEWPID" --env "FIFO_UEBERZUG=$FIFO_UEBERZUG" \
+ --env "ICONLOOKUP=$ICONLOOKUP" --env "NNN_PREVIEWHEIGHT=$NNN_PREVIEWHEIGHT" \
+ --env "NNN_PREVIEWWIDTH=$NNN_PREVIEWWIDTH" --env "NNN_PREVIEWDIR=$NNN_PREVIEWDIR" \
+ --env "USE_PISTOL=$USE_PISTOL" --env "BAT_STYLE=$BAT_STYLE" \
+ --env "BAT_THEME=$BAT_THEME" --env "FIFOPID=$FIFOPID" \
+ --env "CURSEL=$CURSEL" --location "${SPLIT}split" "$0" "$1" ;;
+ iterm)
+ command="$SHELL -c 'cd $PWD; \
+ PATH=\\\"$PATH\\\" NNN_FIFO=\\\"$NNN_FIFO\\\" PREVIEW_MODE=1 PAGER=\\\"$PAGER\\\" \
+ USE_SCOPE=\\\"$USE_SCOPE\\\" SPLIT=\\\"$SPLIT\\\" TERMINAL=\\\"$TERMINAL\\\" \
+ PREVIEWPID=\\\"$PREVIEWPID\\\" CURSEL=\\\"$CURSEL\\\" TMPDIR=\\\"$TMPDIR\\\" \
+ ICONLOOKUP=\\\"$ICONLOOKUP\\\" NNN_PREVIEWHEIGHT=\\\"$NNN_PREVIEWHEIGHT\\\" \
+ NNN_PREVIEWWIDTH=\\\"$NNN_PREVIEWWIDTH\\\" NNN_PREVIEWDIR=\\\"$NNN_PREVIEWDIR\\\" \
+ USE_PISTOL=\\\"$USE_PISTOL\\\" BAT_STYLE=\\\"$BAT_STYLE\\\" \
+ BAT_THEME=\\\"$BAT_THEME\\\" FIFOPID=\\\"$FIFOPID\\\" \\\"$0\\\" \\\"$1\\\"'"
+ if [ "$SPLIT" = "h" ]; then split="horizontally"; else split="vertically"; fi
+ osascript <<-EOF
+ tell application "iTerm"
+ tell current session of current window
+ split $split with default profile command "$command"
+ end tell
+ end tell
+EOF
+ ;;
+ winterm)
+ if [ "$SPLIT" = "h" ]; then split="H"; else split="V"; fi
+ cmd.exe /c wt -w 0 sp -$split -s$((SPLIT_SIZE / 100)) bash -c "cd $PWD \; \
+ PATH='$PATH' NNN_FIFO=$NNN_FIFO PREVIEW_MODE=1 CURSEL=$CURSEL TMPDIR=$TMPDIR \
+ FIFOPID=$FIFOPID BAT_STYLE=$BAT_STYLE BAT_THEME=$BAT_THEME PREVIEWPID=$PREVIEWPID \
+ PAGER='$PAGER' ICONLOOKUP=$ICONLOOKUP NNN_PREVIEWWIDTH=$NNN_PREVIEWWIDTH \
+ USE_SCOPE=$USE_SCOPE SPLIT=$SPLIT USE_PISTOL=$USE_PISTOL \
+ NNN_PREVIEWDIR=$NNN_PREVIEWDIR NNN_PREVIEWHEIGHT=$NNN_PREVIEWHEIGHT \
+ FIFO_UEBERZUG=$FIFO_UEBERZUG QLPATH=$2 $0 $1" \; -w 0 mf previous
+ ;;
+ *) if [ -n "$2" ]; then
+ QUICKLOOK=1 QLPATH="$2" PREVIEW_MODE=1 "$0" "$1" &
+ else
+ PREVIEWPID="$PREVIEWPID" CURSEL="$CURSEL" PREVIEW_MODE=1 \
+ FIFOPID="$FIFOPID" FIFO_UEBERZUG="$FIFO_UEBERZUG" $TERMINAL -e "$0" "$1" &
+ fi ;;
+ esac
+}
+
+toggle_preview() {
+ if exists QuickLook.exe; then
+ QLPATH="QuickLook.exe"
+ elif exists Bridge.exe; then
+ QLPATH="Bridge.exe"
+ fi
+ if pidkill "$FIFOPID"; then
+ [ -p "$NNN_PPIPE" ] && printf "0" > "$NNN_PPIPE"
+ pidkill "$PREVIEWPID"
+ pkill -f "tail --follow $FIFO_UEBERZUG"
+ if [ -n "$QLPATH" ] && stat "$1"; then
+ f="$(wslpath -w "$1")" && "$QLPATH" "$f" &
+ fi
+ else
+ [ -p "$NNN_PPIPE" ] && printf "1" > "$NNN_PPIPE"
+ start_preview "$1" "$QLPATH"
+ fi
+}
+
+fifo_pager() {
+ cmd="$1"
+ shift
+
+ # We use a FIFO to access $PAGER PID in jobs control
+ tmpfifopath="$TMPDIR/nnn-preview-tui-fifo.$$"
+ mkfifo "$tmpfifopath" || return
+
+ $PAGER < "$tmpfifopath" &
+ printf "%s" "$!" > "$PREVIEWPID"
+
+ (
+ exec > "$tmpfifopath"
+ if [ "$cmd" = "pager" ]; then
+ if exists bat; then
+ bat --terminal-width="$cols" --decorations=always --color=always \
+ --paging=never --style="$BAT_STYLE" --theme="$BAT_THEME" "$@" &
+ else
+ $PAGER "$@" &
+ fi
+ else
+ "$cmd" "$@" &
+ fi
+ )
+
+ rm "$tmpfifopath"
+}
+
+# Binary file: show file info inside the pager
+print_bin_info() {
+ printf -- "-------- \033[1;31mBinary file\033[0m --------\n"
+ if exists mediainfo; then
+ mediainfo "$1"
+ else
+ file -b "$1"
+ fi
+}
+
+handle_mime() {
+ case "$2" in
+ image/jpeg) image_preview "$cols" "$lines" "$1" ;;
+ image/gif) generate_preview "$cols" "$lines" "$1" "gif" ;;
+ image/vnd.djvu) generate_preview "$cols" "$lines" "$1" "djvu" ;;
+ image/*) generate_preview "$cols" "$lines" "$1" "image" ;;
+ video/*) generate_preview "$cols" "$lines" "$1" "video" ;;
+ audio/*) generate_preview "$cols" "$lines" "$1" "audio" ;;
+ application/font*|application/*opentype|font/*) generate_preview "$cols" "$lines" "$1" "font" ;;
+ */*office*|*/*document*) generate_preview "$cols" "$lines" "$1" "office" ;;
+ application/zip) fifo_pager unzip -l "$1" ;;
+ text/troff)
+ if exists man; then
+ fifo_pager man -Pcat -l "$1"
+ else
+ fifo_pager pager "$1"
+ fi ;;
+ *) handle_ext "$1" "$3" "$4" ;;
+ esac
+}
+
+handle_ext() {
+ case "$2" in
+ epub) generate_preview "$cols" "$lines" "$1" "epub" ;;
+ pdf) generate_preview "$cols" "$lines" "$1" "pdf" ;;
+ gz|bz2) fifo_pager tar -tvf "$1" ;;
+ md) if exists glow; then
+ fifo_pager glow -s dark "$1"
+ elif exists lowdown; then
+ fifo_pager lowdown -Tterm "$1"
+ else
+ fifo_pager pager "$1"
+ fi ;;
+ htm|html|xhtml)
+ if exists w3m; then
+ fifo_pager w3m "$1"
+ elif exists lynx; then
+ fifo_pager lynx "$1"
+ elif exists elinks; then
+ fifo_pager elinks "$1"
+ else
+ fifo_pager pager "$1"
+ fi ;;
+ 7z|a|ace|alz|arc|arj|bz|cab|cpio|deb|jar|lha|lz|lzh|lzma|lzo\
+ |rar|rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z)
+ if exists atool; then
+ fifo_pager atool -l "$1"
+ elif exists bsdtar; then
+ fifo_pager bsdtar -tvf "$1"
+ fi ;;
+ *) if [ "$3" = "bin" ]; then
+ fifo_pager print_bin_info "$1"
+ else
+ fifo_pager pager "$1"
+ fi ;;
+ esac
+}
+
+preview_file() {
+ clear
+ # Trying to use pistol if it's available.
+ if [ "$USE_PISTOL" -ne 0 ] && exists pistol; then
+ fifo_pager pistol "$1"
+ return
+ fi
+
+ # Trying to use scope.sh if it's available.
+ if [ "$USE_SCOPE" -ne 0 ] && exists scope.sh; then
+ fifo_pager scope.sh "$1" "$cols" "$lines" "$(mktemp -d)" "True"
+ return
+ fi
+
+ # Use QuickLook if it's available.
+ if [ -n "$QUICKLOOK" ]; then
+ stat "$1" && f="$(wslpath -w "$1")" && "$QLPATH" "$f" &
+ return
+ fi
+
+ # Detecting the exact type of the file: the encoding, mime type, and extension in lowercase.
+ encoding="$(file -bL --mime-encoding -- "$1")"
+ mimetype="$(file -bL --mime-type -- "$1")"
+ ext="${1##*.}"
+ [ -n "$ext" ] && ext="$(printf "%s" "${ext}" | tr '[:upper:]' '[:lower:]')"
+ lines=$(tput lines)
+ cols=$(tput cols)
+
+ # Otherwise, falling back to the defaults.
+ if [ -d "$1" ]; then
+ cd "$1" || return
+ if [ "$ICONLOOKUP" -ne 0 ] && [ -f "$(dirname "$0")"/.iconlookup ]; then
+ [ "$SPLIT" = v ] && BSTR="\n"
+ # shellcheck disable=SC2012
+ ls -F --group-directories-first | head -n "$((lines - 3))" | "$(dirname "$0")"/.iconlookup -l "$cols" -B "$BSTR" -b " "
+ elif exists tree; then
+ fifo_pager tree --filelimit "$(find . -maxdepth 1 | wc -l)" -L 3 -C -F --dirsfirst --noreport
+ elif exists exa; then
+ exa -G --group-directories-first --colour=always
+ else
+ fifo_pager ls -F --group-directories-first --color=always
+ fi
+ elif [ "${encoding#*)}" = "binary" ]; then
+ handle_mime "$1" "$mimetype" "$ext" "bin"
+ else
+ handle_mime "$1" "$mimetype" "$ext"
+ fi
+}
+
+generate_preview() {
+ if [ -n "$QLPATH" ] && stat "$3"; then
+ f="$(wslpath -w "$3")" && "$QLPATH" "$f" &
+ elif [ ! -f "$NNN_PREVIEWDIR/$3.jpg" ] || [ -n "$(find -L "$3" -newer "$NNN_PREVIEWDIR/$3.jpg")" ]; then
+ mkdir -p "$NNN_PREVIEWDIR/${3%/*}"
+ case $4 in
+ audio) ffmpeg -i "$3" -filter_complex "scale=iw*min(1\,min($NNN_PREVIEWWIDTH/iw\,ih)):-1" "$NNN_PREVIEWDIR/$3.jpg" -y ;;
+ epub) gnome-epub-thumbnailer "$3" "$NNN_PREVIEWDIR/$3.jpg" ;;
+ font) fontpreview -i "$3" -o "$NNN_PREVIEWDIR/$3.jpg" ;;
+ gif) if [ -p "$FIFO_UEBERZUG" ] && exists convert; then
+ frameprefix="$NNN_PREVIEWDIR/$3/${3##*/}"
+ if [ ! -d "$NNN_PREVIEWDIR/$3" ]; then
+ mkdir -p "$NNN_PREVIEWDIR/$3"
+ convert -coalesce -resize "$NNN_PREVIEWWIDTH"x"$NNN_PREVIEWHEIGHT"\> "$3" "$frameprefix.jpg" ||
+ MAGICK_TMPDIR="/tmp" convert -coalesce -resize "$NNN_PREVIEWWIDTH"x"$NNN_PREVIEWHEIGHT"\> "$3" "$frameprefix.jpg"
+ fi
+ frames=$(($(find "$NNN_PREVIEWDIR/$3" | wc -l) - 2))
+ [ $frames -lt 0 ] && return
+ while true; do
+ for i in $(seq 0 $frames); do
+ image_preview "$1" "$2" "$frameprefix-$i.jpg"
+ sleep 0.1
+ done
+ done &
+ printf "%s" "$!" > "$PREVIEWPID"
+ return
+ else
+ exec >/dev/tty
+ image_preview "$1" "$2" "$3"
+ return
+ fi ;;
+ image) if exists convert; then
+ convert "$3" -flatten -resize "$NNN_PREVIEWWIDTH"x"$NNN_PREVIEWHEIGHT"\> "$NNN_PREVIEWDIR/$3.jpg"
+ else
+ image_preview "$1" "$2" "$3" && return
+ fi ;;
+ office) libreoffice --convert-to jpg "$3" --outdir "$NNN_PREVIEWDIR/${3%/*}"
+ filename="$(printf "%s" "${3##*/}" | cut -d. -f1)"
+ mv "$NNN_PREVIEWDIR/${3%/*}/$filename.jpg" "$NNN_PREVIEWDIR/$3.jpg" ;;
+ pdf) pdftoppm -jpeg -f 1 -singlefile "$3" "$NNN_PREVIEWDIR/$3" ;;
+ djvu) ddjvu -format=ppm -page=1 "$3" "$NNN_PREVIEWDIR/$3.jpg" ;;
+ video) ffmpegthumbnailer -s0 -i "$3" -o "$NNN_PREVIEWDIR/$3.jpg" || rm "$NNN_PREVIEWDIR/$3.jpg" ;;
+ esac
+ fi
+ if [ -f "$NNN_PREVIEWDIR/$3.jpg" ]; then
+ image_preview "$1" "$2" "$NNN_PREVIEWDIR/$3.jpg"
+ else
+ fifo_pager print_bin_info "$3"
+ fi
+} >/dev/null 2>&1
+
+image_preview() {
+ clear
+ if [ "$TERMINAL" = "kitty" ]; then
+ # Kitty terminal users can use the native image preview method
+ kitty +kitten icat --silent --scale-up --place "$1"x"$2"@0x0 --transfer-mode=stream --stdin=no "$3" &
+ elif exists ueberzug; then
+ ueberzug_layer "$1" "$2" "$3" && return
+ elif exists catimg; then
+ catimg "$3" &
+ elif exists viu; then
+ viu -t "$3" &
+ else
+ fifo_pager print_bin_info "$3" && return
+ fi
+ printf "%s" "$!" > "$PREVIEWPID"
+}
+
+ueberzug_layer() {
+ [ -f "$POSOFFSET" ] && read -r x y < "$POSOFFSET"
+ printf '{"action": "add", "identifier": "nnn_ueberzug", "x": %d, "y": %d, "width": "%d", "height": "%d", "scaler": "fit_contain", "path": "%s"}\n'\
+ "${x:-0}" "${y:-0}" "$1" "$2" "$3" > "$FIFO_UEBERZUG"
+}
+
+ueberzug_remove() {
+ printf '{"action": "remove", "identifier": "nnn_ueberzug"}\n' > "$FIFO_UEBERZUG"
+}
+
+winch_handler() {
+ clear
+ pidkill "$PREVIEWPID"
+ if [ -p "$FIFO_UEBERZUG" ]; then
+ pkill -f "tail --follow $FIFO_UEBERZUG"
+ tail --follow "$FIFO_UEBERZUG" | ueberzug layer --silent --parser json &
+ fi
+ preview_file "$(cat "$CURSEL")"
+}
+
+preview_fifo() {
+ while read -r selection; do
+ if [ -n "$selection" ]; then
+ pidkill "$PREVIEWPID"
+ [ -p "$FIFO_UEBERZUG" ] && ueberzug_remove
+ [ "$selection" = "close" ] && break
+ preview_file "$selection"
+ printf "%s" "$selection" > "$CURSEL"
+ fi
+ done < "$NNN_FIFO"
+ sleep 0.1 # make sure potential preview by winch_handler is killed
+ pkill -P "$$"
+}
+
+if [ "$PREVIEW_MODE" ]; then
+ if [ "$TERMINAL" != "kitty" ] && exists ueberzug; then
+ mkfifo "$FIFO_UEBERZUG"
+ tail --follow "$FIFO_UEBERZUG" | ueberzug layer --silent --parser json &
+ fi
+
+ preview_file "$PWD/$1"
+ preview_fifo &
+ printf "%s" "$!" > "$FIFOPID"
+ printf "%s" "$PWD/$1" > "$CURSEL"
+ trap 'winch_handler; wait' WINCH
+ trap 'rm "$PREVIEWPID" "$CURSEL" "$FIFO_UEBERZUG" "$FIFOPID" "$POSOFFSET" 2>/dev/null' INT HUP EXIT
+ wait "$!" 2>/dev/null
+ exit 0
+else
+ if [ ! -r "$NNN_FIFO" ]; then
+ clear
+ prompt "No FIFO available! (\$NNN_FIFO='$NNN_FIFO')\nPlease read Usage in preview-tui."
+ elif [ "$KITTY_WINDOW_ID" ] && [ -z "$TMUX" ] && [ -z "$KITTY_LISTEN_ON" ]; then
+ clear
+ prompt "\$KITTY_LISTEN_ON not set!\nPlease read Usage in preview-tui."
+ else
+ toggle_preview "$1" &
+ fi
+fi