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.
 
 
 
 
 
 

198 lignes
5.5 KiB

  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. XDOTOOL_TIMEOUT=2
  48. PAGER=${PAGER:-"vim -R"}
  49. NUKE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins/nuke"
  50. if which xterm ; then
  51. TERMINAL="xterm -into"
  52. elif which urxvt ; then
  53. TERMINAL="urxvt -embed"
  54. elif which st ; then
  55. TERMINAL="st -w"
  56. else
  57. echo "No xembed term found" >&2
  58. fi
  59. term_nuke () {
  60. # $1 -> $XID, $2 -> $FILE
  61. $TERMINAL "$1" -e "$NUKE" "$2" &
  62. }
  63. start_tabbed () {
  64. FIFO="$(mktemp -u)"
  65. mkfifo "$FIFO"
  66. tabbed > "$FIFO" &
  67. jobs # Get rid of the "Completed" entries
  68. TABBEDPID="$(jobs -p %%)"
  69. if [ -z "$TABBEDPID" ] ; then
  70. echo "Can't start tabbed"
  71. exit 1
  72. fi
  73. read -r XID < "$FIFO"
  74. rm "$FIFO"
  75. }
  76. get_viewer_pid () {
  77. VIEWERPID="$(jobs -p %%)"
  78. }
  79. previewer_loop () {
  80. unset -v NNN_FIFO
  81. # mute from now
  82. exec >/dev/null 2>&1
  83. MAINWINDOW="$(xdotool getactivewindow)"
  84. start_tabbed
  85. xdotool windowactivate "$MAINWINDOW"
  86. # Bruteforce focus stealing prevention method,
  87. # works well in floating window managers like XFCE
  88. # but make interaction with the preview window harder
  89. # (uncomment to use):
  90. #xdotool behave "$XID" focus windowactivate "$MAINWINDOW" &
  91. while read -r FILE ; do
  92. jobs # Get rid of the "Completed" entries
  93. if ! jobs | grep tabbed ; then
  94. break
  95. fi
  96. if [ ! -e "$FILE" ] ; then
  97. continue
  98. fi
  99. if [ -n "$VIEWERPID" ] && jobs -p | grep "$VIEWERPID" ; then
  100. kill "$VIEWERPID"
  101. fi
  102. MIME="$(file -b --mime-type "$FILE")"
  103. case "$MIME" in
  104. video/*)
  105. if which mpv ; then
  106. mpv --force-window=immediate --loop-file --wid="$XID" "$FILE" &
  107. else
  108. term_nuke "$XID" "$FILE"
  109. fi
  110. ;;
  111. audio/*)
  112. if which mpv ; then
  113. mpv --force-window=immediate --loop-file --wid="$XID" "$FILE" &
  114. else
  115. term_nuke "$XID" "$FILE"
  116. fi
  117. ;;
  118. image/*)
  119. if which sxiv ; then
  120. sxiv -e "$XID" "$FILE" &
  121. else
  122. term_nuke "$XID" "$FILE"
  123. fi
  124. ;;
  125. application/pdf)
  126. if which zathura ; then
  127. zathura -e "$XID" "$FILE" &
  128. else
  129. term_nuke "$XID" "$FILE"
  130. fi
  131. ;;
  132. inode/directory)
  133. $TERMINAL "$XID" -e nnn "$FILE" &
  134. ;;
  135. text/*)
  136. if [ -x "$NUKE" ] ; then
  137. term_nuke "$XID" "$FILE"
  138. else
  139. # shellcheck disable=SC2086
  140. $TERMINAL "$XID" -e $PAGER "$FILE" &
  141. fi
  142. ;;
  143. *)
  144. if [ -x "$NUKE" ] ; then
  145. term_nuke "$XID" "$FILE"
  146. else
  147. $TERMINAL "$XID" -e sh -c "file '$FILE' | $PAGER -" &
  148. fi
  149. ;;
  150. esac
  151. get_viewer_pid
  152. # following lines are not needed with the bruteforce xdotool method
  153. ACTIVE_XID="$(xdotool getactivewindow)"
  154. if [ $((ACTIVE_XID == XID)) -ne 0 ] ; then
  155. xdotool windowactivate "$MAINWINDOW"
  156. else
  157. timeout "$XDOTOOL_TIMEOUT" xdotool behave "$XID" focus windowactivate "$MAINWINDOW" &
  158. fi
  159. done
  160. kill "$TABBEDPID"
  161. }
  162. if [ ! -r "$NNN_FIFO" ] ; then
  163. echo "Can't read \$NNN_FIFO ('$NNN_FIFO')"
  164. exit 1
  165. fi
  166. previewer_loop < "$NNN_FIFO" &
  167. disown