My build of nnn with minor changes
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

252 lignes
7.9 KiB

  1. #!/usr/bin/env sh
  2. # Description: Terminal based file previewer
  3. #
  4. # Note: This plugin needs a "NNN_FIFO" to work. See man.
  5. #
  6. # Dependencies:
  7. # - Supports 3 independent methods to preview with:
  8. # - tmux (>=3.0), or
  9. # - kitty with allow_remote_control on, or
  10. # - $TERMINAL set to a terminal (it's xterm by default).
  11. # - less or $PAGER
  12. # - tree or exa or ls
  13. # - mediainfo or file
  14. # - mktemp
  15. # - unzip
  16. # - tar
  17. # - man
  18. # - optional: bat for code syntax highlighting
  19. # - optional: kitty terminal, catimg, viu, or ueberzug for images
  20. # - optional: scope.sh file viewer from ranger.
  21. # To use:
  22. # 1. drop scope.sh executable in $PATH
  23. # 2. set/export $USE_SCOPE as 1
  24. # - optional: pistol file viewer (https://github.com/doronbehar/pistol).
  25. # To use:
  26. # 1. install pistol
  27. # 2. set/export $USE_PISTOL as 1
  28. # - optional: ffmpegthumbnailer for video thumbnails (https://github.com/dirkvdb/ffmpegthumbnailer).
  29. # To use:
  30. # 1. install ffmpegthumbnailer
  31. # 2. set/export USE_VIDEOTHUMB as 1
  32. #
  33. # Usage:
  34. # You need to set a NNN_FIFO path and a key for the plugin with NNN_PLUG,
  35. # then start `nnn`:
  36. #
  37. # $ nnn -a
  38. #
  39. # or
  40. #
  41. # $ NNN_FIFO=/tmp/nnn.fifo nnn
  42. #
  43. # Then in `nnn`, launch the `preview-tui` plugin.
  44. #
  45. # If you provide the same NNN_FIFO to all nnn instances, there will be a
  46. # single common preview window. If you provide different FIFO path (e.g.
  47. # with -a), they will be independent.
  48. #
  49. # The previews will be shown in a tmux split. If that isn't possible, it
  50. # will try to use a kitty terminal split. And as a final fallback, a
  51. # different terminal window will be used ($TERMINAL).
  52. #
  53. # Tmux and kitty users can configure $SPLIT to either "h" or "v" to set a
  54. # 'h'orizontal split or a 'v'ertical split (as in, the line that splits the
  55. # windows will be horizontal or vertical).
  56. #
  57. # Kitty users need `allow_remote_control` set to `yes`. To customize the
  58. # window split, `enabled_layouts` has to be set to `all` or `splits` (the
  59. # former is the default value). This terminal is also able to show images
  60. # without extra dependencies.
  61. #
  62. # Shell: POSIX compliant
  63. # Authors: Todd Yamakawa, Léo Villeveygoux, @Recidiviste, Mario Ortiz Manero
  64. SPLIT="$SPLIT" # you can set a permanent split here
  65. TERMINAL="$TERMINAL" # same goes for the terminal
  66. USE_SCOPE="${USE_SCOPE:-0}"
  67. USE_PISTOL="${USE_PISTOL:-0}"
  68. USE_VIDEOTHUMB="${USE_VIDEOTHUMB:-0}"
  69. PAGER="${PAGER:-less -R}"
  70. [ "$PAGER" = "most" ] && PAGER="less -R"
  71. if [ -e "${TMUX%%,*}" ] && tmux -V | grep -q '[ -][3456789]\.'; then
  72. TERMINAL=tmux
  73. elif [ -n "$KITTY_WINDOW_ID" ] && kitty @ ls >/dev/null 2>&1; then
  74. TERMINAL=kitty
  75. else
  76. TERMINAL="${TERMINAL:-xterm}"
  77. fi
  78. if [ -z "$SPLIT" ] && [ $(($(tput lines) * 2)) -gt "$(tput cols)" ]; then
  79. SPLIT='h'
  80. elif [ "$SPLIT" != 'h' ]; then
  81. SPLIT='v'
  82. fi
  83. exists() {
  84. which "$1" >/dev/null 2>&1
  85. }
  86. fifo_pager() {
  87. cmd="$1"
  88. shift
  89. # We use a FIFO to access $PAGER PID in jobs control
  90. tmpfifopath="${TMPDIR:-/tmp}/nnn-preview-tui-fifo.$$"
  91. mkfifo "$tmpfifopath" || return
  92. $PAGER < "$tmpfifopath" &
  93. (
  94. exec > "$tmpfifopath"
  95. "$cmd" "$@" &
  96. )
  97. rm "$tmpfifopath"
  98. }
  99. # Binary file: show file info inside the pager
  100. print_bin_info() {
  101. printf -- "-------- \033[1;31mBinary file\033[0m --------\n"
  102. if exists mediainfo; then
  103. mediainfo "$1" 2>/dev/null
  104. else
  105. file -b "$1"
  106. fi
  107. }
  108. preview_file () {
  109. kill %- %+ 2>/dev/null && wait %- %+ 2>/dev/null
  110. clear
  111. # Trying to use pistol if it's available.
  112. if [ "$USE_PISTOL" -ne 0 ] && exists pistol; then
  113. fifo_pager pistol "$1"
  114. return
  115. fi
  116. # Trying to use scope.sh if it's available.
  117. if [ "$USE_SCOPE" -ne 0 ] && exists scope.sh; then
  118. fifo_pager scope.sh "$1" "$cols" "$lines" "$(mktemp -d)" \
  119. "True" 2>/dev/null
  120. return
  121. fi
  122. # Detecting the exact type of the file: the encoding, mime type, and
  123. # extension in lowercase.
  124. encoding="$(file -Lb --mime-encoding -- "$1")"
  125. mimetype="$(file -Lb --mime-type -- "$1")"
  126. ext="${1##*.}"
  127. if [ -n "$ext" ]; then
  128. ext="$(printf "%s" "${ext}" | tr '[:upper:]' '[:lower:]')"
  129. fi
  130. lines=$(($(tput lines)-1))
  131. cols=$(tput cols)
  132. # Otherwise, falling back to the defaults.
  133. if [ -d "$1" ]; then
  134. cd "$1" || return
  135. if exists tree; then
  136. fifo_pager tree -L 3 -F
  137. elif exists exa; then
  138. fifo_pager exa -G --colour=always 2>/dev/null
  139. else
  140. fifo_pager ls --color=always
  141. fi
  142. elif [ "$encoding" = "binary" ]; then
  143. if [ "${mimetype%%/*}" = "image" ] || [ "${mimetype%%/*}" = "video" ]; then
  144. if [ "${mimetype%%/*}" = "video" ] && [ "$USE_VIDEOTHUMB" -ne 0 ] && exists ffmpegthumbnailer; then
  145. videothumb="/tmp/videothumb.$$.png"
  146. ffmpegthumbnailer -s 512 -i "$1" -o "$videothumb" >/dev/null 2>&1
  147. set "$videothumb"
  148. trap 'rm "$videothumb"' EXIT
  149. fi
  150. if [ "$TERMINAL" = "kitty" ]; then
  151. # Kitty terminal users can use the native image preview method.
  152. kitty +kitten icat --silent --transfer-mode=stream --stdin=no \
  153. "$1" &
  154. elif exists catimg; then
  155. catimg "$1"
  156. elif exists viu; then
  157. viu -t "$1"
  158. elif exists ueberzug; then
  159. preview_ueberzug "$cols" "$lines" "$1"
  160. else
  161. fifo_pager print_bin_info "$1"
  162. fi
  163. elif [ "$mimetype" = "application/zip" ] ; then
  164. fifo_pager unzip -l "$1"
  165. elif [ "$ext" = "gz" ] || [ "$ext" = "bz2" ] ; then
  166. fifo_pager tar -tvf "$1"
  167. else
  168. fifo_pager print_bin_info "$1"
  169. fi
  170. elif [ "$mimetype" = "text/troff" ] ; then
  171. fifo_pager man -Pcat -l "$1"
  172. else
  173. if exists bat; then
  174. fifo_pager bat --terminal-width="$cols" --paging=never --decorations=always --color=always \
  175. "$1" 2>/dev/null
  176. else
  177. $PAGER "$1" &
  178. fi
  179. fi
  180. }
  181. preview_ueberzug() {
  182. {
  183. printf '{"action": "add", "identifier": "nnn_ueberzug", "x": 0, "y": 0, "width": "%s", "height": "%s", "path": "%s"}\n' "$1" "$2" "$3"
  184. read -r
  185. } | ueberzug layer --parser json
  186. }
  187. if [ "$PREVIEW_MODE" ] ; then
  188. if [ ! -r "$NNN_FIFO" ] ; then
  189. echo "No FIFO available! (\$NNN_FIFO='$NNN_FIFO')" >&2
  190. read -r
  191. exit 1
  192. fi
  193. preview_file "$1"
  194. # use cat instead of 'exec <' to avoid issues with dash shell
  195. # shellcheck disable=SC2002
  196. cat "$NNN_FIFO" |\
  197. while read -r selection ; do
  198. preview_file "$selection"
  199. done
  200. # Restoring the previous layout for kitty users. This will only work for
  201. # kitty >= 0.18.0.
  202. if [ "$TERMINAL" = "kitty" ]; then
  203. kitty @ last-used-layout --no-response >/dev/null 2>&1
  204. fi
  205. exit 0
  206. fi
  207. if [ "$TERMINAL" = "tmux" ]; then
  208. # tmux splits are inverted
  209. if [ "$SPLIT" = "v" ]; then SPLIT="h"; else SPLIT="v"; fi
  210. tmux split-window -e "NNN_FIFO=$NNN_FIFO" -e "PREVIEW_MODE=1" -d"$SPLIT" "$0" "$1"
  211. elif [ "$TERMINAL" = "kitty" ]; then
  212. # Setting the layout for the new window. It will be restored after the
  213. # script ends.
  214. kitty @ goto-layout splits >/dev/null
  215. # Trying to use kitty's integrated window management as the split window.
  216. # All environmental variables that will be used in the new window must
  217. # be explicitly passed.
  218. kitty @ launch --no-response --title "nnn preview" --keep-focus \
  219. --cwd "$PWD" --env "PATH=$PATH" --env "NNN_FIFO=$NNN_FIFO" \
  220. --env "PREVIEW_MODE=1" --env "PAGER=$PAGER" \
  221. --env "USE_SCOPE=$USE_SCOPE" --env "SPLIT=$SPLIT" \
  222. --env "USE_PISTOL=$USE_PISTOL" \
  223. --location "${SPLIT}split" "$0" "$1" >/dev/null
  224. else
  225. PREVIEW_MODE=1 $TERMINAL -e "$0" "$1" &
  226. fi