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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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. 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