__fzf_complete.fish 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. ##
  2. # Use fzf as fish completion widget.
  3. #
  4. #
  5. # When FZF_COMPLETE variable is set, fzf is used as completion
  6. # widget for the fish shell by binding the TAB key.
  7. #
  8. # FZF_COMPLETE can have some special numeric values:
  9. #
  10. # `set FZF_COMPLETE 0` basic widget accepts with TAB key
  11. # `set FZF_COMPLETE 1` extends 0 with candidate preview window
  12. # `set FZF_COMPLETE 2` same as 1 but TAB walks on candidates
  13. # `set FZF_COMPLETE 3` multi TAB selection, RETURN accepts selected ones.
  14. #
  15. # Any other value of FZF_COMPLETE is given directly as options to fzf.
  16. #
  17. # If you prefer to set more advanced options, take a look at the
  18. # `__fzf_complete_opts` function and override that in your environment.
  19. # modified from https://github.com/junegunn/fzf/wiki/Examples-(fish)#completion
  20. function __fzf_complete -d 'fzf completion and print selection back to commandline'
  21. # As of 2.6, fish's "complete" function does not understand
  22. # subcommands. Instead, we use the same hack as __fish_complete_subcommand and
  23. # extract the subcommand manually.
  24. set -l cmd (commandline -co) (commandline -ct)
  25. switch $cmd[1]
  26. case env sudo
  27. for i in (seq 2 (count $cmd))
  28. switch $cmd[$i]
  29. case '-*'
  30. case '*=*'
  31. case '*'
  32. set cmd $cmd[$i..-1]
  33. break
  34. end
  35. end
  36. end
  37. set -l cmd_lastw $cmd[-1]
  38. set cmd (string join -- ' ' $cmd)
  39. set -l initial_query ''
  40. test -n "$cmd_lastw"; and set initial_query --query="$cmd_lastw"
  41. set -l complist (complete -C$cmd)
  42. set -l result
  43. # do nothing if there is nothing to select from
  44. test -z "$complist"; and return
  45. set -l compwc (echo $complist | wc -w)
  46. if test $compwc -eq 1
  47. # if there is only one option dont open fzf
  48. set result "$complist"
  49. else
  50. set -l query
  51. string join -- \n $complist \
  52. | sort \
  53. | eval (__fzfcmd) $initial_query --print-query (__fzf_complete_opts) \
  54. | cut -f1 \
  55. | while read -l r
  56. # first line is the user entered query
  57. if test -z "$query"
  58. set query $r
  59. # rest of lines are selected candidates
  60. else
  61. set result $result $r
  62. end
  63. end
  64. # exit if user canceled
  65. if test -z "$query" ;and test -z "$result"
  66. return
  67. end
  68. # if user accepted but no candidate matches, use the input as result
  69. if test -z "$result"
  70. set result $query
  71. end
  72. end
  73. set prefix (string sub -s 1 -l 1 -- (commandline -t))
  74. for i in (seq (count $result))
  75. set -l r $result[$i]
  76. switch $prefix
  77. case "'"
  78. commandline -t -- (string escape -- $r)
  79. case '"'
  80. if string match '*"*' -- $r >/dev/null
  81. commandline -t -- (string escape -- $r)
  82. else
  83. commandline -t -- '"'$r'"'
  84. end
  85. case '~'
  86. commandline -t -- (string sub -s 2 (string escape -n -- $r))
  87. case '*'
  88. commandline -t -- (string escape -n -- $r)
  89. end
  90. [ $i -lt (count $result) ]; and commandline -i ' '
  91. end
  92. commandline -f repaint
  93. end
  94. function __fzf_complete_opts_common
  95. echo --cycle --reverse --inline-info
  96. end
  97. function __fzf_complete_opts_tab_accepts
  98. echo --bind tab:accept,btab:cancel
  99. end
  100. function __fzf_complete_opts_tab_walks
  101. echo --bind tab:down,btab:up
  102. end
  103. function __fzf_complete_opts_preview
  104. set -l file (status -f)
  105. echo --with-nth=1 --preview-window=right:wrap --preview="fish\ '$file'\ __fzf_complete_preview\ '{1}'\ '{2..}'"
  106. end
  107. test "$argv[1]" = "__fzf_complete_preview"; and __fzf_complete_preview $argv[2..3]
  108. function __fzf_complete_opts_0 -d 'basic single selection with tab accept'
  109. __fzf_complete_opts_common
  110. echo --no-multi
  111. __fzf_complete_opts_tab_accepts
  112. end
  113. function __fzf_complete_opts_1 -d 'single selection with preview and tab accept'
  114. __fzf_complete_opts_0
  115. __fzf_complete_opts_preview
  116. end
  117. function __fzf_complete_opts_2 -d 'single selection with preview and tab walks'
  118. __fzf_complete_opts_1
  119. __fzf_complete_opts_tab_walks
  120. end
  121. function __fzf_complete_opts_3 -d 'multi selection with preview'
  122. __fzf_complete_opts_common
  123. echo --multi
  124. __fzf_complete_opts_preview
  125. end
  126. function __fzf_complete_opts -d 'fzf options for fish tab completion'
  127. switch $FZF_COMPLETE
  128. case 0
  129. __fzf_complete_opts_0
  130. case 1
  131. __fzf_complete_opts_1
  132. case 2
  133. __fzf_complete_opts_2
  134. case 3
  135. __fzf_complete_opts_3
  136. case '*'
  137. echo $FZF_COMPLETE
  138. end
  139. end