From e18aadc93770a7c0e0fcc870aed5a3d3f5473203 Mon Sep 17 00:00:00 2001 From: "Ivan K. Boikov" Date: Sun, 20 Apr 2025 16:50:12 +0200 Subject: nnn: update plugins --- nnn/.config/nnn/plugins/.iconlookup | 97 ++++++------ nnn/.config/nnn/plugins/.nmv | 8 +- nnn/.config/nnn/plugins/bulknew | 2 +- nnn/.config/nnn/plugins/cbcopy-mac | 16 ++ nnn/.config/nnn/plugins/cbpaste-mac | 24 +++ nnn/.config/nnn/plugins/diffs | 2 +- nnn/.config/nnn/plugins/dups | 6 +- nnn/.config/nnn/plugins/finder | 4 +- nnn/.config/nnn/plugins/fixname | 2 +- nnn/.config/nnn/plugins/fzcd | 2 +- nnn/.config/nnn/plugins/fzhist | 19 ++- nnn/.config/nnn/plugins/fzopen | 42 +++--- nnn/.config/nnn/plugins/getplugs | 4 +- nnn/.config/nnn/plugins/imgur | 2 +- nnn/.config/nnn/plugins/imgview | 2 +- nnn/.config/nnn/plugins/mimelist | 12 +- nnn/.config/nnn/plugins/nbak | 4 +- nnn/.config/nnn/plugins/nmount | 42 +++++- nnn/.config/nnn/plugins/nuke | 6 +- nnn/.config/nnn/plugins/organize | 14 +- nnn/.config/nnn/plugins/pdfread | 4 +- nnn/.config/nnn/plugins/preview-tabbed | 21 ++- nnn/.config/nnn/plugins/preview-tui | 263 +++++++++++++++++++-------------- nnn/.config/nnn/plugins/upload | 37 ++--- nnn/.config/nnn/plugins/wallpaper | 10 +- 25 files changed, 406 insertions(+), 239 deletions(-) create mode 100755 nnn/.config/nnn/plugins/cbcopy-mac create mode 100755 nnn/.config/nnn/plugins/cbpaste-mac diff --git a/nnn/.config/nnn/plugins/.iconlookup b/nnn/.config/nnn/plugins/.iconlookup index d48d676..49b4764 100755 --- a/nnn/.config/nnn/plugins/.iconlookup +++ b/nnn/.config/nnn/plugins/.iconlookup @@ -29,6 +29,7 @@ awk 'BEGIN { 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_elixir=104 #color_elixir=109 #color_elixir="143;188;187" 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" @@ -44,49 +45,53 @@ awk 'BEGIN { # 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["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["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["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["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["license"][1] = "󰈙"; icons["license"][2] = color_docs + icons["makefile"][1] = "󰆍"; icons["makefile"][2] = color_default + icons["archive"][1] = "󰀼"; icons["archive"][2] = color_archive + icons["rust"][1] = ""; icons["rust"][2] = color_default icons["script"][1] = ""; icons["script"][2] = color_shell + icons["subtitle"][1] = "󰅺"; icons["subtitle"][2] = color_default 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["js"][1] = "󰌞"; icons["js"][2] = color_js + icons["linux"][1] = "󰌽"; icons["linux"][2] = color_default + icons["elixir"][1] = ""; icons["elixir"][2] = color_fsharp 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["chess"][1] = "󰄺"; icons["chess"][2] = color_default icons["haskell"][1] = ""; icons["haskell"][2] = color_vim - icons["html"][1] = ""; icons["html"][2] = color_default + icons["font"][1] = ""; icons["font"][2] = color_default + 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["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 @@ -140,6 +145,9 @@ awk 'BEGIN { 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] + icons["ex"][1] = icons["elixir"][1]; icons["ex"][2] = icons["elixir"][2] + icons["eex"][1] = icons["elixir"][1]; icons["eex"][2] = icons["elixir"][2] + icons["exs"][1] = icons["elixir"][1]; icons["exs"][2] = icons["elixir"][2] # f icons["fsharp"][1] = icons["fsharp"][1]; icons["fsharp"][2] = icons["fsharp"][2] @@ -154,7 +162,7 @@ awk 'BEGIN { # 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["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] @@ -167,12 +175,14 @@ awk 'BEGIN { 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] + icons["heex"][1] = icons["elixir"][1]; icons["heex"][2] = icons["elixir"][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] + icons["isub"][1] = icons["subtitle"][1]; icons["isub"][2] = icons["subtitle"][2] # j icons["jar"][1] = icons["java"][1]; icons["jar"][2] = icons["java"][2] @@ -180,10 +190,12 @@ awk 'BEGIN { 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["json"][1] = ""; icons["json"][2] = color_js icons["jsx"][1] = icons["react"][1]; icons["jsx"][2] = icons["react"][2] + icons["jxl"][1] = icons["picturefile"][1]; icons["jxl"][2] = icons["picturefile"][2] # k + icons["ksh"][1] = icons["font"][1]; icons["ksf"][2] = icons["font"][2] # l icons["lha"][1] = icons["archive"][1]; icons["lha"][2] = icons["archive"][2] @@ -194,7 +206,7 @@ awk 'BEGIN { icons["lzma"][1] = icons["archive"][1]; icons["lzma"][2] = icons["archive"][2] # m - icons["m"][1] = "ﴜ"; icons["mat"][2] = color_c + 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 @@ -207,7 +219,7 @@ awk 'BEGIN { 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 + icons["msi"][1] = "󰍲"; icons["msi"][2] = color_default # n icons["nix"][1] = ""; icons["nix"][2] = color_fsharp @@ -216,17 +228,18 @@ awk 'BEGIN { 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["otf"][1] = icons["font"][1]; icons["otf"][2] = icons["font"][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["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["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] @@ -239,10 +252,10 @@ awk 'BEGIN { # 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["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 + 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 @@ -253,18 +266,18 @@ awk 'BEGIN { 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["srt"][1] = icons["subtitle"][1]; icons["srt"][2] = icons["subtitle"][2] 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["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] + icons["ttf"][1] = icons["font"][1]; icons["ttf"][2] = icons["font"][2] # u @@ -272,7 +285,7 @@ awk 'BEGIN { 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 + icons["vtt"][1] = icons["subtitle"][1]; icons["vtt"][2] = icons["subtitle"][2] # 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] @@ -283,8 +296,8 @@ awk 'BEGIN { 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["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] diff --git a/nnn/.config/nnn/plugins/.nmv b/nnn/.config/nnn/plugins/.nmv index eaebda6..67abe16 100755 --- a/nnn/.config/nnn/plugins/.nmv +++ b/nnn/.config/nnn/plugins/.nmv @@ -32,7 +32,7 @@ case "$NNN_TRASH" in 2) RM_UTIL="gio trash" ;; *) - RM_UTIL="rm -ri" ;; + RM_UTIL="rm -ri --" ;; esac exit_status=0 @@ -64,7 +64,7 @@ lines=$(printf "%s\n" "$arr" | wc -l) width=${#lines} dst_file=$(mktemp "$TMPDIR/.nnnXXXXXX") -trap 'rm -f "$dst_file"' EXIT +trap 'rm -f -- "$dst_file"' EXIT printf "%s" "$arr" | awk '{printf("%'"${width}"'d %s\n", NR, $0)}' > "$dst_file" @@ -122,7 +122,7 @@ while read -r num name; do tmp="$tmp~$c" done - if mv "$name" "$tmp"; then + if mv -- "$name" "$tmp"; then if [ "$VERBOSE" -ne 0 ]; then printf "'%s' -> '%s'\n" "$name" "$tmp" fi @@ -142,7 +142,7 @@ while read -r num name; do 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 + 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 diff --git a/nnn/.config/nnn/plugins/bulknew b/nnn/.config/nnn/plugins/bulknew index 64331e4..7780961 100755 --- a/nnn/.config/nnn/plugins/bulknew +++ b/nnn/.config/nnn/plugins/bulknew @@ -29,4 +29,4 @@ $EDITOR "$tmpfile" sed "/^\//d" "$tmpfile" | xargs -n1 -I{} sh -c "$cmd" -rm "$tmpfile" +rm -- "$tmpfile" diff --git a/nnn/.config/nnn/plugins/cbcopy-mac b/nnn/.config/nnn/plugins/cbcopy-mac new file mode 100755 index 0000000..a117a72 --- /dev/null +++ b/nnn/.config/nnn/plugins/cbcopy-mac @@ -0,0 +1,16 @@ +#!/usr/bin/osascript + +# Description: Copy the hovered file to MacOS clipboard. +# +# Note: Supports only MacOS +# +# Shell: POSIX compliant +# Author: Syed Umar Anis + + +on run args + set filePath to (second item of args & "/" & first item of args) + tell application "Finder" + set the clipboard to (filePath as POSIX file) + end tell +end diff --git a/nnn/.config/nnn/plugins/cbpaste-mac b/nnn/.config/nnn/plugins/cbpaste-mac new file mode 100755 index 0000000..5edf9c6 --- /dev/null +++ b/nnn/.config/nnn/plugins/cbpaste-mac @@ -0,0 +1,24 @@ +#!/usr/bin/env sh +# shellcheck disable=all + +# Description: Paste the clipboard files into the current directory. +# Only works if clipboard contents are files. +# +# Note: Supports only MacOS +# +# Shell: POSIX compliant +# Author: Syed Umar Anis + + +fs=($( osascript -e "use framework \"Foundation\" + property this : a reference to the current application + property NSPasteboard : a reference to NSPasteboard of this + property NSURL : a reference to NSURL of this + property pb : a reference to NSPasteboard's generalPasteboard + + property text item delimiters : linefeed + + pb's readObjectsForClasses:[NSURL] options:[] + (result's valueForKey:\"path\") as list as text" )) + +cp -R -- "${fs[@]}" "$2/" diff --git a/nnn/.config/nnn/plugins/diffs b/nnn/.config/nnn/plugins/diffs index 0464781..16adc4b 100755 --- a/nnn/.config/nnn/plugins/diffs +++ b/nnn/.config/nnn/plugins/diffs @@ -25,7 +25,7 @@ dirdiff() { ls -A1 "$1" > "$dir1" ls -A1 "$2" > "$dir2" $diffcmd "$dir1" "$dir2" - rm "$dir1" "$dir2" + rm -- "$dir1" "$dir2" } if [ -s "$selection" ]; then diff --git a/nnn/.config/nnn/plugins/dups b/nnn/.config/nnn/plugins/dups index 27c1807..d402367 100755 --- a/nnn/.config/nnn/plugins/dups +++ b/nnn/.config/nnn/plugins/dups @@ -58,13 +58,13 @@ read -r force if [ "$force" = "f" ]; then #shellcheck disable=SC2016 - sed -e "$sedcmd" "$tmpfile" | tr '\n' '\0' | xargs -0 -r sh -c 'rm -f "$0" "$@" "$TMPDIR/finderbms" printf "%s\n" "$fexpr" >> "$TMPDIR/finderbms" - mv "$TMPDIR/finderbms" "$NNN_FINDHIST" + mv -- "$TMPDIR/finderbms" "$NNN_FINDHIST" fi fi diff --git a/nnn/.config/nnn/plugins/fixname b/nnn/.config/nnn/plugins/fixname index 4047152..2b0ec1b 100755 --- a/nnn/.config/nnn/plugins/fixname +++ b/nnn/.config/nnn/plugins/fixname @@ -65,7 +65,7 @@ for i in "${targets[@]}"; do if [ -e "$(cleanup "$i")" ]; then tmp='_' fi - mv "$i" "$tmp$(cleanup "$i")"; + mv -- "$i" "$tmp$(cleanup "$i")"; fi done diff --git a/nnn/.config/nnn/plugins/fzcd b/nnn/.config/nnn/plugins/fzcd index 125092c..35fae7e 100755 --- a/nnn/.config/nnn/plugins/fzcd +++ b/nnn/.config/nnn/plugins/fzcd @@ -60,7 +60,7 @@ if [ -n "$LIST" ]; then # Alternative for 'fd' # sel=$(xargs -d '\n' < "$tmpfile" fd . | fzf --delimiter / --tiebreak=begin --info=hidden) - rm "$tmpfile" + rm -- "$tmpfile" else printf "find missing" read -r _ diff --git a/nnn/.config/nnn/plugins/fzhist b/nnn/.config/nnn/plugins/fzhist index 111bc22..de10c2a 100755 --- a/nnn/.config/nnn/plugins/fzhist +++ b/nnn/.config/nnn/plugins/fzhist @@ -3,7 +3,9 @@ # Description: Fuzzy find a command from history, # edit in $EDITOR and run as a command # -# Note: Supports only bash and fish history +# Note: Supports only bash, zsh and fish history +# +# TODO: For zsh there's also $ZDOTDIR which might need to be checked as well for the -z $HISTFILE && -n $ZDOTDIR case. # # Shell: POSIX compliant # Author: Arun Prakash Jana @@ -17,7 +19,18 @@ fi shellname="$(basename "$SHELL")" if [ "$shellname" = "bash" ]; then - hist_file="$HOME/.bash_history" + if [ -f "$HISTFILE" ]; then + hist_file="$HISTFILE" + else + hist_file="$HOME/.bash_history" + fi + entry="$("$fuzzy" < "$hist_file")" +elif [ "$shellname" = "zsh" ]; then + if [ -f "$HISTFILE" ]; then + hist_file="$HISTFILE" + else + hist_file="$HOME/.zsh_history" + fi entry="$("$fuzzy" < "$hist_file")" elif [ "$shellname" = "fish" ]; then hist_file="$HOME/.local/share/fish/fish_history" @@ -33,7 +46,7 @@ if [ -n "$entry" ]; then $SHELL -c "$(cat "$tmpfile")" fi - rm "$tmpfile" + rm -- "$tmpfile" printf "Press any key to exit" read -r _ diff --git a/nnn/.config/nnn/plugins/fzopen b/nnn/.config/nnn/plugins/fzopen index 17b0585..4303dc3 100755 --- a/nnn/.config/nnn/plugins/fzopen +++ b/nnn/.config/nnn/plugins/fzopen @@ -59,25 +59,27 @@ if [ "$3" ]; then exit 0 fi -if [ "$USE_NUKE" -ne 0 ]; then - "$NUKE" "$entry" - exit 0 -fi +if [ "$entry" ]; then + if [ "$USE_NUKE" -ne 0 ]; then + "$NUKE" "$entry" + exit 0 + fi -# Open the file (works for a single file only) -cmd_file="" -cmd_open="" -if uname | grep -q "Darwin"; then - cmd_file="file -bIL" - cmd_open="open" -else - cmd_file="file -biL" - cmd_open="xdg-open" -fi + # Open the file (works for a single file only) + cmd_file="" + cmd_open="" + if uname | grep -q "Darwin"; then + cmd_file="file -bIL" + cmd_open="open" + else + cmd_file="file -biL" + cmd_open="xdg-open" + fi -case "$($cmd_file "$entry")" in - *text*) - "${VISUAL:-$EDITOR}" "$entry" ;; - *) - $cmd_open "$entry" >/dev/null 2>&1 ;; -esac + case "$($cmd_file "$entry")" in + *text*) + "${VISUAL:-$EDITOR}" "$entry" ;; + *) + $cmd_open "$entry" >/dev/null 2>&1 ;; + esac +fi diff --git a/nnn/.config/nnn/plugins/getplugs b/nnn/.config/nnn/plugins/getplugs index 361a605..30dbf7b 100755 --- a/nnn/.config/nnn/plugins/getplugs +++ b/nnn/.config/nnn/plugins/getplugs @@ -24,7 +24,7 @@ prompt () { if [ "$operation" = "m" ]; then op="merge" elif [ "$operation" = "o" ]; then - op="cp -vRf" + op="cp -vRf --" else op="true" fi @@ -62,7 +62,7 @@ for f in $(find . -maxdepth 1 \( ! -iname "." ! -iname "*.md" \)); do $op "$f" ../../plugins/ fi else - cp -vRf "$f" ../../plugins/ + cp -vRf -- "$f" ../../plugins/ fi done cd ../.. || exit 1 diff --git a/nnn/.config/nnn/plugins/imgur b/nnn/.config/nnn/plugins/imgur index 16d21bc..e5981fc 100755 --- a/nnn/.config/nnn/plugins/imgur +++ b/nnn/.config/nnn/plugins/imgur @@ -583,7 +583,7 @@ for upload_file in "${upload_files[@]}"; do # delete file if configured if [ "${keep_file}" = "false" ] && [ -z "${1}" ]; then echo "Deleting temp file ${file_dir}/${img_file}" - rm -rf "${img_file}" + rm -rf -- "${img_file}" fi echo "" diff --git a/nnn/.config/nnn/plugins/imgview b/nnn/.config/nnn/plugins/imgview index d8cc247..0337511 100755 --- a/nnn/.config/nnn/plugins/imgview +++ b/nnn/.config/nnn/plugins/imgview @@ -54,7 +54,7 @@ make_thumbs() { done for file in "$NNN_PREVIEWDIR$dir"/*; do filename="$(basename "$file" .jpg)" - [ ! -e "$dir/$filename" ] && rm "$file" 2>/dev/null + [ ! -e "$dir/$filename" ] && rm -- "$file" 2>/dev/null done } diff --git a/nnn/.config/nnn/plugins/mimelist b/nnn/.config/nnn/plugins/mimelist index ccfe05a..3813c09 100755 --- a/nnn/.config/nnn/plugins/mimelist +++ b/nnn/.config/nnn/plugins/mimelist @@ -2,8 +2,12 @@ # Description: Find and list files by mime type in smart context # +# Dependencies: +# - file +# - mimetype (optional, PERL File MimeInfo) +# # Shell: POSIX compliant -# Author: Arun Prakash Jana +# Author: Arun Prakash Jana, Michel DHOOGE # shellcheck disable=SC1090,SC1091 . "$(dirname "$0")"/.nnn-plugin-helper @@ -12,4 +16,8 @@ printf "mime (e.g., video/audio/image): " read -r mime printf "%s" "+l" > "$NNN_PIPE" -find . | file -if- | grep "$mime" | awk -F: '{printf "%s\0", $1}' > "$NNN_PIPE" +if type mimetype >/dev/null 2>&1; then + find . | mimetype -f - | grep "$mime" | awk -F: '{printf "%s%c", $1, 0}' > "$NNN_PIPE" +else + find . | file -if- | grep "$mime" | awk -F: '{printf "%s%c", $1, 0}' > "$NNN_PIPE" +fi diff --git a/nnn/.config/nnn/plugins/nbak b/nnn/.config/nnn/plugins/nbak index f9cb644..9950026 100755 --- a/nnn/.config/nnn/plugins/nbak +++ b/nnn/.config/nnn/plugins/nbak @@ -34,7 +34,7 @@ fi cd "$tempdir/$outdir" || exit 1 # Backing up config dir content -cp -r "$configdir" . || exit 1 +cp -r -- "$configdir" . || exit 1 # Environment config env | sed "s/'/'\\\\''/" |\ @@ -72,4 +72,4 @@ printf "Saving as '%s' ... " "$workdir/$outfile" tar caf "$workdir/$outfile" "$outdir" && echo "Done" || echo "Failed" -cd "$workdir" && rm -rf "$tempdir" +cd "$workdir" && rm -rf -- "$tempdir" diff --git a/nnn/.config/nnn/plugins/nmount b/nnn/.config/nnn/plugins/nmount index c30efb4..e05453f 100755 --- a/nnn/.config/nnn/plugins/nmount +++ b/nnn/.config/nnn/plugins/nmount @@ -4,7 +4,7 @@ # If the device is not mounted, it will be mounted. # If the device is mounted, it will be unmounted and powered down. # -# Dependencies: lsblk, pmount +# Dependencies: lsblk, pmount (optional), udisks2 # # Usage: Runs `lsblk` on 'l', exits on 'Return`. # @@ -13,7 +13,7 @@ # macOS: "diskutil list" # BSD: "geom disk list" # - The script uses udisksctl (from udisks2) to power down devices. This is also Linux-specific. -# Users on non-Linux platforms can comment it and use an alterntive to power-down disks. +# Users on non-Linux platforms can comment it and use an alternative to power-down disks. # # Shell: POSIX compliant # Author: Arun Prakash Jana @@ -32,16 +32,48 @@ while [ -n "$dev" ]; do elif [ "$dev" = "q" ]; then exit else - if grep -qs "$dev " /proc/mounts; then + # LUKS volumes mounted with udisksctl appear differently than with pmount + if grep -qs "$dev " /proc/mounts || [ -n "$(lsblk -n "/dev/$dev" -o MOUNTPOINT)" ]; then sync "$(lsblk -n "/dev/$dev" -o MOUNTPOINT | sed "/^$/d")" - if pumount "/dev/$dev"; then + if type pumount >/dev/null 2>&1; then + pumount "/dev/$dev" + exit_code="$?" + else + # Unlike pmount, udisksctl does not transparently handle LUKS volumes + # We need to manually get the unlocked device, unmount it, and then lock the volume + if lsblk -n "/dev/$dev" -o FSTYPE | grep "crypto_LUKS" >/dev/null; then + dev_map="$(udisksctl info -b /dev/"$dev" | grep "CleartextDevice" | grep -o "dm_2d[[:digit:]]*" | sed "s/_2d/-/")" + udisksctl unmount -b "/dev/$dev_map" --no-user-interaction >/dev/null + exit_code="$?" + udisksctl lock -b "/dev/$dev" --no-user-interaction >/dev/null + else + udisksctl unmount -b "/dev/$dev" --no-user-interaction >/dev/null + exit_code="$?" + fi + fi + if [ $exit_code -eq 0 ]; then echo "/dev/$dev unmounted." if udisksctl power-off -b "/dev/$dev" --no-user-interaction; then echo "/dev/$dev ejected." fi fi elif [ -b "/dev/$dev" ]; then - if pmount "/dev/$dev"; then + if type pmount >/dev/null 2>&1; then + pmount "/dev/$dev" + exit_code="$?" + else + # Unlike pmount, udisksctl does not transparently handle LUKS volumes + # We need to manually get the unlocked device and mount that instead of the volume itself + if [ "$(lsblk "/dev/$dev" -n -o FSTYPE)" = "crypto_LUKS" ]; then + dev_map=$(udisksctl unlock -b "/dev/$dev" --no-user-interaction | grep -o "dm-[[:digit:]]*") + udisksctl mount -b "/dev/$dev_map" --no-user-interaction >/dev/null + exit_code="$?" + else + udisksctl mount -b "/dev/$dev" --no-user-interaction >/dev/null + exit_code="$?" + fi + fi + if [ $exit_code -eq 0 ]; then sleep 1 echo "/dev/$dev mounted to $(lsblk -n "/dev/$dev" -o MOUNTPOINT | sed "/^$/d")." fi diff --git a/nnn/.config/nnn/plugins/nuke b/nnn/.config/nnn/plugins/nuke index b3eafc8..dad566c 100755 --- a/nnn/.config/nnn/plugins/nuke +++ b/nnn/.config/nnn/plugins/nuke @@ -271,13 +271,13 @@ abspath() { listimages() { find -L "///${1%/*}" -maxdepth 1 -type f -print0 | grep -izZE '\.(jpe?g|png|gif|webp|tiff|bmp|ico|svg)$' | - sort -z | tee "$tmp" + sort -zV | tee "$tmp" } load_dir() { abspath "$2" tmp="${TMPDIR:-/tmp}/nuke_$$" - trap 'rm -f $tmp' EXIT + trap 'rm -f -- "$tmp"' EXIT count="$(listimages "$abs_target" | grep -a -m 1 -ZznF "$abs_target" | cut -d: -f1)" if [ -n "$count" ]; then @@ -402,7 +402,7 @@ handle_multimedia() { # "${FPATH}"; # then # convert -- "${preview_png}" "${IMAGE_CACHE_PATH}" \ - # && rm "${preview_png}" \ + # && rm -- "${preview_png}" \ # && exit 6 # else # exit 1 diff --git a/nnn/.config/nnn/plugins/organize b/nnn/.config/nnn/plugins/organize index fb70aaf..81cc9df 100755 --- a/nnn/.config/nnn/plugins/organize +++ b/nnn/.config/nnn/plugins/organize @@ -13,36 +13,36 @@ organize() { case "$(file -biL "$1")" in *video*) [ ! -d "Videos" ] && mkdir "Videos" - mv "$1" "Videos/$1" + mv -- "$1" "Videos/$1" printf "Moved %s to Videos\n" "$1" ;; *audio*) [ ! -d "Audio" ] && mkdir "Audio" - mv "$1" "Audio/$1" + mv -- "$1" "Audio/$1" printf "Moved %s to Audio\n" "$1" ;; *image*) [ ! -d "Images" ] && mkdir "Images" - mv "$1" "Images/$1" + mv -- "$1" "Images/$1" printf "Moved %s to Images\n" "$1" ;; *pdf*|*document*|*epub*|*djvu*|*cb*) [ ! -d "Documents" ] && mkdir "Documents" - mv "$1" "Documents/$1" + mv -- "$1" "Documents/$1" printf "Moved %s to Documents\n" "$1" ;; *text*) [ ! -d "Plaintext" ] && mkdir "Plaintext" - mv "$1" "Plaintext/$1" + mv -- "$1" "Plaintext/$1" printf "Moved %s to Plaintext\n" "$1" ;; *tar*|*xz*|*compress*|*7z*|*rar*|*zip*) [ ! -d "Archives" ] && mkdir "Archives" - mv "$1" "Archives/$1" + mv -- "$1" "Archives/$1" printf "Moved %s to Archives\n" "$1" ;; *binary*) [ ! -d "Binaries" ] && mkdir "Binaries" - mv "$1" "Binaries/$1" + mv -- "$1" "Binaries/$1" printf "Moved %s to Binaries\n" "$1" ;; esac } diff --git a/nnn/.config/nnn/plugins/pdfread b/nnn/.config/nnn/plugins/pdfread index 1e889be..9f65728 100755 --- a/nnn/.config/nnn/plugins/pdfread +++ b/nnn/.config/nnn/plugins/pdfread @@ -15,7 +15,7 @@ if [ -n "$1" ]; then pico2wave -w "$tmpf".wav -l en-GB "$(tr '\n' ' ' < "$tmpf".txt)" - rm "$tmpf".txt + rm -- "$tmpf".txt else pico2wave -w "$tmpf".wav -l en-GB "$(tr '\n' ' ' < "$1")" fi @@ -26,5 +26,5 @@ if [ -n "$1" ]; then # flat read but better quality # play -qV0 "$tmpf".wav treble 2 gain -l 2 - rm "$tmpf".wav + rm -- "$tmpf".wav fi diff --git a/nnn/.config/nnn/plugins/preview-tabbed b/nnn/.config/nnn/plugins/preview-tabbed index 5235c1e..ab5b2c1 100755 --- a/nnn/.config/nnn/plugins/preview-tabbed +++ b/nnn/.config/nnn/plugins/preview-tabbed @@ -4,7 +4,7 @@ # # Dependencies: # - tabbed (https://tools.suckless.org/tabbed): xembed host -# - xterm (or urxvt or st) : xembed client for text-based preview +# - xterm (or urxvt or st or alacritty) : xembed client for text-based preview # - mpv (https://mpv.io): xembed client for video/audio # - sxiv (https://github.com/muennich/sxiv) or, # - nsxiv (https://codeberg.org/nsxiv/nsxiv) : xembed client for images @@ -63,10 +63,15 @@ elif type urxvt >/dev/null 2>&1 ; then TERMINAL="urxvt -embed" elif type st >/dev/null 2>&1 ; then TERMINAL="st -w" +elif type alacritty >/dev/null 2>&1 ; then + TERMINAL="alacritty --embed" else echo "No xembed term found" >&2 fi +if type xdg-user-dir >/dev/null 2>&1 ; then + PICTURES_DIR=$(xdg-user-dir PICTURES) +fi term_nuke () { # $1 -> $XID, $2 -> $FILE @@ -90,7 +95,7 @@ start_tabbed () { read -r XID < "$FIFO" - rm "$FIFO" + rm -- "$FIFO" } get_viewer_pid () { @@ -175,7 +180,17 @@ previewer_loop () { fi ;; inode/directory) - $TERMINAL "$XID" -e nnn "$FILE" & + if [[ -n $PICTURES_DIR && "$FILE" == "$PICTURES_DIR"* ]] ; then + if type sxiv >/dev/null 2>&1 ; then + sxiv -te "$XID" "$FILE" & + elif type nsxiv >/dev/null 2>&1 ; then + nsxiv -te "$XID" "$FILE" & + else + $TERMINAL "$XID" -e nnn "$FILE" & + fi + else + $TERMINAL "$XID" -e nnn "$FILE" & + fi ;; text/*) if [ -x "$NUKE" ] ; then diff --git a/nnn/.config/nnn/plugins/preview-tui b/nnn/.config/nnn/plugins/preview-tui index f9a51ca..860a93a 100755 --- a/nnn/.config/nnn/plugins/preview-tui +++ b/nnn/.config/nnn/plugins/preview-tui @@ -1,4 +1,4 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash # Description: Terminal based file previewer # @@ -13,7 +13,7 @@ # - Windows Terminal (https://github.com/Microsoft/Terminal | https://aka.ms/terminal) with WSL, or # - $NNN_TERMINAL set to a terminal (it's xterm by default). # - less or $NNN_PAGER -# - tree or exa or ls +# - tree or exa/eza or (GNU) ls # - mediainfo or file # - mktemp # - unzip @@ -21,8 +21,12 @@ # - man # - optional: bsdtar or atool for additional archive preview # - optional: bat for code syntax highlighting -# - optional: ueberzug, kitty terminal, wezterm terminal, viu, catimg or chafa for images -# - optional: convert(ImageMagick) for playing gif preview (required for kitty image previews) +# - optional: ueberzug, kitty terminal, wezterm terminal, img2sixel, viu, catimg or chafa for images +# - optional: convert(ImageMagick) for playing gif preview (mandatory for kitty image previews) +# - optional: mpv for gif and video +# Also requires a terminal supporting the sixel (https://www.arewesixelyet.com/) +# or kitty (https://sw.kovidgoyal.net/kitty/graphics-protocol) video_output backends. +# Requires tmux compiled with `./configure --enable-sixel` if used. # - optional: ffmpegthumbnailer for video thumbnails (https://github.com/dirkvdb/ffmpegthumbnailer) # - optional: ffmpeg for audio thumbnails # - optional: libreoffce for opendocument/officedocument preview @@ -40,6 +44,7 @@ # - optional: pistol file viewer (https://github.com/doronbehar/pistol). # 1. install pistol # 2. set/export $NNN_PISTOL as 1 +# - optional: librsvg for rsvg-convert # # Usage: # You need to set a NNN_FIFO path and a key for the plugin with NNN_PLUG, @@ -61,10 +66,6 @@ # will try to use a kitty terminal split. And as a final fallback, a # different terminal window will be used ($NNN_TERMINAL). # -# Tmux, wezterm and kitty users can configure $NNN_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` @@ -72,111 +73,128 @@ # With ImageMagick installed, this terminal can use the icat kitten to display images. # Refer to kitty documentation for further details. # +# Users with both tmux and kitty can leverage image previews inside tmux with kitty's icat kitten +# - setup kitty as stated above +# - tmux >= v3.3a required +# - add the following to your tmux.conf: +# - `set -g allow-passthrough on` +# # Wezterm should work out of the box. If `NNN_PREVIEWIMGPROG` is not specified it will use # built in iTerm2 image protocol. # -# Iterm2 users are recommended to use viu to view images without getting pixelated. +# Note that GNU ls is used for its `--group-directories-first` flag. +# On MacOS this may be installed with `brew install coreutils`, or the flag can be removed. +# 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 automatically 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 +# When specifying a different terminal, additional arguments are supported. In particular, you can +# append a specific title to the terminal and set it to "nofocus" in your WM config. +# E.g for alacritty and i3, you can set $NNN_TERMINAL to 'alacritty --title preview-tui' and add +# 'no_focus [title="preview-tui"]' to your i3 config file. +# +# Shell: Bash (for environment manipulation through arrays) +# Authors: Todd Yamakawa, Léo Villeveygoux, @Recidiviste, Mario Ortiz Manero, Luuk van Baal, @WanderLanz, @flipflop133 -NNN_SPLIT=${NNN_SPLIT:-} # Set permanent split direction -NNN_TERMINAL=${NNN_TERMINAL:-} # Set external terminal to be used -NNN_SPLITSIZE=${NNN_SPLITSIZE:-50} # Set previewer split size percentage -TMPDIR=${TMPDIR:-/tmp} +# Configurable environment variables: +NNN_SPLIT=${NNN_SPLIT:-} # permanent split direction +NNN_TERMINAL=${NNN_TERMINAL:-} # external terminal to be used +NNN_SPLITSIZE=${NNN_SPLITSIZE:-50} # previewer split size percentage +TMPDIR=${TMPDIR:-/tmp} # location of temporary files +ENVVARS=( + "NNN_SCOPE=${NNN_SCOPE:-0}" # use scope + "NNN_PISTOL=${NNN_PISTOL:-0}" # use pistol + "NNN_ICONLOOKUP=${NNN_ICONLOOKUP:-0}" # use .iconlookup + "NNN_PAGER=${NNN_PAGER:-less -P?n -R -C}" # pager options + "NNN_BATTHEME=${NNN_BATTHEME:-ansi}" # bat theme + "NNN_BATSTYLE=${NNN_BATSTYLE:-numbers}" # bat style + "NNN_PREVIEWWIDTH=${NNN_PREVIEWWIDTH:-1920}" # width of generated preview images + "NNN_PREVIEWHEIGHT=${NNN_PREVIEWHEIGHT:-1080}" # height of generated preview images + "NNN_PREVIEWDIR=${NNN_PREVIEWDIR:-$TMPDIR/nnn/previews}" # location of generated preview images + "NNN_PREVIEWIMGPROG=${NNN_PREVIEWIMGPROG:-}" # program used to preview images + "NNN_PREVIEWVIDEO=${NNN_PREVIEWVIDEO:-}" # mpv backend used to preview video +) +# Non-configurable environment variables NNN_PARENT=${NNN_FIFO#*.} [ "$NNN_PARENT" -eq "$NNN_PARENT" ] 2>/dev/null || NNN_PARENT="" # Make empty if non-numeric -ENVVARS=" -PWD=$PWD -PATH=$PATH -PREVIEW_MODE=$2 -NNN_FIFO=$NNN_FIFO -NNN_SCOPE=${NNN_SCOPE:-0} -NNN_PISTOL=${NNN_PISTOL:-0} -NNN_ICONLOOKUP=${NNN_ICONLOOKUP:-0} -NNN_PAGER=${NNN_PAGER:-less -P?n -R} -NNN_BATTHEME=${NNN_BATTHEME:-ansi} -NNN_BATSTYLE=${NNN_BATSTYLE:-numbers} -NNN_PREVIEWWIDTH=${NNN_PREVIEWWIDTH:-1920} -NNN_PREVIEWHEIGHT=${NNN_PREVIEWHEIGHT:-1080} -NNN_PREVIEWDIR=${NNN_PREVIEWDIR:-$TMPDIR/nnn/previews} -NNN_PREVIEWIMGPROG=${NNN_PREVIEWIMGPROG:-} -FIFOPID=$TMPDIR/nnn-preview-tui-fifopid.$NNN_PARENT -FIFOPATH=$TMPDIR/nnn-preview-tui-fifo.$NNN_PARENT -PREVIEWPID=$TMPDIR/nnn-preview-tui-previewpid.$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" - -if [ -e "${TMUX%%,*}" ] && tmux -V | grep -q '[ -][3456789]\.'; then - NNN_TERMINAL=tmux -elif [ -n "$KITTY_LISTEN_ON" ]; then - NNN_TERMINAL=kitty -elif [ -n "$WEZTERM_PANE" ]; then - NNN_TERMINAL=wezterm -elif [ -z "$NNN_TERMINAL" ] && [ "$TERM_PROGRAM" = "iTerm.app" ]; then - NNN_TERMINAL=iterm -elif [ -n "$WT_SESSION" ]; then - NNN_TERMINAL=winterm -else - NNN_TERMINAL="${NNN_TERMINAL:-xterm}" -fi - -if [ -z "$NNN_SPLIT" ] && [ $(($(tput lines) * 2)) -gt "$(tput cols)" ]; then - NNN_SPLIT='h' -elif [ "$NNN_SPLIT" != 'h' ]; then - NNN_SPLIT='v' -fi - -ENVVARS="$ENVVARS -NNN_SPLIT=$NNN_SPLIT -NNN_TERMINAL=$NNN_TERMINAL" -IFS=' -' -for env in $ENVVARS; do - export "${env?}" - case "$NNN_TERMINAL" in - tmux) ENVSTRING="$ENVSTRING -e '$env'" ;; - kitty) ENVSTRING="$ENVSTRING --env '$env'" ;; - winterm|iterm) ENVSTRING="$ENVSTRING \\\"$env\\\"" ;; - *) ENVSTRING="$ENVSTRING $env";; - esac -done; unset IFS +ENVVARS+=( + "PWD=$PWD" + "PATH=$PATH" + "NNN_FIFO=$NNN_FIFO" + "FIFOPID=$TMPDIR/nnn-preview-tui-fifopid.$NNN_PARENT" + "FIFOPATH=$TMPDIR/nnn-preview-tui-fifo.$NNN_PARENT" + "PREVIEWPID=$TMPDIR/nnn-preview-tui-previewpid.$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" +) trap '' PIPE exists() { type "$1" >/dev/null 2>&1 ;} pkill() { command pkill "$@" >/dev/null 2>&1 ;} -prompt() { printf "%b" "$@"; cfg=$(stty -g); stty raw -echo; head -c 1; stty "$cfg" ;} +prompt() { clear; printf "%b" "$@"; cfg=$(stty -g); stty raw -echo; head -c 1; stty "$cfg" ;} pidkill() { - if [ -f "$1" ]; then - PID="$(cat "$1" 2>/dev/null)" || return 1 - kill "$PID" >/dev/null 2>&1 - RET=$? - wait "$PID" 2>/dev/null - return $RET - fi - return 1 + if [ -f "$1" ]; then + PID="$(cat "$1" 2>/dev/null)" || return 1 + kill "$PID" >/dev/null 2>&1 + RET=$? + wait "$PID" 2>/dev/null + return $RET + fi + return 1 } start_preview() { + if [ -e "${TMUX%%,*}" ] && tmux -V | grep -q '[ -][3456789]\.'; then + NNN_TERMINAL=tmux + exists mpv && tmux display -p '#{client_termfeatures}' | grep -q 'sixel' && ENVVARS+=("NNN_PREVIEWVIDEO=sixel") + elif [ -n "$KITTY_LISTEN_ON" ]; then + NNN_TERMINAL=kitty + exists mpv && ENVVARS+=("NNN_PREVIEWVIDEO=kitty") + elif [ -n "$WEZTERM_PANE" ]; then + NNN_TERMINAL=wezterm + exists mpv && ENVVARS+=("NNN_PREVIEWVIDEO=kitty") + elif [ -z "$NNN_TERMINAL" ] && [ "$TERM_PROGRAM" = "iTerm.app" ]; then + NNN_TERMINAL=iterm + exists mpv && ENVVARS+=("NNN_PREVIEWVIDEO=sixel") + elif [ -n "$WT_SESSION" ]; then + NNN_TERMINAL=winterm + else + NNN_TERMINAL="${NNN_TERMINAL:-xterm}" + fi + + if [ -z "$NNN_SPLIT" ] && [ $(($(tput lines) * 2)) -gt "$(tput cols)" ]; then + NNN_SPLIT='h' + elif [ "$NNN_SPLIT" != 'h' ]; then + NNN_SPLIT='v' + fi + + ENVVARS+=("NNN_TERMINAL=$NNN_TERMINAL" "NNN_SPLIT=$NNN_SPLIT" "QLPATH=$2" "PREVIEW_MODE=1") + case "$NNN_TERMINAL" in + iterm|winterm) # has to run in separate shell command: escape + ENVVARS=("${ENVVARS[@]/#/\\\"}") + ENVVARS=("${ENVVARS[@]/%/\\\"}") + command="$SHELL -c 'env ${ENVVARS[*]} \\\"$0\\\" \\\"$1\\\"'" ;; + esac + case "$NNN_TERMINAL" in tmux) # tmux splits are inverted + ENVVARS=("${ENVVARS[@]/#/-e}") if [ "$NNN_SPLIT" = "v" ]; then split="h"; else split="v"; fi - eval tmux split-window "$ENVSTRING" -d"$split" -p"$NNN_SPLITSIZE" "$0" "$1" 1 ;; + tmux split-window -l"$NNN_SPLITSIZE"% "${ENVVARS[@]}" -d"$split" -p"$NNN_SPLITSIZE" "$0" "$1" ;; kitty) # Setting the layout for the new window. It will be restored after the script ends. + ENVVARS=("${ENVVARS[@]/#/--env=}") kitty @ goto-layout splits # Trying to use kitty's integrated window management as the split window. - eval kitty @ launch --no-response --title "preview-tui" --keep-focus \ - --cwd "$PWD" "$ENVSTRING" --location "${NNN_SPLIT}split" "$0" "$1" 1 ;; + kitty @ launch --no-response --title "preview-tui" --keep-focus \ + --cwd "$PWD" "${ENVVARS[@]}" --location "${NNN_SPLIT}split" "$0" "$1" ;; wezterm) + export "${ENVVARS[@]}" if [ "$NNN_SPLIT" = "v" ]; then split="--horizontal"; else split="--bottom"; fi - wezterm cli split-pane --cwd "$PWD" $split "$0" "$1" 1 >/dev/null + wezterm cli split-pane --cwd "$PWD" $split --percent "$NNN_SPLITSIZE" "$0" "$1" >/dev/null wezterm cli activate-pane-direction Prev ;; iterm) - command="$SHELL -c 'cd $PWD; env $ENVSTRING $0 $1 1'" if [ "$NNN_SPLIT" = "h" ]; then split="horizontally"; else split="vertically"; fi osascript <<-EOF tell application "iTerm" @@ -188,17 +206,18 @@ EOF ;; winterm) if [ "$NNN_SPLIT" = "h" ]; then split="H"; else split="V"; fi - cmd.exe /c wt -w 0 sp -$split -s"0.$NNN_SPLITSIZE" bash -c "cd $PWD \; \ - env $ENVSTRING QLPATH=$2 $0 $1 1" \; -w 0 mf previous 2>/dev/null ;; + wt -w 0 sp -$split -s"0.$NNN_SPLITSIZE" "$command" \; -w 0 mf previous 2>/dev/null ;; *) if [ -n "$2" ]; then - env "$ENVSTRING" QUICKLOOK=1 QLPATH="$2" "$0" "$1" 1 & + env "${ENVVARS[@]}" QUICKLOOK=1 "$0" "$1" & else - env "$ENVSTRING" "$NNN_TERMINAL" -e "$0" "$1" 1 & + # shellcheck disable=SC2086 # (allow arguments) + env "${ENVVARS[@]}" $NNN_TERMINAL -e "$0" "$1" & fi ;; esac } toggle_preview() { + export "${ENVVARS[@]}" if exists QuickLook.exe; then QLPATH="QuickLook.exe" elif exists Bridge.exe; then @@ -241,7 +260,7 @@ fifo_pager() { fi ) - rm "$FIFOPATH" + rm -- "$FIFOPATH" } # Binary file: show file info inside the pager @@ -350,7 +369,9 @@ preview_file() { 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 + fifo_pager exa -T --group-directories-first --colour=always -L 3 + elif exists eza; then # eza is a community fork of exa (exa is unmaintained) + fifo_pager eza -T --group-directories-first --colour=always -L 3 else fifo_pager ls -F --group-directories-first --color=always fi @@ -365,6 +386,9 @@ preview_file() { generate_preview() { if [ -n "$QLPATH" ] && stat "$3"; then f="$(wslpath -w "$3")" && "$QLPATH" "$f" & + elif [ -n "$NNN_PREVIEWVIDEO" ] && [[ "$4" == +(gif|video) ]]; then + [ "$4" = "video" ] && args=(--start=10% --length=4) || args=() + video_preview "$1" "$2" "$3" "${args[@]}" && return elif [ ! -f "$NNN_PREVIEWDIR/$3.jpg" ] || [ -n "$(find -L "$3" -newer "$NNN_PREVIEWDIR/$3.jpg")" ]; then mkdir -p "$NNN_PREVIEWDIR/${3%/*}" case $4 in @@ -388,25 +412,30 @@ generate_preview() { done & printf "%s" "$!" > "$PREVIEWPID" return + elif [ -n "$NNN_PREVIEWVIDEO" ]; then + video_preview "$1" "$2" "$3" && return else - image_preview "$1" "$2" "$3" - return + image_preview "$1" "$2" "$3" && return fi ;; - image) if exists convert; then + image) if exists rsvg-convert && [[ "${3##*.}" == "svg" ]]; then + rsvg-convert -a -w "$NNN_PREVIEWWIDTH" -h "$NNN_PREVIEWHEIGHT" -f png -o "$NNN_PREVIEWDIR/$3.png" "$3" + elif 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" ;; + 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 -m -s0 -i "$3" -o "$NNN_PREVIEWDIR/$3.jpg" || rm "$NNN_PREVIEWDIR/$3.jpg" ;; + video) video_preview "$1" "$2" "$3" && return ;; esac fi if [ -f "$NNN_PREVIEWDIR/$3.jpg" ]; then image_preview "$1" "$2" "$NNN_PREVIEWDIR/$3.jpg" + elif [[ "${3##*.}" == "svg" ]] && [ -f "$NNN_PREVIEWDIR/$3.png" ]; then + image_preview "$1" "$2" "$NNN_PREVIEWDIR/$3.png" else fifo_pager print_bin_info "$3" fi @@ -415,25 +444,39 @@ generate_preview() { image_preview() { clear exec >/dev/tty - if [ "$NNN_TERMINAL" = "kitty" ]; then - # Kitty terminal users can use the native image preview method + if [ "$NNN_TERMINAL" = "kitty" ] && [[ "$NNN_PREVIEWIMGPROG" == +(|icat) ]]; then kitty +kitten icat --silent --scale-up --place "$1"x"$2"@0x0 --transfer-mode=stream --stdin=no "$3" & - elif [ "$NNN_TERMINAL" = "wezterm" ] && [ -z "$NNN_PREVIEWIMGPROG" ]; then + elif [ "$NNN_TERMINAL" = "tmux" ] && [[ -n "$KITTY_LISTEN_ON" ]] && [[ "$NNN_PREVIEWIMGPROG" == +(|icat) ]]; then + kitty +kitten icat --silent --scale-up --place "$(($1 - 1))x$(($2 - 1))"@0x0 --transfer-mode=memory --stdin=no "$3" & + elif [ "$NNN_TERMINAL" = "wezterm" ] && [[ "$NNN_PREVIEWIMGPROG" == +(|imgcat) ]]; then wezterm imgcat "$3" & - elif exists ueberzug && { [ -z "$NNN_PREVIEWIMGPROG" ] || [ "$NNN_PREVIEWIMGPROG" = "ueberzug" ] ;}; then + elif exists ueberzug && [[ "$NNN_PREVIEWIMGPROG" == +(|ueberzug) ]]; then ueberzug_layer "$1" "$2" "$3" && return - elif exists catimg && { [ -z "$NNN_PREVIEWIMGPROG" ] || [ "$NNN_PREVIEWIMGPROG" = "catimg" ] ;}; then + elif exists catimg && [[ "$NNN_PREVIEWIMGPROG" == +(|catimg) ]]; then catimg "$3" & - elif exists viu && { [ -z "$NNN_PREVIEWIMGPROG" ] || [ "$NNN_PREVIEWIMGPROG" = "viu" ] ;}; then + elif exists viu && [[ "$NNN_PREVIEWIMGPROG" == +(|viu) ]]; then viu -t "$3" & - elif exists chafa && { [ -z "$NNN_PREVIEWIMGPROG" ] || [ "$NNN_PREVIEWIMGPROG" = "chafa" ] ;}; then + elif exists chafa && [[ "$NNN_PREVIEWIMGPROG" == +(|chafa) ]]; then chafa "$3" & + elif exists img2sixel && [[ "$NNN_PREVIEWIMGPROG" == +(|img2sixel) ]]; then + img2sixel -g "$3" & else fifo_pager print_bin_info "$3" && return fi printf "%s" "$!" > "$PREVIEWPID" } +video_preview() { + clear + exec >/dev/tty + if [ -n "$NNN_PREVIEWVIDEO" ]; then + mpv --no-config --really-quiet --vo="$NNN_PREVIEWVIDEO" --profile=sw-fast --loop-file --no-audio "$4" "$3" & + else + ffmpegthumbnailer -m -s0 -i "$3" -o "$NNN_PREVIEWDIR/$3.jpg" || rm -- "$NNN_PREVIEWDIR/$3.jpg" & + 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'\ @@ -469,25 +512,25 @@ preview_fifo() { } if [ "$PREVIEW_MODE" -eq 1 ] 2>/dev/null; then - if [ "$NNN_TERMINAL" != "kitty" ] && exists ueberzug; then + if exists ueberzug && [ "$NNN_TERMINAL" != "kitty" ] && [[ "$NNN_PREVIEWIMGPROG" == +(|ueberzug) ]]; then mkfifo "$FIFO_UEBERZUG" tail --follow "$FIFO_UEBERZUG" | ueberzug layer --silent --parser json & fi preview_file "$PWD/$1" - preview_fifo & + preview_fifo & WAITPID=$! 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 + trap 'winch_handler' WINCH + trap 'rm -- "$PREVIEWPID" "$CURSEL" "$FIFO_UEBERZUG" "$FIFOPID" "$POSOFFSET" 2>/dev/null' INT HUP EXIT + while kill -s 0 $WAITPID; do + wait $WAITPID 2>/dev/null + done exit 0 else if [ ! -r "$NNN_FIFO" ]; then - clear prompt "No FIFO available! (\$NNN_FIFO='$NNN_FIFO')\nPlease read Usage in '$0'." elif [ "$KITTY_WINDOW_ID" ] && [ -z "$TMUX" ] && [ -z "$KITTY_LISTEN_ON" ]; then - clear prompt "\$KITTY_LISTEN_ON not set!\nPlease read Usage in '$0'." else toggle_preview "$1" & diff --git a/nnn/.config/nnn/plugins/upload b/nnn/.config/nnn/plugins/upload index 4948587..e225d20 100755 --- a/nnn/.config/nnn/plugins/upload +++ b/nnn/.config/nnn/plugins/upload @@ -1,12 +1,11 @@ #!/usr/bin/env sh -# Description: Selections are uploaded using Firefox Send +# Description: Selections are archived into a tar file (uncompressed) and uploaded to file.io # For single files: -# Upload to Firefox Send if ffsend is found, else -# Paste contents of a text a file http://ix.io +# Paste contents of a text file to http://ix.io # Upload a binary file to file.io # -# Dependencies: ffsend (https://github.com/timvisee/ffsend), curl, jq, tr +# Dependencies: curl, jq, tar, file with `--mime-type` support # # Note: Binary file set to expire after a week # @@ -15,30 +14,24 @@ selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection} if [ -s "$selection" ]; then - if type ffsend >/dev/null 2>&1; then - # File name will be randomized foo.tar - xargs -0 < "$selection" ffsend u - else - printf "ffsend is required to upload selection." - fi + xargs -0 tar -c < "$selection" | \ + curl -s -F "file=@/dev/stdin;filename=selection.tar" 'https://file.io/?expires=1w' | \ + jq '.link' | tr -d '"' # Clear selection printf "-" > "$NNN_PIPE" else if [ -n "$1" ] && [ -s "$1" ]; then - if type ffsend >/dev/null 2>&1; then - ffsend -fiq u "$1" - elif [ "$(mimetype --output-format %m "$1" | awk -F '/' '{print $1}')" = "text" ]; then - curl -F "f:1=@$1" ix.io - else - # Upload the file, show the download link and wait till user presses any key - curl -s -F "file=@$1" https://file.io/?expires=1w | jq '.link' | tr -d '"' - - # To write download link to "$1".loc and exit - # curl -s -F "file=@$1" https://file.io/?expires=1w -o `basename "$1"`.loc - fi + if file --mime-type "$1" | grep -q -F "text/"; then + curl -F "file=@$1" https://0x0.st + else + # Upload the file, show the download link and wait till user presses any key + curl -s -F "file=@$1" https://file.io/?expires=1w | jq '.link' | tr -d '"' + # To write download link to "$1".loc and exit + # curl -s -F "file=@$1" https://file.io/?expires=1w -o `basename "$1"`.loc + fi else - printf "empty file!" + printf "empty file!" fi fi diff --git a/nnn/.config/nnn/plugins/wallpaper b/nnn/.config/nnn/plugins/wallpaper index 2017fbd..966e7ce 100755 --- a/nnn/.config/nnn/plugins/wallpaper +++ b/nnn/.config/nnn/plugins/wallpaper @@ -8,11 +8,19 @@ # Shell: POSIX compliant # Author: juacq97 +resp= + if [ -n "$1" ]; then if [ "$(file --mime-type "$1" | awk '{print $NF}' | awk -F '/' '{print $1}')" = "image" ]; then if [ "$XDG_SESSION_TYPE" = "x11" ]; then if type nitrogen >/dev/null 2>&1; then - nitrogen --set-zoom-fill --save "$1" + printf "Set to full desktop or a specific monitors? [0, 1, etc. Defaults to full.]" + read -r resp + if [ "$resp" != "" ]; then + nitrogen --set-zoom-fill --save "$1" --head="$resp" + else + nitrogen --set-zoom-fill --save "$1" + fi elif type wal >/dev/null 2>&1; then wal -i "$1" else -- cgit v1.2.3