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.

preview-tabbed 5.7 KiB

il y a 4 ans
il y a 4 ans
il y a 4 ans
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. #!/usr/bin/env bash
  2. # Description: tabbed/xembed based file previewer
  3. #
  4. # Note: This plugin needs a "NNN_FIFO" to work. See man.
  5. #
  6. # Dependencies:
  7. # - tabbed (https://tools.suckless.org/tabbed): xembed host
  8. # - xterm (or urxvt or st) : xembed client for text-based preview
  9. # - mpv (https://mpv.io): xembed client for video/audio
  10. # - sxiv (https://github.com/muennich/sxiv): xembed client for images
  11. # - zathura (https://pwmt.org/projects/zathura): xembed client for PDF documents
  12. # - nnn's nuke plugin for text preview and fallback (should be in plugins directory)
  13. # nuke is a fallback for 'mpv', 'sxiv', and 'zathura', but it has has its own
  14. # dependencies, see the script itself
  15. # - vim (or any editor/pager really)
  16. # - file
  17. # - mktemp
  18. # - xdotool (optional, to keep main window focused)
  19. #
  20. # How to use:
  21. # First, install the dependencies. Then you need to set a NNN_FIFO path
  22. # and set a key for the plugin, then start `nnn`:
  23. #
  24. # $ NNN_FIFO=/tmp/nnn.fifo nnn
  25. #
  26. # Then in `nnn`, launch the `preview-tabbed` plugin.
  27. #
  28. # If you provide the same NNN_FIFO to all nnn instances, there will be a
  29. # single common preview window. I you provide different FIFO path, they
  30. # will be independent.
  31. #
  32. # How it works:
  33. # We use `tabbed` [1] as a xembed [2] host, to have a single window
  34. # owning each previewer window. So each previewer must be a xembed client.
  35. # For text previewers, this is not an issue, as there are a lot of
  36. # xembed-able terminal emulator (we default to `xterm`, but examples are
  37. # provided for `urxvt` and `st`). For graphic preview this can be trickier,
  38. # but a few popular viewers are xembed-able, we use:
  39. # - `mpv`: multimedia player, for video/audio preview
  40. # - `sxiv`: image viewer
  41. # - `zathura`: PDF viewer
  42. # - but we allways fallback to `nuke` plugin
  43. #
  44. # [1]: http://tools.suckless.org/tabbed/
  45. # [2]: https://specifications.freedesktop.org/xembed-spec/xembed-spec-latest.html
  46. #
  47. # Shell: bash (job control is weakly specified in POSIX)
  48. # Author: Léo Villeveygoux
  49. XDOTOOL_TIMEOUT=2
  50. PAGER=${PAGER:-"vim -R"}
  51. NUKE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins/nuke"
  52. if which xterm >/dev/null 2>&1 ; then
  53. TERMINAL="xterm -into"
  54. elif which urxvt >/dev/null 2>&1 ; then
  55. TERMINAL="urxvt -embed"
  56. elif which st >/dev/null 2>&1 ; then
  57. TERMINAL="st -w"
  58. else
  59. echo "No xembed term found" >&2
  60. fi
  61. term_nuke () {
  62. # $1 -> $XID, $2 -> $FILE
  63. $TERMINAL "$1" -e "$NUKE" "$2" &
  64. }
  65. start_tabbed () {
  66. FIFO="$(mktemp -u)"
  67. mkfifo "$FIFO"
  68. tabbed > "$FIFO" &
  69. jobs # Get rid of the "Completed" entries
  70. TABBEDPID="$(jobs -p %%)"
  71. if [ -z "$TABBEDPID" ] ; then
  72. echo "Can't start tabbed"
  73. exit 1
  74. fi
  75. read -r XID < "$FIFO"
  76. rm "$FIFO"
  77. }
  78. get_viewer_pid () {
  79. VIEWERPID="$(jobs -p %%)"
  80. }
  81. kill_viewer () {
  82. if [ -n "$VIEWERPID" ] && jobs -p | grep "$VIEWERPID" ; then
  83. kill "$VIEWERPID"
  84. fi
  85. }
  86. previewer_loop () {
  87. unset -v NNN_FIFO
  88. # mute from now
  89. exec >/dev/null 2>&1
  90. MAINWINDOW="$(xdotool getactivewindow)"
  91. start_tabbed
  92. xdotool windowactivate "$MAINWINDOW"
  93. # Bruteforce focus stealing prevention method,
  94. # works well in floating window managers like XFCE
  95. # but make interaction with the preview window harder
  96. # (uncomment to use):
  97. #xdotool behave "$XID" focus windowactivate "$MAINWINDOW" &
  98. while read -r FILE ; do
  99. jobs # Get rid of the "Completed" entries
  100. if ! jobs | grep tabbed ; then
  101. break
  102. fi
  103. if [ ! -e "$FILE" ] ; then
  104. continue
  105. fi
  106. kill_viewer
  107. MIME="$(file -b --mime-type "$FILE")"
  108. case "$MIME" in
  109. video/*)
  110. if which mpv >/dev/null 2>&1 ; then
  111. mpv --force-window=immediate --loop-file --wid="$XID" "$FILE" &
  112. else
  113. term_nuke "$XID" "$FILE"
  114. fi
  115. ;;
  116. audio/*)
  117. if which mpv >/dev/null 2>&1 ; then
  118. mpv --force-window=immediate --loop-file --wid="$XID" "$FILE" &
  119. else
  120. term_nuke "$XID" "$FILE"
  121. fi
  122. ;;
  123. image/*)
  124. if which sxiv >/dev/null 2>&1 ; then
  125. sxiv -e "$XID" "$FILE" &
  126. else
  127. term_nuke "$XID" "$FILE"
  128. fi
  129. ;;
  130. application/pdf)
  131. if which zathura >/dev/null 2>&1 ; then
  132. zathura -e "$XID" "$FILE" &
  133. else
  134. term_nuke "$XID" "$FILE"
  135. fi
  136. ;;
  137. inode/directory)
  138. $TERMINAL "$XID" -e nnn "$FILE" &
  139. ;;
  140. text/*)
  141. if [ -x "$NUKE" ] ; then
  142. term_nuke "$XID" "$FILE"
  143. else
  144. # shellcheck disable=SC2086
  145. $TERMINAL "$XID" -e $PAGER "$FILE" &
  146. fi
  147. ;;
  148. *)
  149. if [ -x "$NUKE" ] ; then
  150. term_nuke "$XID" "$FILE"
  151. else
  152. $TERMINAL "$XID" -e sh -c "file '$FILE' | $PAGER -" &
  153. fi
  154. ;;
  155. esac
  156. get_viewer_pid
  157. # following lines are not needed with the bruteforce xdotool method
  158. ACTIVE_XID="$(xdotool getactivewindow)"
  159. if [ $((ACTIVE_XID == XID)) -ne 0 ] ; then
  160. xdotool windowactivate "$MAINWINDOW"
  161. else
  162. timeout "$XDOTOOL_TIMEOUT" xdotool behave "$XID" focus windowactivate "$MAINWINDOW" &
  163. fi
  164. done
  165. kill "$TABBEDPID"
  166. kill_viewer
  167. }
  168. if [ ! -r "$NNN_FIFO" ] ; then
  169. echo "Can't read \$NNN_FIFO ('$NNN_FIFO')"
  170. exit 1
  171. fi
  172. previewer_loop < "$NNN_FIFO" &
  173. disown