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.6 KiB

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