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

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