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.
 
 
 
 
 
 

424 lignes
15 KiB

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