aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xfiles/.config/nnn/plugins/.iconlookup2
-rwxr-xr-xfiles/.config/nnn/plugins/.nmv12
-rwxr-xr-xfiles/.config/nnn/plugins/.npreview135
-rwxr-xr-xfiles/.config/nnn/plugins/autojump28
-rwxr-xr-xfiles/.config/nnn/plugins/bulknew2
-rwxr-xr-xfiles/.config/nnn/plugins/cbcopy-mac16
-rwxr-xr-xfiles/.config/nnn/plugins/cbpaste-mac24
-rwxr-xr-xfiles/.config/nnn/plugins/chksum6
-rwxr-xr-xfiles/.config/nnn/plugins/diffs2
-rwxr-xr-xfiles/.config/nnn/plugins/dragdrop88
-rwxr-xr-xfiles/.config/nnn/plugins/dups6
-rwxr-xr-xfiles/.config/nnn/plugins/finder2
-rwxr-xr-xfiles/.config/nnn/plugins/fixname2
-rwxr-xr-xfiles/.config/nnn/plugins/fzcd2
-rwxr-xr-xfiles/.config/nnn/plugins/fzhist19
-rwxr-xr-xfiles/.config/nnn/plugins/fzopen42
-rwxr-xr-xfiles/.config/nnn/plugins/fzplug2
-rwxr-xr-xfiles/.config/nnn/plugins/getplugs4
-rwxr-xr-xfiles/.config/nnn/plugins/gpgs42
-rwxr-xr-xfiles/.config/nnn/plugins/gpgv28
-rwxr-xr-xfiles/.config/nnn/plugins/imgur2
-rwxr-xr-xfiles/.config/nnn/plugins/imgview2
-rwxr-xr-xfiles/.config/nnn/plugins/mimelist12
-rwxr-xr-xfiles/.config/nnn/plugins/nbak4
-rwxr-xr-xfiles/.config/nnn/plugins/nmount82
-rwxr-xr-xfiles/.config/nnn/plugins/nuke12
-rwxr-xr-xfiles/.config/nnn/plugins/organize14
-rwxr-xr-xfiles/.config/nnn/plugins/pdfread4
-rwxr-xr-xfiles/.config/nnn/plugins/preview-tabbed32
-rwxr-xr-xfiles/.config/nnn/plugins/preview-tui150
-rwxr-xr-xfiles/.config/nnn/plugins/renamer13
-rwxr-xr-xfiles/.config/nnn/plugins/stats71
-rwxr-xr-xfiles/.config/nnn/plugins/suedit6
-rwxr-xr-xfiles/.config/nnn/plugins/tnp47
-rwxr-xr-xfiles/.config/nnn/plugins/upload37
-rwxr-xr-xfiles/.config/nnn/plugins/wallpaper10
-rwxr-xr-xfiles/.config/nnn/plugins/x2sel14
-rwxr-xr-xfiles/.config/nnn/plugins/xdgdefault5
38 files changed, 784 insertions, 197 deletions
diff --git a/files/.config/nnn/plugins/.iconlookup b/files/.config/nnn/plugins/.iconlookup
index 49b4764..453110b 100755
--- a/files/.config/nnn/plugins/.iconlookup
+++ b/files/.config/nnn/plugins/.iconlookup
@@ -329,7 +329,7 @@ awk 'BEGIN {
if ($0 ~/^\.$/)
next
ent = ($0 ~/^\.\//) ? substr($0, 3, length($0) - 2) : $0
- ext = $NF
+ ext = ($NF ~/\*$/) ? substr($NF, 1, length($NF) - 1) : $NF
# Print icons, set color and bold directories by using ansi escape codes
if (ext in icons)
diff --git a/files/.config/nnn/plugins/.nmv b/files/.config/nnn/plugins/.nmv
index eaebda6..bc3727f 100755
--- a/files/.config/nnn/plugins/.nmv
+++ b/files/.config/nnn/plugins/.nmv
@@ -31,8 +31,10 @@ case "$NNN_TRASH" in
RM_UTIL="trash-put" ;;
2)
RM_UTIL="gio trash" ;;
+ "")
+ RM_UTIL="rm -ri --" ;;
*)
- RM_UTIL="rm -ri" ;;
+ RM_UTIL="$NNN_TRASH" ;;
esac
exit_status=0
@@ -64,7 +66,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 +124,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
@@ -133,6 +135,7 @@ while read -r num name; do
for key in "${!items[@]}"; do
if [ "${items[$key]}" = "$name" ]; then
+ # shellcheck disable=2004
items[$key]="$tmp"
fi
done
@@ -142,12 +145,13 @@ 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
if [ -d "$name" ]; then
for key in "${!items[@]}"; do
+ # shellcheck disable=2004
items[$key]=$(printf "%s" "${items[$key]}" | sed "s|^$src\(\$\|\/\)|$name\1|")
done
diff --git a/files/.config/nnn/plugins/.npreview b/files/.config/nnn/plugins/.npreview
new file mode 100755
index 0000000..d63db1b
--- /dev/null
+++ b/files/.config/nnn/plugins/.npreview
@@ -0,0 +1,135 @@
+#!/usr/bin/env sh
+
+# Description: Preview plugin for nnn's built-in preview pane
+# Auto-detected from plugins dir
+# Usage: .npreview <filepath> <width> <height>
+# All dependencies optional — graceful fallback to head/file/strings
+
+set -euf
+
+F="$1"
+W="${2:-80}"
+H="${3:-25}"
+ext="${F##*.}"
+ext="$(printf "%s" "$ext" | tr '[:upper:]' '[:lower:]')"
+
+has() { type "$1" >/dev/null 2>&1; }
+hd() { head -n "$H"; }
+
+# --- Handlers ---
+
+show_dir() {
+ has tree && { tree -L 1 -n --dirsfirst --noreport "$F" | hd; return; }
+ find "$F" -maxdepth 1 -print 2>/dev/null | hd
+}
+
+show_text() {
+ has bat && { bat --style=plain --color=never --paging=never --line-range=":${H}" -- "$F" 2>/dev/null; return; }
+ has batcat && { batcat --style=plain --color=never --paging=never --line-range=":${H}" -- "$F" 2>/dev/null; return; }
+ head -n "$H" "$F"
+}
+
+show_pdf() {
+ has pdftotext && { pdftotext -l 1 -nopgbrk -q -- "$F" - 2>/dev/null | hd; return; }
+ has mutool && { mutool draw -F txt -i -- "$F" 1 2>/dev/null | hd; return; }
+ show_meta
+}
+
+show_archive() {
+ case "$ext" in
+ rar) has unrar && { unrar lt -p- -- "$F" 2>/dev/null | hd; return; } ;;
+ 7z) has 7z && { 7z l -p -- "$F" 2>/dev/null | hd; return; } ;;
+ esac
+ has atool && { atool --list -- "$F" 2>/dev/null | hd; return; }
+ has bsdtar && { bsdtar --list --file "$F" 2>/dev/null | hd; return; }
+ has tar && { tar tf "$F" 2>/dev/null | hd; return; }
+ has unzip && [ "$ext" = "zip" ] && { unzip -l "$F" 2>/dev/null | hd; return; }
+ printf "[archive %s]\n" "$(du -h "$F" 2>/dev/null | cut -f1)"
+}
+
+show_image() {
+ has img2txt && { img2txt --gamma=0.6 --width="$W" -- "$F" 2>/dev/null | hd; return; }
+ show_meta
+}
+
+show_meta() {
+ has exiftool && { exiftool "$F" 2>/dev/null | hd; return; }
+ has mediainfo && { mediainfo "$F" 2>/dev/null | hd; return; }
+ has file && { file -b "$F"; return; }
+ printf "[no metadata tool]\n"
+}
+
+show_json() {
+ has jq && { head -c 65536 "$F" | jq --monochrome-output . 2>/dev/null | hd; return; }
+ has python3 && { head -c 65536 "$F" | python3 -m json.tool 2>/dev/null | hd; return; }
+ show_text
+}
+
+show_md() {
+ has glow && { glow -s notty "$F" 2>/dev/null | hd; return; }
+ has lowdown && { lowdown -Tterm "$F" 2>/dev/null | hd; return; }
+ show_text
+}
+
+show_html() {
+ has w3m && { w3m -dump "$F" 2>/dev/null | hd; return; }
+ has lynx && { lynx -dump -- "$F" 2>/dev/null | hd; return; }
+ show_text
+}
+
+show_elf() {
+ has readelf && { readelf -h "$F" 2>/dev/null | hd; return; }
+ has objdump && { objdump -f "$F" 2>/dev/null | hd; return; }
+ has file && file -b "$F"
+}
+
+show_doc() {
+ has odt2txt && { odt2txt "$F" 2>/dev/null | hd; return; }
+ show_meta
+}
+
+show_bin() {
+ has strings && { printf "[binary]\n"; strings "$F" 2>/dev/null | hd; return; }
+ printf "[binary %s]\n" "$(du -h "$F" 2>/dev/null | cut -f1)"
+}
+
+# --- Directory ---
+[ -d "$F" ] && { show_dir; exit 0; }
+
+# --- Dispatch by extension ---
+case "$ext" in
+ a|ace|alz|arc|arj|bz|bz2|cab|cpio|deb|gz|jar|lha|lz|lzh|lzma|lzo|\
+ rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tz|tzo|war|xpi|xz|z|zip|rar|7z|zst)
+ show_archive; exit 0 ;;
+ pdf) show_pdf; exit 0 ;;
+ md|mkd|markdown) show_md; exit 0 ;;
+ htm|html|xhtml) show_html; exit 0 ;;
+ json) show_json; exit 0 ;;
+ odt|ods|odp|sxw) show_doc; exit 0 ;;
+ torrent) has transmission-show && { transmission-show -- "$F" 2>/dev/null | hd; exit 0; } ;;
+ sqlite|sqlite3|db) has sqlite3 && { printf ".tables\n" | sqlite3 "$F" 2>/dev/null | hd; exit 0; } ;;
+ o|so|dylib) show_elf; exit 0 ;;
+ c|cc|cpp|h|hpp|rs|go|py|rb|js|ts|java|sh|bash|zsh|pl|lua|vim|el|\
+ css|scss|yaml|yml|toml|ini|conf|xml|sql|diff|patch|awk|sed|make)
+ show_text; exit 0 ;;
+esac
+
+# --- Dispatch by mime type ---
+has file || { show_text; exit 0; }
+mime="$(file -bL --mime-type -- "$F" 2>/dev/null)"
+
+case "$mime" in
+ text/*|*/xml) show_text ;;
+ application/json) show_json ;;
+ application/pdf) show_pdf ;;
+ application/zip|application/x-tar|application/x-rar*|\
+ application/x-7z*|application/x-bzip*|application/x-xz|\
+ application/x-compress*|application/gzip|application/zstd)
+ show_archive ;;
+ image/*) show_image ;;
+ audio/*|video/*) show_meta ;;
+ application/x-executable|application/x-sharedlib|application/x-pie-executable|\
+ application/x-object) show_elf ;;
+ application/vnd.openxmlformats*|application/vnd.oasis.opendocument*) show_doc ;;
+ *) show_bin ;;
+esac
diff --git a/files/.config/nnn/plugins/autojump b/files/.config/nnn/plugins/autojump
index 6a24a52..795c434 100755
--- a/files/.config/nnn/plugins/autojump
+++ b/files/.config/nnn/plugins/autojump
@@ -15,7 +15,7 @@
# to make z.lua work, you need to set $NNN_ZLUA to the path of script z.lua
#
# Shell: POSIX compliant
-# Authors: Marty Buchaus, Dave Snider, Tim Adler, Nick Waywood
+# Authors: Marty Buchaus, Dave Snider, Tim Adler, Nick Waywood, Markus Meier
if [ ! -p "$NNN_PIPE" ]; then
printf 'ERROR: NNN_PIPE is not set!'
@@ -24,33 +24,35 @@ if [ ! -p "$NNN_PIPE" ]; then
fi
if type jump >/dev/null 2>&1; then
- printf "jump to : "
+ printf "jump to: "
IFS= read -r line
# shellcheck disable=SC2086
odir="$(jump cd ${line})"
printf "%s" "0c$odir" > "$NNN_PIPE"
elif type autojump >/dev/null 2>&1; then
- printf "jump to : "
+ printf "jump to: "
read -r dir
odir="$(autojump "$dir")"
printf "%s" "0c$odir" > "$NNN_PIPE"
elif type zoxide >/dev/null 2>&1; then
if type fzf >/dev/null 2>&1; then
- odir="$(zoxide query -i --)"
- printf "%s" "0c$odir" > "$NNN_PIPE"
+ odir="$(zoxide query -i --)"
+ printf "%s" "0c$odir" > "$NNN_PIPE"
else
- printf "jump to : "
- read -r dir
- odir="$(zoxide query -- "$dir")"
- printf "%s" "0c$odir" > "$NNN_PIPE"
+ printf "jump to: "
+ read -r dir
+ odir="$(zoxide query -- "$dir")"
+ printf "%s" "0c$odir" > "$NNN_PIPE"
fi
elif type lua >/dev/null 2>&1 && [ -n "$NNN_ZLUA" ]; then
- printf "jump to : "
- read -r line
if type fzf >/dev/null 2>&1; then
- odir="$(lua "$NNN_ZLUA" -l "$line" | fzf --nth 2.. --reverse --inline-info --tac +s -e --height 35%)"
- printf "%s" "0c$(echo "$odir" | awk '{print $2}')" > "$NNN_PIPE"
+ odir="$(lua "$NNN_ZLUA" -l \
+ | awk '{print $2}' \
+ | fzf --nth -1 --delimiter=/ --reverse --inline-info --tac +s -e --height 35%)"
+ printf "0c%s" "$odir" > "$NNN_PIPE"
else
+ printf "jump to: "
+ read -r line
odir="$(lua "$NNN_ZLUA" -e "$line")"
printf "%s" "0c$odir" > "$NNN_PIPE"
fi
diff --git a/files/.config/nnn/plugins/bulknew b/files/.config/nnn/plugins/bulknew
index 64331e4..7780961 100755
--- a/files/.config/nnn/plugins/bulknew
+++ b/files/.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/files/.config/nnn/plugins/cbcopy-mac b/files/.config/nnn/plugins/cbcopy-mac
new file mode 100755
index 0000000..a117a72
--- /dev/null
+++ b/files/.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/files/.config/nnn/plugins/cbpaste-mac b/files/.config/nnn/plugins/cbpaste-mac
new file mode 100755
index 0000000..5edf9c6
--- /dev/null
+++ b/files/.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/files/.config/nnn/plugins/chksum b/files/.config/nnn/plugins/chksum
index 9441cc1..68aeec4 100755
--- a/files/.config/nnn/plugins/chksum
+++ b/files/.config/nnn/plugins/chksum
@@ -48,7 +48,7 @@ fi
if [ "$resp" = "s" ]; then
checksum_type
- sed 's|'"$PWD/"'||g' < "$selection" | xargs -0 -I{} ${chsum}sum {} > "checksum_$(date '+%Y%m%d%H%M').$chsum"
+ sed 's|'"$PWD/"'||g' < "$selection" | xargs -0 -I{} "${chsum}sum" {} > "checksum_$(date '+%Y%m%d%H%M').$chsum"
# Clear selection
if [ -p "$NNN_PIPE" ]; then
@@ -66,10 +66,10 @@ elif [ -n "$1" ]; then
done
checksum_type
file=$(basename "$1").$chsum
- ${chsum}sum "$1" > "$file"
+ "${chsum}"sum "$1" > "$file"
elif [ -d "$1" ]; then
checksum_type
file=$(basename "$1").$chsum
- find "$1" -type f -exec ${chsum}sum "{}" + > "$file"
+ find "$1" -type f -exec "${chsum}sum" "{}" + > "$file"
fi
fi
diff --git a/files/.config/nnn/plugins/diffs b/files/.config/nnn/plugins/diffs
index 0464781..16adc4b 100755
--- a/files/.config/nnn/plugins/diffs
+++ b/files/.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/files/.config/nnn/plugins/dragdrop b/files/.config/nnn/plugins/dragdrop
index 812f970..01e4d19 100755
--- a/files/.config/nnn/plugins/dragdrop
+++ b/files/.config/nnn/plugins/dragdrop
@@ -1,11 +1,12 @@
#!/usr/bin/env sh
-
# Description: Open a Drag and drop window, to drop files onto other programs.
# Also provides drag and drop window for files.
#
-# Dependencies: dragon - https://github.com/mwh/dragon
+# Dependencies:
+# - dragon (https://github.com/mwh/dragon), or
+# - kitty (https://github.com/kovidgoyal/kitty)
#
-# Notes:
+# Notes if using dragon:
# 1. Files that are dropped will be added to nnn's selection
# Some web-based files will be downloaded to current dir
# with curl and it may overwrite some existing files
@@ -14,6 +15,9 @@
# Shell: POSIX compliant
# Author: 0xACE
+# If you want system notification, put this equal to 1
+notify=0
+
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
resp=f
all=
@@ -21,16 +25,18 @@ if type dragon-drag-and-drop >/dev/null 2>&1; then
dnd="dragon-drag-and-drop"
elif type dragon-drop >/dev/null 2>&1; then
dnd="dragon-drop"
+elif [ "$TERM" = "xterm-kitty" ]; then
+ dnd="kitten dnd"
else
dnd="dragon"
fi
-add_file ()
+add_file()
{
- printf '%s\0' "$@" >> "$selection"
+ printf '%s\0' "$@" >>"$selection"
}
-use_all ()
+use_all()
{
printf "mark --all (a) [default=none]: "
read -r resp
@@ -52,26 +58,58 @@ else
fi
fi
-if [ "$resp" = "s" ]; then
- use_all
- sed -z 's|'"$PWD/"'||g' < "$selection" | xargs -0 "$dnd" "$all" &
-elif [ "$resp" = "d" ]; then
- use_all
- "$dnd" "$all" "$PWD/"* &
-elif [ "$resp" = "r" ]; then
- true > "$selection"
- "$dnd" --print-path --target | while read -r f
- do
- if printf "%s" "$f" | grep '^\(https\?\|ftps\?\|s\?ftp\):\/\/' ; then
- curl -LJO "$f"
- add_file "$PWD/$(basename "$f")"
+clear_tui()
+{
+ pid=$!
+ reset # nnn to dnd
+ wait $pid
+ reset # dnd to nnn
+}
+
+if [ "$dnd" = "kitten dnd" ]; then
+ if [ "$resp" = "s" ]; then
+ # shellcheck disable=SC2086
+ xargs -0 $dnd 2>/dev/null <"$selection" &
+ elif [ "$resp" = "d" ]; then
+ $dnd "$PWD/"* 2>/dev/null &
+ else # send one or receive
+ $dnd "$1" 2>/dev/null &
+ fi
+
+ clear_tui
+
+ if [ "$resp" = "s" ]; then
+ [ -p "$NNN_PIPE" ] && printf "-" >"$NNN_PIPE" # clear selection
+ fi
+else
+ if [ "$resp" = "s" ]; then
+ use_all
+ sed -z 's|'"$PWD/"'||g' <"$selection" | xargs -0 "$dnd" "$all" 2>/dev/null &
+ elif [ "$resp" = "d" ]; then
+ use_all
+ "$dnd" "$all" "$PWD/"* 2>/dev/null &
+ elif [ "$resp" = "r" ]; then
+ true >"$selection"
+ "$dnd" --print-path --target 2>/dev/null | while read -r f; do
+ if printf "%s" "$f" | grep -q '^\(https\?\|ftps\?\|s\?ftp\)://'; then
+ if output=$(curl -fsLJOS "$f" 2>&1); then
+ filename="$(basename "${f%%\?*}")"
+ add_file "$PWD/$filename"
+ if [ $notify = 1 ]; then
+ notify-send "Download Complete" "Finished downloading $filename"
+ fi
+ else
+ if [ $notify = 1 ]; then
+ notify-send "Download Failed" "$output"
+ else
+ echo "Download Failed: $output"
+ fi
+ fi
elif [ -e "$f" ]; then
- add_file "$f"
+ add_file "$f"
fi
- done &
-else
- if [ -n "$1" ] && [ -e "$1" ]; then
- "$dnd" "$1" &
+ done &
+ elif [ -n "$1" ] && [ -e "$1" ]; then
+ "$dnd" "$1" 2>/dev/null &
fi
fi
-
diff --git a/files/.config/nnn/plugins/dups b/files/.config/nnn/plugins/dups
index 27c1807..d402367 100755
--- a/files/.config/nnn/plugins/dups
+++ b/files/.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" "$@" </dev/tty'
+ sed -e "$sedcmd" "$tmpfile" | tr '\n' '\0' | xargs -0 -r sh -c 'rm -f -- "$0" "$@" </dev/tty'
else
#shellcheck disable=SC2016
- sed -e "$sedcmd" "$tmpfile" | tr '\n' '\0' | xargs -0 -r sh -c 'rm -i "$0" "$@" </dev/tty'
+ sed -e "$sedcmd" "$tmpfile" | tr '\n' '\0' | xargs -0 -r sh -c 'rm -i -- "$0" "$@" </dev/tty'
fi
-rm "$tmpfile"
+rm -- "$tmpfile"
printf "Press any key to exit"
read -r _
diff --git a/files/.config/nnn/plugins/finder b/files/.config/nnn/plugins/finder
index bdd2e69..fc85c33 100755
--- a/files/.config/nnn/plugins/finder
+++ b/files/.config/nnn/plugins/finder
@@ -84,6 +84,6 @@ if [ -n "$fexpr" ]; then
if [ -n "$fexpr" ]; then
tail -n"$NNN_FINDHISTLEN" "$NNN_FINDHIST" > "$TMPDIR/finderbms"
printf "%s\n" "$fexpr" >> "$TMPDIR/finderbms"
- mv "$TMPDIR/finderbms" "$NNN_FINDHIST"
+ mv -- "$TMPDIR/finderbms" "$NNN_FINDHIST"
fi
fi
diff --git a/files/.config/nnn/plugins/fixname b/files/.config/nnn/plugins/fixname
index 4047152..2b0ec1b 100755
--- a/files/.config/nnn/plugins/fixname
+++ b/files/.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/files/.config/nnn/plugins/fzcd b/files/.config/nnn/plugins/fzcd
index 125092c..35fae7e 100755
--- a/files/.config/nnn/plugins/fzcd
+++ b/files/.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/files/.config/nnn/plugins/fzhist b/files/.config/nnn/plugins/fzhist
index 111bc22..de10c2a 100755
--- a/files/.config/nnn/plugins/fzhist
+++ b/files/.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/files/.config/nnn/plugins/fzopen b/files/.config/nnn/plugins/fzopen
index 17b0585..4303dc3 100755
--- a/files/.config/nnn/plugins/fzopen
+++ b/files/.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/files/.config/nnn/plugins/fzplug b/files/.config/nnn/plugins/fzplug
index 11dcf7f..1069f43 100755
--- a/files/.config/nnn/plugins/fzplug
+++ b/files/.config/nnn/plugins/fzplug
@@ -34,7 +34,7 @@ if type bat >/dev/null; then
BAT="bat --terminal-width='$(tput cols)' --decorations=always --color=always --style='${BAT_STYLE:-header,numbers}'"
fi
-plugin=$(find "$nnnpluginsdir" "$CUSTOMDIR1" "$CUSTOMDIR2" \
+plugin=$(find -L "$nnnpluginsdir" "$CUSTOMDIR1" "$CUSTOMDIR2" \
-maxdepth 3 -perm -111 -type f 2>/dev/null | fzf --ansi --preview \
"${BAT:-cat} {}" --preview-window="right:66%:wrap" --delimiter / \
--with-nth -1 --bind="?:toggle-preview")
diff --git a/files/.config/nnn/plugins/getplugs b/files/.config/nnn/plugins/getplugs
index 361a605..30dbf7b 100755
--- a/files/.config/nnn/plugins/getplugs
+++ b/files/.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/files/.config/nnn/plugins/gpgs b/files/.config/nnn/plugins/gpgs
new file mode 100755
index 0000000..3d434c3
--- /dev/null
+++ b/files/.config/nnn/plugins/gpgs
@@ -0,0 +1,42 @@
+#!/usr/bin/env sh
+
+# Description: signs selected files using gpg.
+# includes options for clearsigning and
+# detached signing documents as well
+#
+# signed and detach signed files are stored with extension .sig
+# whereas clearsigned one are stored as .asc [by default by gpg]
+#
+# Note: The chosen method of signing is applied to all selected files [if selection is chosen]
+#
+# Shell: POSIX compliant
+# Author: wassup05
+
+file=$1
+selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
+
+printf "(s)election/(c)urrent? [default=c] "
+read -r file_resp
+printf "(s)ign/(c)learsign/(d)etach-sig? [default=s] "
+read -r sig_resp
+
+getfiles(){
+ if [ "$file_resp" = "s" ]; then
+ cat "$selection"
+ else
+ printf "%s\0" "$file"
+ fi
+}
+
+if [ "$sig_resp" = "c" ]; then
+ getfiles | xargs -0 -I{} gpg --clearsign {}
+elif [ "$sig_resp" = "d" ]; then
+ getfiles | xargs -0 -I{} gpg --detach-sig --output "{}.sig"
+else
+ getfiles | xargs -0 -I{} gpg --sign --output "{}.sig" {}
+fi
+
+# Clear selection
+if [ "$file_resp" = "s" ] && [ -p "$NNN_PIPE" ]; then
+ printf "-" > "$NNN_PIPE"
+fi
diff --git a/files/.config/nnn/plugins/gpgv b/files/.config/nnn/plugins/gpgv
new file mode 100755
index 0000000..23e52e7
--- /dev/null
+++ b/files/.config/nnn/plugins/gpgv
@@ -0,0 +1,28 @@
+#!/usr/bin/env sh
+
+# Description: verifies signed files using gpg.
+# includes options for detached signing
+# (in which case it asks for a document to verify)
+# as well as normal signing
+#
+# Note: Uses the current file only [selections not supported]
+#
+# Shell: POSIX compliant
+# Author: wassup05
+
+file=$1
+
+printf "(s)ign/(d)etach-sig [default=s] "
+read -r sig_resp
+
+if [ "$sig_resp" = "d" ]; then
+ printf "Enter document name: "
+ read -r doc_name
+ command gpg --verify "$file" "$doc_name"
+else
+ command gpg --verify "$file"
+fi
+
+printf "\n"
+# shellcheck disable=SC2034
+read -r resp # Waiting for input to go back to nnn
diff --git a/files/.config/nnn/plugins/imgur b/files/.config/nnn/plugins/imgur
index 16d21bc..e5981fc 100755
--- a/files/.config/nnn/plugins/imgur
+++ b/files/.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/files/.config/nnn/plugins/imgview b/files/.config/nnn/plugins/imgview
index d8cc247..0337511 100755
--- a/files/.config/nnn/plugins/imgview
+++ b/files/.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/files/.config/nnn/plugins/mimelist b/files/.config/nnn/plugins/mimelist
index ccfe05a..3813c09 100755
--- a/files/.config/nnn/plugins/mimelist
+++ b/files/.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/files/.config/nnn/plugins/nbak b/files/.config/nnn/plugins/nbak
index f9cb644..9950026 100755
--- a/files/.config/nnn/plugins/nbak
+++ b/files/.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/files/.config/nnn/plugins/nmount b/files/.config/nnn/plugins/nmount
index e05453f..b484b08 100755
--- a/files/.config/nnn/plugins/nmount
+++ b/files/.config/nnn/plugins/nmount
@@ -1,4 +1,4 @@
-#!/usr/bin/env sh
+#!/usr/bin/env bash
# Description: Toggle mount status of a device using pmount
# If the device is not mounted, it will be mounted.
@@ -6,7 +6,7 @@
#
# Dependencies: lsblk, pmount (optional), udisks2
#
-# Usage: Runs `lsblk` on 'l', exits on 'Return`.
+# Usage: Runs `lsblk` on 'l', unmounts all USB HDDs on 'u', exits on 'Return`.
#
# Notes:
# - The script uses Linux-specific lsblk to list block devices. Alternatives:
@@ -15,22 +15,89 @@
# - 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 alternative to power-down disks.
#
-# Shell: POSIX compliant
+# Shell: Bash
# Author: Arun Prakash Jana
-prompt="device name [e.g. sdXn] ('l'ist, 'q'uit): "
+prompt="device name [e.g. sdXn] ('l'ist, 'u'nmount all USB, 'q'uit): "
+previous_input=""
+
+restore_previous_input() {
+ if [ -n "$previous_input" ]; then
+ READLINE_LINE="$previous_input"
+ READLINE_POINT=${#READLINE_LINE}
+ fi
+}
+
+clear_input() {
+ READLINE_LINE=""
+ READLINE_POINT=0
+}
+
+bind -x '"\e[A":restore_previous_input'
+bind -x '"\e[B":clear_input'
lsblk
printf "\nEnsure you aren't still in the mounted device.\n"
-printf "%s" "$prompt"
-read -r dev
+read -r -e -p "$prompt" dev
while [ -n "$dev" ]; do
+ previous_input="$dev"
if [ "$dev" = "l" ]; then
lsblk
elif [ "$dev" = "q" ]; then
exit
+ elif [ "$dev" = "u" ]; then
+ usb_devs=$(lsblk -ndo NAME,TRAN | awk '$2=="usb"{print $1}')
+ if [ -z "$usb_devs" ]; then
+ echo "No USB block devices found."
+ else
+ for disk in $usb_devs; do
+ # Get only real partitions (e.g. sda1), skip device-mapper entries like luks-*
+ parts=$(lsblk -nlpo NAME,TYPE "/dev/$disk" | awk '$2=="part"{print $1}')
+ if [ -z "$parts" ]; then
+ echo "/dev/$disk has no partitions, skipping."
+ continue
+ fi
+ mounted=0
+ for part in $parts; do
+ mnt=$(lsblk -n "$part" -o MOUNTPOINT | sed '/^$/d')
+ # Check if this partition or any child (e.g. LUKS) is mounted
+ child_mnt=$(lsblk -nro MOUNTPOINT "$part" | sed '/^$/d')
+ if [ -z "$mnt" ] && [ -z "$child_mnt" ]; then
+ continue
+ fi
+ mounted=1
+ if type pumount >/dev/null 2>&1; then
+ sync "$child_mnt"
+ pumount "$part"
+ prc=$?
+ elif lsblk -n "$part" -o FSTYPE | grep -q "crypto_LUKS"; then
+ dev_map=$(udisksctl info -b "$part" | grep "CleartextDevice" | grep -o "dm_2d[[:digit:]]*" | sed "s/_2d/-/")
+ sync "$child_mnt"
+ udisksctl unmount -b "/dev/$dev_map" --no-user-interaction >/dev/null
+ prc=$?
+ udisksctl lock -b "$part" --no-user-interaction >/dev/null
+ else
+ sync "$mnt"
+ udisksctl unmount -b "$part" --no-user-interaction >/dev/null
+ prc=$?
+ fi
+ if [ $prc -eq 0 ]; then
+ echo "$part unmounted."
+ else
+ echo "Failed to unmount $part."
+ fi
+ done
+ if [ $mounted -eq 0 ]; then
+ echo "/dev/$disk has no mounted partitions, skipping."
+ continue
+ fi
+ if udisksctl power-off -b "/dev/$disk" --no-user-interaction 2>/dev/null; then
+ echo "/dev/$disk ejected."
+ fi
+ done
+ fi
else
# LUKS volumes mounted with udisksctl appear differently than with pmount
if grep -qs "$dev " /proc/mounts || [ -n "$(lsblk -n "/dev/$dev" -o MOUNTPOINT)" ]; then
@@ -83,6 +150,5 @@ while [ -n "$dev" ]; do
fi
echo
- printf "%s" "$prompt"
- read -r dev
+ read -r -e -p "$prompt" dev
done
diff --git a/files/.config/nnn/plugins/nuke b/files/.config/nnn/plugins/nuke
index b3eafc8..44e2540 100755
--- a/files/.config/nnn/plugins/nuke
+++ b/files/.config/nnn/plugins/nuke
@@ -226,7 +226,8 @@ handle_extension() {
glow -sdark "${FPATH}" | eval "$PAGER"
exit 0
elif type lowdown >/dev/null 2>&1; then
- lowdown -Tterm "${FPATH}" | eval "$PAGER"
+ cols=$(tput cols)
+ lowdown -Tterm --term-width="$cols" --term-column="$cols" "${FPATH}" | eval "$PAGER"
exit 0
fi
;;
@@ -271,13 +272,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 +403,7 @@ handle_multimedia() {
# "${FPATH}";
# then
# convert -- "${preview_png}" "${IMAGE_CACHE_PATH}" \
- # && rm "${preview_png}" \
+ # && rm -- "${preview_png}" \
# && exit 6
# else
# exit 1
@@ -544,12 +545,13 @@ handle_bin() {
esac
}
-MIMETYPE="$( file -bL --mime-type -- "${FPATH}" )"
handle_extension
+MIMETYPE="$( file -bL --mime-type -- "${FPATH}" )"
handle_multimedia "${MIMETYPE}"
handle_mime "${MIMETYPE}"
[ "$BIN" -ne 0 ] && [ -x "${FPATH}" ] && handle_bin
handle_blocked "${MIMETYPE}"
handle_fallback
+# shellcheck disable=SC2317
exit 1
diff --git a/files/.config/nnn/plugins/organize b/files/.config/nnn/plugins/organize
index fb70aaf..81cc9df 100755
--- a/files/.config/nnn/plugins/organize
+++ b/files/.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/files/.config/nnn/plugins/pdfread b/files/.config/nnn/plugins/pdfread
index 1e889be..9f65728 100755
--- a/files/.config/nnn/plugins/pdfread
+++ b/files/.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/files/.config/nnn/plugins/preview-tabbed b/files/.config/nnn/plugins/preview-tabbed
index 5235c1e..2493fdf 100755
--- a/files/.config/nnn/plugins/preview-tabbed
+++ b/files/.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
@@ -57,16 +57,21 @@ if [ -n "$WAYLAND_DISPLAY" ] ; then
exit 1
fi
-if type xterm >/dev/null 2>&1 ; then
- TERMINAL="xterm -into"
-elif type urxvt >/dev/null 2>&1 ; then
- TERMINAL="urxvt -embed"
+if type alacritty >/dev/null 2>&1 ; then
+ TERMINAL="alacritty --embed"
elif type st >/dev/null 2>&1 ; then
TERMINAL="st -w"
+elif type urxvt >/dev/null 2>&1 ; then
+ TERMINAL="urxvt -embed"
+elif type xterm >/dev/null 2>&1 ; then
+ TERMINAL="xterm -into"
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
@@ -189,7 +204,8 @@ previewer_loop () {
if [ -x "$NUKE" ] ; then
term_nuke "$XID" "$FILE"
else
- $TERMINAL "$XID" -e sh -c "file '$FILE' | $PAGER -" &
+ SAFE_FILE=$(printf "%s" "$FILE" | sed "s/'/'\\\\''/g")
+ $TERMINAL "$XID" -e sh -c "file '$SAFE_FILE' | $PAGER -" &
fi
;;
esac
diff --git a/files/.config/nnn/plugins/preview-tui b/files/.config/nnn/plugins/preview-tui
index e78b110..7fc48e7 100755
--- a/files/.config/nnn/plugins/preview-tui
+++ b/files/.config/nnn/plugins/preview-tui
@@ -5,15 +5,16 @@
# Note: This plugin needs a "NNN_FIFO" to work. See man.
#
# Dependencies:
-# - Supports 6 independent methods to preview with:
+# - Supports 7 independent methods to preview with:
# - tmux (>=3.0), or
# - kitty with allow_remote_control and listen_on set in kitty.conf, or
# - wezterm (https://wezfurlong.org/wezterm), 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
+# - zellij (https://github.com/zellij-org/zellij) or
# - $NNN_TERMINAL set to a terminal (it's xterm by default).
# - less or $NNN_PAGER
-# - tree or exa or (GNU) ls
+# - tree or exa/eza or (GNU) ls
# - mediainfo or file
# - mktemp
# - unzip
@@ -21,8 +22,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, timg 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 +45,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,
@@ -68,6 +74,12 @@
# 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.
#
@@ -84,28 +96,33 @@
# '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
+# 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:-}" # command 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=(
+ENVVARS+=(
"PWD=$PWD"
"PATH=$PATH"
"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 -C}"
- "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"
@@ -132,14 +149,20 @@ pidkill() {
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
+ elif [ -n "$ZELLIJ" ]; then
+ NNN_TERMINAL=zellij
else
NNN_TERMINAL="${NNN_TERMINAL:-xterm}"
fi
@@ -152,7 +175,7 @@ start_preview() {
ENVVARS+=("NNN_TERMINAL=$NNN_TERMINAL" "NNN_SPLIT=$NNN_SPLIT" "QLPATH=$2" "PREVIEW_MODE=1")
case "$NNN_TERMINAL" in
- iterm|winterm) # need run in separate shell command: escape
+ iterm|winterm) # has to run in separate shell command: escape
ENVVARS=("${ENVVARS[@]/#/\\\"}")
ENVVARS=("${ENVVARS[@]/%/\\\"}")
command="$SHELL -c 'env ${ENVVARS[*]} \\\"$0\\\" \\\"$1\\\"'" ;;
@@ -162,7 +185,7 @@ start_preview() {
tmux) # tmux splits are inverted
ENVVARS=("${ENVVARS[@]/#/-e}")
if [ "$NNN_SPLIT" = "v" ]; then split="h"; else split="v"; fi
- tmux split-window "${ENVVARS[@]}" -d"$split" -p"$NNN_SPLITSIZE" "$0" "$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
@@ -187,6 +210,17 @@ EOF
winterm)
if [ "$NNN_SPLIT" = "h" ]; then split="H"; else split="V"; fi
wt -w 0 sp -$split -s"0.$NNN_SPLITSIZE" "$command" \; -w 0 mf previous 2>/dev/null ;;
+ zellij)
+ case "$NNN_SPLIT" in
+ h)
+ direction="down" ;;
+ *)
+ direction=right ;;
+ esac
+ zellij run --name "nnn preview" --close-on-exit \
+ --direction "$direction" -- env "${ENVVARS[@]}" "$0" "$1" &
+ (sleep 0.2 && zellij action focus-previous-pane) &
+ ;;
*) if [ -n "$2" ]; then
env "${ENVVARS[@]}" QUICKLOOK=1 "$0" "$1" &
else
@@ -240,7 +274,7 @@ fifo_pager() {
fi
)
- rm "$FIFOPATH"
+ rm -- "$FIFOPATH"
}
# Binary file: show file info inside the pager
@@ -282,7 +316,7 @@ handle_ext() {
md) if exists glow; then
fifo_pager glow -s dark "$1"
elif exists lowdown; then
- fifo_pager lowdown -Tterm "$1"
+ fifo_pager lowdown -Tterm --term-width="$cols" --term-column="$cols" "$1"
else
fifo_pager pager "$1"
fi ;;
@@ -303,6 +337,12 @@ handle_ext() {
elif exists bsdtar; then
fifo_pager bsdtar -tvf "$1"
fi ;;
+ json)
+ if exists jq; then
+ fifo_pager jq --color-output '.' "$1"
+ else
+ fifo_pager pager "$1"
+ fi ;;
*) if [ "$3" = "bin" ]; then
fifo_pager print_bin_info "$1"
else
@@ -349,7 +389,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
@@ -364,6 +406,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
@@ -387,25 +432,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
@@ -414,24 +464,33 @@ generate_preview() {
image_preview() {
clear
exec >/dev/tty
- if [ "$NNN_TERMINAL" = "kitty" ] && [ -z "$NNN_PREVIEWIMGPROG" ]; then
+ 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
- catimg "$3" &
- elif exists viu && { [ -z "$NNN_PREVIEWIMGPROG" ] || [ "$NNN_PREVIEWIMGPROG" = "viu" ] ;}; then
- viu -t "$3" &
- elif exists chafa && { [ -z "$NNN_PREVIEWIMGPROG" ] || [ "$NNN_PREVIEWIMGPROG" = "chafa" ] ;}; then
- chafa "$3" &
+ elif exists "${NNN_PREVIEWIMGPROG%% *}"; then # can include command flags; only check first word
+ $NNN_PREVIEWIMGPROG "$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'\
@@ -457,6 +516,7 @@ preview_fifo() {
if [ -n "$selection" ]; then
pidkill "$PREVIEWPID"
[ -p "$FIFO_UEBERZUG" ] && ueberzug_remove
+ [ -n "$KITTY_LISTEN_ON" ] && kitty +kitten icat --clear --stdin=no >/dev/tty 2>/dev/null
[ "$selection" = "close" ] && break
preview_file "$selection"
printf "%s" "$selection" > "$CURSEL"
@@ -467,18 +527,20 @@ 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
diff --git a/files/.config/nnn/plugins/renamer b/files/.config/nnn/plugins/renamer
index 51c586e..9d5b2e9 100755
--- a/files/.config/nnn/plugins/renamer
+++ b/files/.config/nnn/plugins/renamer
@@ -6,7 +6,7 @@
# - Try to mimic current batch rename functionality but with correct
# handling of edge cases by qmv or vidir.
# - Qmv opens with hidden files if no selection is used. Selected
-# directories are shown.
+# directories are shown.
# - Vidir don't show directories nor hidden files.
#
# Shell: POSIX compliant
@@ -15,11 +15,11 @@
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
if type qmv >/dev/null 2>&1; then
- batchrenamesel="qmv -fdo -da"
- batchrename="qmv -fdo -a"
+ batchrenamesel="qmv -fdo -da"
+ batchrename="qmv -fdo -a"
elif type vidir >/dev/null 2>&1; then
- batchrenamesel="vidir"
- batchrename="vidir"
+ batchrenamesel="vidir"
+ batchrename="vidir"
else
printf "there is not batchrename program installed."
exit
@@ -32,6 +32,7 @@ fi
if [ "$resp" = "y" ]; then
# -o flag is necessary for interactive editors
+ # shellcheck disable=SC2086
xargs -o -0 $batchrenamesel < "$selection"
# Clear selection
@@ -40,6 +41,6 @@ if [ "$resp" = "y" ]; then
fi
elif [ ! "$(LC_ALL=C ls -a)" = ".
.." ]; then
- # On older systems that don't have ls -A
+ # On older systems that don't have ls -A
$batchrename
fi
diff --git a/files/.config/nnn/plugins/stats b/files/.config/nnn/plugins/stats
new file mode 100755
index 0000000..bafd74a
--- /dev/null
+++ b/files/.config/nnn/plugins/stats
@@ -0,0 +1,71 @@
+#!/usr/bin/env sh
+
+# Description: Show file stats similar to nnn show_stats() output in a pager
+# Dependencies: file, stat, pager (PAGER/NNN_PAGER/less)
+# Shell: POSIX compliant
+
+entry=${1:-}
+dir=${2:-}
+
+if [ -z "$entry" ]; then
+ printf '%s\n' "No hovered entry provided." >&2
+ exit 1
+fi
+
+case "$entry" in
+ /*) target=$entry ;;
+ *)
+ if [ -n "$dir" ]; then
+ target=$dir/$entry
+ else
+ target=$PWD/$entry
+ fi
+ ;;
+esac
+
+os=$(uname -s 2>/dev/null || printf '%s' unknown)
+
+# Match nnn FILE_MIME_OPTS handling.
+file_mime_opts=''
+case "$os" in
+ Darwin)
+ file_mime_opts='-bIL'
+ ;;
+ SunOS)
+ file_mime_opts=''
+ ;;
+ *)
+ file_mime_opts='-biL'
+ ;;
+esac
+
+# Match nnn stat behavior.
+stat_x=0
+case "$os" in
+ FreeBSD|OpenBSD|NetBSD|Darwin|DragonFly)
+ stat_x=1
+ ;;
+esac
+
+tmpfile=$(mktemp "${TMPDIR:-/tmp}/nnn-stats.XXXXXX") || exit 1
+trap 'rm -f "$tmpfile"' EXIT HUP INT TERM
+
+{
+ if [ "$stat_x" -eq 1 ]; then
+ stat -x "$target"
+ else
+ stat "$target"
+ fi
+
+ file -b "$target"
+
+ if [ -n "$file_mime_opts" ]; then
+ file "$file_mime_opts" "$target"
+ fi
+} >"$tmpfile" 2>&1
+
+pager_cmd=${NNN_PAGER:-${PAGER:-less}}
+
+# Allow pager command with options (e.g. "less -R").
+# shellcheck disable=SC2086
+$pager_cmd "$tmpfile" || cat "$tmpfile"
diff --git a/files/.config/nnn/plugins/suedit b/files/.config/nnn/plugins/suedit
index 21dddf4..03608e8 100755
--- a/files/.config/nnn/plugins/suedit
+++ b/files/.config/nnn/plugins/suedit
@@ -7,10 +7,10 @@
EDITOR="${EDITOR:-vim}"
-if type sudo >/dev/null 2>&1; then
+if type sudoedit >/dev/null 2>&1; then
+ sudoedit "$1"
+elif type sudo >/dev/null 2>&1; then
sudo -E "$EDITOR" "$1"
-elif type sudoedit >/dev/null 2>&1; then
- sudoedit -E "$1"
elif type doas >/dev/null 2>&1; then
doas "$EDITOR" "$1"
fi
diff --git a/files/.config/nnn/plugins/tnp b/files/.config/nnn/plugins/tnp
new file mode 100755
index 0000000..8c484a2
--- /dev/null
+++ b/files/.config/nnn/plugins/tnp
@@ -0,0 +1,47 @@
+#!/usr/bin/env sh
+
+# Description: Only works inside a tmux session - Opens files in Neovim.
+# If $NVIM is set and its server is alive, files are opened
+# in that server. Otherwise, a new pane is split on the left
+# and files are opened there until the nnn pane is closed.
+#
+# Dependencies: tmux neovim
+#
+# Tip: Exec nnn inside Neovim pane via a leader key
+#
+# vim.keymap.set("n", "<Leader>n", function()
+# if vim.env.TMUX then
+# vim.fn.system({
+# "tmux", "split-window", "-h",
+# "-c", vim.fn.getcwd(),
+# "-e", "NVIM=" .. vim.v.servername,
+# "exec nnn"
+# })
+# end
+# end)
+#
+# Shell: POSIX compliant
+# Author: 8lackfish
+
+fpath="${2:+$2/}$1"
+
+if [ -n "$TMUX" ]; then
+ if [ -S "$NVIM" ]; then
+ svname="$NVIM"
+ nvim --server "$svname" --remote "$fpath"
+ else
+ id=$(tmux display-message -p '#{pane_id}.#{window_id}.#{session_id}' | tr -d '%@$')
+ svname="${XDG_RUNTIME_DIR:-/tmp}/nvim.nnn-tnp.$id"
+ if [ -S "$svname" ]; then
+ nvim --server "$svname" --remote "$fpath"
+ else
+ tmux split-pane -bdh "nvim --listen \"${svname}\" \"${fpath}\""
+ fi
+ fi
+ until nvim --headless --server "$svname" \
+ --remote-expr "execute('%argdelete')" >/dev/null 2>&1
+ do :; done
+else
+ printf "\n'%s' only works inside a tmux session" "$(basename "$0")"
+ printf "\n\n'Enter' to return"; read -r _
+fi
diff --git a/files/.config/nnn/plugins/upload b/files/.config/nnn/plugins/upload
index 4948587..e225d20 100755
--- a/files/.config/nnn/plugins/upload
+++ b/files/.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/files/.config/nnn/plugins/wallpaper b/files/.config/nnn/plugins/wallpaper
index 2017fbd..966e7ce 100755
--- a/files/.config/nnn/plugins/wallpaper
+++ b/files/.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
diff --git a/files/.config/nnn/plugins/x2sel b/files/.config/nnn/plugins/x2sel
index 95414fc..4682e51 100755
--- a/files/.config/nnn/plugins/x2sel
+++ b/files/.config/nnn/plugins/x2sel
@@ -8,7 +8,7 @@
# - pbpaste (macOS)
# - termux-clipboard-get (Termux)
# - powershell (WSL)
-# - cygwim's /dev/clipboard (Cygwin)
+# - cygwin's /dev/clipboard (Cygwin)
# - wl-paste (Wayland)
# - clipboard (Haiku)
#
@@ -26,6 +26,9 @@ getclip () {
if [ "$XDG_SESSION_TYPE" = "wayland" ]; then
# Wayland
wl-paste
+ elif type powershell.exe >/dev/null 2>&1; then
+ # WSL
+ powershell.exe -noprofile -command Get-Clipboard | tr -d '\r'
elif type xsel >/dev/null 2>&1; then
# Linux
xsel -bo
@@ -38,9 +41,6 @@ getclip () {
elif type termux-clipboard-get >/dev/null 2>&1; then
# Termux
termux-clipboard-get
- elif type powershell.exe >/dev/null 2>&1; then
- # WSL
- powershell.exe Get-Clipboard
elif [ -r /dev/clipboard ] ; then
# Cygwin
cat /dev/clipboard
@@ -52,9 +52,15 @@ getclip () {
CLIPBOARD=$(getclip)
+if [ -z "$CLIPBOARD" ]; then
+ echo "No content in clipboard"
+ exit 1
+fi
+
# Check if clipboard actually contains a file list
for file in $CLIPBOARD ; do
if [ ! -e "$file" ] ; then
+ echo "'$file' is not a file"
exit 1;
fi
done
diff --git a/files/.config/nnn/plugins/xdgdefault b/files/.config/nnn/plugins/xdgdefault
index cf64a2f..27934c9 100755
--- a/files/.config/nnn/plugins/xdgdefault
+++ b/files/.config/nnn/plugins/xdgdefault
@@ -40,7 +40,10 @@ while [ -n "$dirs" ]; do
dirs=${dirs#*:}
done
-app=$(find "$@" -iname '*.desktop' -exec grep '^Name=' {} + \
+# see PR #2102
+# shellcheck disable=SC2038
+app=$(find "$@" -iname '*.desktop' -exec grep -l "MimeType=.*$ftype" {} + 2>/dev/null \
+ | xargs -I {} grep '^Name=' {} /dev/null \
| sort -u -t ':' -k 1,1 \
| sed -e 's;..*/\(..*desktop\):Name=\(..*\);\2:\1;' \
| sort -t ':' -k 1,1 \