My build of nnn with minor changes
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

200 linhas
5.7 KiB

  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