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.
 
 
 
 
 
 

425 lignes
15 KiB

  1. #!/usr/bin/env sh
  2. # #############################################################################
  3. # Description: Sample script to play files in apps by file type or mime
  4. #
  5. # Shell: POSIX compliant
  6. # Usage: nuke filepath
  7. #
  8. # Integration with nnn:
  9. # 1. Export the required config:
  10. # export NNN_OPENER=/absolute/path/to/nuke
  11. # # Otherwise, if nuke is in $PATH
  12. # # export NNN_OPENER=nuke
  13. # 2. Run nnn with the program option to indicate a CLI opener
  14. # nnn -c
  15. # 3. nuke can use nnn plugins (e.g. mocplay is used for audio), $PATH is updated.
  16. #
  17. # Details:
  18. # Inspired by ranger's scope.sh, modified for usage with nnn.
  19. #
  20. # Tries to play 'file' (1st argument) in the following order:
  21. # i. by extension
  22. # ii. by mime (image, video, audio, pdf)
  23. # iii. by mime (other file types)
  24. #
  25. # Modification tips:
  26. # 1. Invokes CLI utilities by default. Set GUI to 1 to enable GUI apps.
  27. # 2. PAGER is "less -R".
  28. # 3. Start GUI apps in bg to unblock. Redirect stdout and strerr if required.
  29. # 4. Some CLI utilities are piped to the $PAGER, to wait and quit uniformly.
  30. # 5. If the output cannot be paged use "read -r _" to wait for user input.
  31. # 6. On a DE, try 'xdg-open' in handle_fallback() as last resort.
  32. #
  33. # Feel free to change the utilities to your favourites and add more mimes.
  34. #
  35. # Defaults:
  36. # By extension (only the enbaled ones):
  37. # most archives: list with atool, bsdtar
  38. # rar: list with unrar
  39. # 7-zip: list with 7z
  40. # pdf: zathura (GUI), pdftotext, mutool, exiftool
  41. # m4a: mocplay (nnn plugin using MOC), mpv, mediainfo, exiftool
  42. # torrent: transmission-show
  43. # odt|ods|odp|sxw: odt2txt
  44. # htm|html|xhtml: w3m, lynx, elinks
  45. # json: jq, python (json.tool module)
  46. # Multimedia by mime:
  47. # image/*: sxiv (GUI), viu, img2txt, exiftool
  48. # video/*: smplayer, mpv (GUI), ffmpegthumbnailer, mediainfo, exiftool
  49. # audio/*: mocplay (nnn plugin using MOC), mpv, mediainfo, exiftool
  50. # application/pdf: zathura (GUI), pdftotext, mutool, exiftool
  51. # Other mimes:
  52. # text/* | */xml: vi
  53. # image/vnd.djvu): djvutxt, exiftool
  54. #
  55. # ToDo:
  56. # 1. Adapt, test and enable all mimes
  57. # 2. Clean-up unnecessary the exit codes
  58. # #############################################################################
  59. # set to 1 to enable GUI apps
  60. GUI=0
  61. set -euf -o noclobber -o noglob -o nounset
  62. IFS="$(printf '%b_' '\n')"; IFS="${IFS%_}" # protect trailing \n
  63. PATH=$PATH:"${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins"
  64. IMAGE_CACHE_PATH="$(dirname "$1")"/.thumbs
  65. FPATH="$1"
  66. FNAME=$(basename "$1")
  67. ext="${FNAME##*.}"
  68. if ! [ -z "$ext" ]; then
  69. ext="$(printf "%s" "${ext}" | tr '[:upper:]' '[:lower:]')"
  70. fi
  71. # handle this extension and exit
  72. handle_extension() {
  73. case "${ext}" in
  74. ## Archive
  75. a|ace|alz|arc|arj|bz|bz2|cab|cpio|deb|gz|jar|lha|lz|lzh|lzma|lzo|\
  76. rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z|zip)
  77. if which atool >/dev/null 2>&1; then
  78. atool --list -- "${FPATH}" | less -R
  79. exit 0
  80. elif which bsdtar >/dev/null 2>&1; then
  81. bsdtar --list --file "${FPATH}" | less -R
  82. exit 0
  83. fi
  84. exit 1;;
  85. rar)
  86. if which unrar >/dev/null 2>&1; then
  87. ## Avoid password prompt by providing empty password
  88. unrar lt -p- -- "${FPATH}" | less -R
  89. fi
  90. exit 1;;
  91. 7z)
  92. if which 7z >/dev/null 2>&1; then
  93. ## Avoid password prompt by providing empty password
  94. 7z l -p -- "${FPATH}" | less -R
  95. exit 0
  96. fi
  97. exit 1;;
  98. ## PDF
  99. pdf)
  100. if [ $GUI -ne 0 ] && which zathura >/dev/null 2>&1; then
  101. zathura "${FPATH}" >/dev/null 2>&1 &
  102. exit 0
  103. elif which pdftotext >/dev/null 2>&1; then
  104. ## Preview as text conversion
  105. pdftotext -l 10 -nopgbrk -q -- "${FPATH}" - | less -R
  106. exit 0
  107. elif which mutool >/dev/null 2>&1; then
  108. mutool draw -F txt -i -- "${FPATH}" 1-10
  109. exit 0
  110. elif which exiftool >/dev/null 2>&1; then
  111. exiftool "${FPATH}" | less -R
  112. exit 0
  113. fi
  114. exit 1;;
  115. ## M4A audio
  116. m4a)
  117. if which mocp >/dev/null 2>&1; then
  118. mocplay "${FPATH}" >/dev/null 2>&1
  119. exit 0
  120. elif which mpv >/dev/null 2>&1; then
  121. mpv "${FPATH}" >/dev/null 2>&1 &
  122. exit 0
  123. elif which mediainfo >/dev/null 2>&1; then
  124. mediainfo "${FPATH}" | less -R
  125. exit 0
  126. elif which exiftool >/dev/null 2>&1; then
  127. exiftool "${FPATH}"| less -R
  128. exit 0
  129. fi
  130. exit 1;;
  131. ## BitTorrent
  132. torrent)
  133. if which transmission-show >/dev/null 2>&1; then
  134. transmission-show -- "${FPATH}"
  135. exit 0
  136. fi
  137. exit 1;;
  138. ## OpenDocument
  139. odt|ods|odp|sxw)
  140. if which odt2txt >/dev/null 2>&1; then
  141. ## Preview as text conversion
  142. odt2txt "${FPATH}" | less -R
  143. exit 0
  144. fi
  145. exit 1;;
  146. ## HTML
  147. htm|html|xhtml)
  148. ## Preview as text conversion
  149. if which w3m >/dev/null 2>&1; then
  150. w3m -dump "${FPATH}" | less -R
  151. exit 0
  152. elif which lynx >/dev/null 2>&1; then
  153. lynx -dump -- "${FPATH}" | less -R
  154. exit 0
  155. elif which elinks >/dev/null 2>&1; then
  156. elinks -dump "${FPATH}" | less -R
  157. exit 0
  158. fi
  159. ;;
  160. ## JSON
  161. json)
  162. if which jq >/dev/null 2>&1; then
  163. jq --color-output . "${FPATH}" | less -R
  164. exit 0
  165. elif which python >/dev/null 2>&1; then
  166. python -m json.tool -- "${FPATH}" | less -R
  167. exit 0
  168. fi
  169. ;;
  170. esac
  171. }
  172. handle_multimedia() {
  173. ## Size of the preview if there are multiple options or it has to be
  174. ## rendered from vector graphics. If the conversion program allows
  175. ## specifying only one dimension while keeping the aspect ratio, the width
  176. ## will be used.
  177. # local DEFAULT_SIZE="1920x1080"
  178. mimetype="${1}"
  179. case "${mimetype}" in
  180. ## SVG
  181. # image/svg+xml|image/svg)
  182. # convert -- "${FPATH}" "${IMAGE_CACHE_PATH}" && exit 6
  183. # exit 1;;
  184. ## DjVu
  185. # image/vnd.djvu)
  186. # ddjvu -format=tiff -quality=90 -page=1 -size="${DEFAULT_SIZE}" \
  187. # - "${IMAGE_CACHE_PATH}" < "${FPATH}" \
  188. # && exit 6 || exit 1;;
  189. ## Image
  190. image/*)
  191. if [ $GUI -ne 0 ] && which sxiv >/dev/null 2>&1; then
  192. sxiv -q "$1" "$(dirname "${FPATH}")" &
  193. exit 0
  194. elif which viu >/dev/null 2>&1; then
  195. viu -n "${FPATH}" | less -R
  196. exit 0
  197. elif which img2txt >/dev/null 2>&1; then
  198. img2txt --gamma=0.6 -- "${FPATH}" | less -R
  199. exit 0
  200. elif which exiftool >/dev/null 2>&1; then
  201. exiftool "${FPATH}" | less -R
  202. exit 0
  203. fi
  204. # local orientation
  205. # orientation="$( identify -format '%[EXIF:Orientation]\n' -- "${FPATH}" )"
  206. ## If orientation data is present and the image actually
  207. ## needs rotating ("1" means no rotation)...
  208. # if [[ -n "$orientation" && "$orientation" != 1 ]]; then
  209. ## ...auto-rotate the image according to the EXIF data.
  210. # convert -- "${FPATH}" -auto-orient "${IMAGE_CACHE_PATH}" && exit 6
  211. # fi
  212. ## `w3mimgdisplay` will be called for all images (unless overriden
  213. ## as above), but might fail for unsupported types.
  214. exit 7;;
  215. ## Video
  216. video/*)
  217. if [ $GUI -ne 0 ] && which smplayer >/dev/null 2>&1; then
  218. smplayer "${FPATH}" >/dev/null 2>&1 &
  219. exit 0
  220. elif [ $GUI -ne 0 ] && which mpv >/dev/null 2>&1; then
  221. mpv "${FPATH}" >/dev/null 2>&1 &
  222. exit 0
  223. elif which ffmpegthumbnailer >/dev/null 2>&1; then
  224. # Thumbnail
  225. [ -d "${IMAGE_CACHE_PATH}" ] || mkdir "${IMAGE_CACHE_PATH}"
  226. ffmpegthumbnailer -i "${FPATH}" -o "${IMAGE_CACHE_PATH}/${FNAME}.jpg" -s 0
  227. viu -n "${IMAGE_CACHE_PATH}/${FNAME}.jpg" | less -R
  228. exit 0
  229. elif which mediainfo >/dev/null 2>&1; then
  230. mediainfo "${FPATH}" | less -R
  231. exit 0
  232. elif which exiftool >/dev/null 2>&1; then
  233. exiftool "${FPATH}"| less -R
  234. exit 0
  235. fi
  236. exit 1;;
  237. ## Audio
  238. audio/*)
  239. if which mocp >/dev/null 2>&1; then
  240. mocplay "${FPATH}" >/dev/null 2>&1
  241. exit 0
  242. elif which mpv >/dev/null 2>&1; then
  243. mpv "${FPATH}" >/dev/null 2>&1 &
  244. exit 0
  245. elif which mediainfo >/dev/null 2>&1; then
  246. mediainfo "${FPATH}" | less -R
  247. exit 0
  248. elif which exiftool >/dev/null 2>&1; then
  249. exiftool "${FPATH}"| less -R
  250. exit 0
  251. fi
  252. exit 1;;
  253. ## PDF
  254. application/pdf)
  255. if [ $GUI -ne 0 ] && which zathura >/dev/null 2>&1; then
  256. zathura "${FPATH}" >/dev/null 2>&1 &
  257. exit 0
  258. elif which pdftotext >/dev/null 2>&1; then
  259. ## Preview as text conversion
  260. pdftotext -l 10 -nopgbrk -q -- "${FPATH}" - | less -R
  261. exit 0
  262. elif which mutool >/dev/null 2>&1; then
  263. mutool draw -F txt -i -- "${FPATH}" 1-10 | less -R
  264. exit 0
  265. elif which exiftool >/dev/null 2>&1; then
  266. exiftool "${FPATH}" | less -R
  267. exit 0
  268. fi
  269. exit 1;;
  270. # pdftoppm -f 1 -l 1 \
  271. # -scale-to-x "${DEFAULT_SIZE%x*}" \
  272. # -scale-to-y -1 \
  273. # -singlefile \
  274. # -jpeg -tiffcompression jpeg \
  275. # -- "${FPATH}" "${IMAGE_CACHE_PATH%.*}" \
  276. # && exit 6 || exit 1;;
  277. ## ePub, MOBI, FB2 (using Calibre)
  278. # application/epub+zip|application/x-mobipocket-ebook|\
  279. # application/x-fictionbook+xml)
  280. # # ePub (using https://github.com/marianosimone/epub-thumbnailer)
  281. # epub-thumbnailer "${FPATH}" "${IMAGE_CACHE_PATH}" \
  282. # "${DEFAULT_SIZE%x*}" && exit 6
  283. # ebook-meta --get-cover="${IMAGE_CACHE_PATH}" -- "${FPATH}" \
  284. # >/dev/null && exit 6
  285. # exit 1;;
  286. ## Font
  287. # application/font*|application/*opentype)
  288. # preview_png="/tmp/$(basename "${IMAGE_CACHE_PATH%.*}").png"
  289. # if fontimage -o "${preview_png}" \
  290. # --pixelsize "120" \
  291. # --fontname \
  292. # --pixelsize "80" \
  293. # --text " ABCDEFGHIJKLMNOPQRSTUVWXYZ " \
  294. # --text " abcdefghijklmnopqrstuvwxyz " \
  295. # --text " 0123456789.:,;(*!?') ff fl fi ffi ffl " \
  296. # --text " The quick brown fox jumps over the lazy dog. " \
  297. # "${FPATH}";
  298. # then
  299. # convert -- "${preview_png}" "${IMAGE_CACHE_PATH}" \
  300. # && rm "${preview_png}" \
  301. # && exit 6
  302. # else
  303. # exit 1
  304. # fi
  305. # ;;
  306. ## Preview archives using the first image inside.
  307. ## (Very useful for comic book collections for example.)
  308. # application/zip|application/x-rar|application/x-7z-compressed|\
  309. # application/x-xz|application/x-bzip2|application/x-gzip|application/x-tar)
  310. # local fn=""; local fe=""
  311. # local zip=""; local rar=""; local tar=""; local bsd=""
  312. # case "${mimetype}" in
  313. # application/zip) zip=1 ;;
  314. # application/x-rar) rar=1 ;;
  315. # application/x-7z-compressed) ;;
  316. # *) tar=1 ;;
  317. # esac
  318. # { [ "$tar" ] && fn=$(tar --list --file "${FPATH}"); } || \
  319. # { fn=$(bsdtar --list --file "${FPATH}") && bsd=1 && tar=""; } || \
  320. # { [ "$rar" ] && fn=$(unrar lb -p- -- "${FPATH}"); } || \
  321. # { [ "$zip" ] && fn=$(zipinfo -1 -- "${FPATH}"); } || return
  322. #
  323. # fn=$(echo "$fn" | python -c "import sys; import mimetypes as m; \
  324. # [ print(l, end='') for l in sys.stdin if \
  325. # (m.guess_type(l[:-1])[0] or '').startswith('image/') ]" |\
  326. # sort -V | head -n 1)
  327. # [ "$fn" = "" ] && return
  328. # [ "$bsd" ] && fn=$(printf '%b' "$fn")
  329. #
  330. # [ "$tar" ] && tar --extract --to-stdout \
  331. # --file "${FPATH}" -- "$fn" > "${IMAGE_CACHE_PATH}" && exit 6
  332. # fe=$(echo -n "$fn" | sed 's/[][*?\]/\\\0/g')
  333. # [ "$bsd" ] && bsdtar --extract --to-stdout \
  334. # --file "${FPATH}" -- "$fe" > "${IMAGE_CACHE_PATH}" && exit 6
  335. # [ "$bsd" ] || [ "$tar" ] && rm -- "${IMAGE_CACHE_PATH}"
  336. # [ "$rar" ] && unrar p -p- -inul -- "${FPATH}" "$fn" > \
  337. # "${IMAGE_CACHE_PATH}" && exit 6
  338. # [ "$zip" ] && unzip -pP "" -- "${FPATH}" "$fe" > \
  339. # "${IMAGE_CACHE_PATH}" && exit 6
  340. # [ "$rar" ] || [ "$zip" ] && rm -- "${IMAGE_CACHE_PATH}"
  341. # ;;
  342. esac
  343. }
  344. handle_mime() {
  345. mimetype="${1}"
  346. case "${mimetype}" in
  347. ## Text
  348. text/* | */xml)
  349. vi "${FPATH}"
  350. exit 1;;
  351. ## Syntax highlight
  352. # if [[ "$( stat --printf='%s' -- "${FPATH}" )" -gt "${HIGHLIGHT_SIZE_MAX}" ]]; then
  353. # exit 2
  354. # fi
  355. # if [[ "$( tput colors )" -ge 256 ]]; then
  356. # local pygmentize_format='terminal256'
  357. # local highlight_format='xterm256'
  358. # else
  359. # local pygmentize_format='terminal'
  360. # local highlight_format='ansi'
  361. # fi
  362. # env HIGHLIGHT_OPTIONS="${HIGHLIGHT_OPTIONS}" highlight \
  363. # --out-format="${highlight_format}" \
  364. # --force -- "${FPATH}" && exit 5
  365. # pygmentize -f "${pygmentize_format}" -O "style=${PYGMENTIZE_STYLE}"\
  366. # -- "${FPATH}" && exit 5
  367. # exit 2;;
  368. ## DjVu
  369. image/vnd.djvu)
  370. if which djvutxt >/dev/null 2>&1; then
  371. ## Preview as text conversion (requires djvulibre)
  372. djvutxt "${FPATH}" | less -R
  373. exit 0
  374. elif which exiftool >/dev/null 2>&1; then
  375. exiftool "${FPATH}" | less -R
  376. exit 0
  377. fi
  378. exit 1;;
  379. esac
  380. }
  381. handle_fallback() {
  382. if [ $GUI -ne 0 ]; then
  383. xdg-open "${FPATH}" >/dev/null 2>&1 &
  384. exit 0
  385. fi
  386. echo '----- File details -----' && file --dereference --brief -- "${FPATH}"
  387. exit 1
  388. }
  389. MIMETYPE="$( file --dereference --brief --mime-type -- "${FPATH}" )"
  390. handle_extension
  391. handle_multimedia "${MIMETYPE}"
  392. handle_mime "${MIMETYPE}"
  393. handle_fallback
  394. exit 1