This repository has been archived by the owner on Oct 23, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathfzf.kak
277 lines (237 loc) · 11.1 KB
/
fzf.kak
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# Author: Andrey Listopadov
# This plugin implements fzf mode for Kakoune.
# This mode adds several mappings to invoke different fzf commands.
# https://github.com/andreyorst/fzf.kak
define-command -docstring "Enter fzf-mode.
fzf-mode contains mnemonic key bindings for every fzf.kak command
Best used with mapping like:
map global normal '<some key>' ': fzf-mode<ret>'
" \
fzf-mode %{ require-module fzf; evaluate-commands 'enter-user-mode fzf' }
provide-module fzf %§
# Options
declare-option -docstring 'implementation of fzf that you want to use.
Currently supported implementations:
fzf: github.com/junegunn/fzf
sk: github.com/lotabout/skim' \
str fzf_implementation 'fzf'
declare-option -docstring 'allow showing preview window
Default value:
true
' \
bool fzf_preview true
declare-option -docstring 'preview window position.
Supported values: up (top), down (bottom), left, right, auto
Default value: auto' \
str fzf_preview_pos "auto"
declare-option -docstring 'Highlighter to use in preview window. You can provide
only the name of the tool that you want to use, or specify a command.
Supported tools:
<package>: <value>:
Bat: "bat"
Coderay: "coderay"
Highlight: "highlight"
Rouge: "rouge"
clp: "clp"
These are default arguments for the tools above:
<tool>: <value>:
bat: "bat --color=always --style=plain {}"
coderay: "coderay {}"
highlight: "highlight --failsafe -O ansi {}"
rouge: "rougify {}"
clp: "clp {}"
' \
str fzf_highlight_command "highlight"
declare-option -docstring "height of fzf tmux split in screen lines or percents.
Default value: 25%%" \
str fzf_tmux_height '25%'
declare-option -docstring "width of fzf tmux popup in screen lines or percents.
Default value: 50%%" \
str fzf_tmux_popup_width '50%'
declare-option -docstring "height of fzf tmux split for file preview in screen lines or percents.
Default value: 70%%" \
str fzf_preview_tmux_height '70%'
declare-option -docstring "width of preview window.
Default value: 50%%" \
str fzf_preview_width '50%'
declare-option -docstring "height of preview window.
Default value: 60%%" \
str fzf_preview_height '60%'
declare-option -docstring 'use tmux popup instead of split pane
Default value:
false
' \
bool fzf_tmux_popup false
declare-option -docstring "mapping to execute action in new window" \
str fzf_window_map 'ctrl-w'
declare-option -docstring "mapping to execute action in new vertical split" \
str fzf_vertical_map 'ctrl-v'
declare-option -docstring "mapping to execute action in new horizontal split" \
str fzf_horizontal_map 'ctrl-s'
declare-option -docstring 'command to use to create new window when not using tmux.
Default value: terminal kak -c %val{session} -e "%arg{@}"' \
str fzf_terminal_command 'terminal kak -c %val{session} -e "%arg{@}"'
declare-option -docstring "use main selection as default query for fzf if the selection is longer than 1 char." \
bool fzf_use_main_selection true
declare-option -docstring "Default options for fzf." \
str fzf_default_opts ''
try %{ declare-user-mode fzf }
define-command -hidden -docstring "wrapper command to create new vertical split" \
fzf-vertical -params .. %{ evaluate-commands %{
tmux-terminal-vertical kak -c %val{session} -e "%arg{@}"
}}
define-command -hidden -docstring "wrapper command to create new horizontal split" \
fzf-horizontal -params .. %{ evaluate-commands %{
tmux-terminal-horizontal kak -c %val{session} -e "%arg{@}"
}}
define-command -hidden -docstring "wrapper command to create new terminal" \
fzf-window -params .. %{ evaluate-commands %sh{
if [ -n "${kak_client_env_TMUX:-}" ]; then
printf "%s\n" 'tmux-terminal-window kak -c %val{session} -e "%arg{@}"'
else
printf "%s\n" "${kak_opt_fzf_terminal_command:?}"
fi
}}
define-command -docstring \
"fzf <switches>: generic fzf command. This command can be used to create new fzf wrappers for various Kakoune or external features.
Switches:
-kak-cmd <command>: A Kakoune cmd that is applied to fzf resulting value
-multiple-cmd <command>: A Kakoune cmd that is applied all multiple selected files but the first one
-items-cmd <items command>: A command that is used as a pipe to provide list of values to fzf
-fzf-impl <implementation>: Owerride fzf implementation variable
-fzf-args <args>: Additional flags for fzf program
-preview-cmd <command>: A preview command
-preview: Should fzf window include preview
-filter <commands>: A pipe which will be applied to result provided by fzf
-post-action <commands>: Extra commands that are preformed after `-kak-cmd' command" \
-shell-script-completion %{
printf "%s\n" "-kak-cmd
-multiple-cmd
-items-cmd
-fzf-impl
-fzf-args
-preview-cmd
-preview
-filter
-post-action"
} \
fzf -params .. %{ evaluate-commands %sh{
fzf_impl="${kak_opt_fzf_implementation:?}"
# trims selection and escapes single quotes
selection=$(printf "%s" "${kak_selection:-}" | sed -e "s/^[[:blank:]]*//g;s/[[:blank:]]*$//g;s/'/'\\\\''/g")
[ "${kak_opt_fzf_use_main_selection:-}" = "true" ] && \
[ "$(printf "%s" "$kak_selection" | wc -m)" -gt 1 ] && \
[ "$(printf "%s\n" "$selection" | wc -l)" -eq 1 ] && \
default_query="-i -q '$selection'"
while [ $# -gt 0 ]; do
case $1 in
(-kak-cmd) shift; kakoune_cmd="$1" ;;
(-multiple-cmd) shift; multiple_cmd="$1" ;;
(-items-cmd) shift; items_cmd="$1 |" ;;
(-fzf-impl) shift; fzf_impl="$1" ;;
(-fzf-args) shift; fzf_args="$1" ;;
(-preview-cmd) shift; preview_cmd="$1" ;;
(-preview) preview="true" ;;
(-filter) shift; filter="| $1" ;;
(-post-action) shift; post_action="$1" ;;
esac
shift
done
[ -z "$multiple_cmd" ] && multiple_cmd="$kakoune_cmd"
if [ "${preview}" = "true" ]; then
# bake position option to define them at runtime
[ -n "${kak_client_env_TMUX:-}" ] && tmux_height="${kak_opt_fzf_preview_tmux_height:-}"
case ${kak_opt_fzf_preview_pos:-} in
(top|up) preview_position="pos=top:${kak_opt_fzf_preview_height:-};" ;;
(bottom|down) preview_position="pos=down:${kak_opt_fzf_preview_height:-};" ;;
(right) preview_position="pos=right:${kak_opt_fzf_preview_width:-};" ;;
(left) preview_position="pos=left:${kak_opt_fzf_preview_width:-};" ;;
(auto|*) preview_position="sleep 0.1; [ \$(tput cols) -gt \$(expr \$(tput lines) \* 2) ] && pos=right:${kak_opt_fzf_preview_width:-} || pos=top:${kak_opt_fzf_preview_height:-};"
esac
# handle preview if not defined explicitly with `-preview-cmd'
if [ "${kak_opt_fzf_preview:-}" = "true" ] && [ -z "${preview_cmd}" ]; then
case ${kak_opt_fzf_highlight_command:-} in
(bat) highlight_cmd="bat --color=always --style=plain {}" ;;
(coderay) highlight_cmd="coderay {}" ;;
(highlight) highlight_cmd="highlight --failsafe -O ansi {}" ;;
(rouge) highlight_cmd="rougify {}" ;;
(clp) highlight_cmd="clp {}" ;;
(*) highlight_cmd="${kak_opt_fzf_highlight_command}" ;;
esac
preview_cmd="--preview '(${highlight_cmd} || cat {}) 2>/dev/null' --preview-window=\${pos}:+2-/2"
fi
fi
fzf_tmp=$(mktemp -d "${TMPDIR:-/tmp}"/fzf.kak.XXXXXX)
fzfcmd="${fzf_tmp}/fzfcmd"
result="${fzf_tmp}/result"
(
shell_path="$(command -v sh)"
if [ -n "${shell_path}" ]; then
# portable shebang
printf "%s\n" "#!${shell_path}"
# set SHELL because fzf preview uses it
printf "%s\n" "SHELL=${shell_path}"
fi
# compose entire fzf command with all args into single file which will be executed later
printf "%s\n" "export FZF_DEFAULT_OPTS=\"${kak_opt_fzf_default_opts:-}\""
printf "%s\n" "cd \"${PWD}\" && ${preview_position} ${items_cmd} ${fzf_impl} ${default_query} ${fzf_args} ${preview_cmd} ${filter} > ${result}"
printf "%s\n" "rm ${fzfcmd}"
) >> "${fzfcmd}"
chmod 755 "${fzfcmd}"
if [ -n "${kak_client_env_TMUX}" ]; then
# set default height if not set already
[ -z "${tmux_height}" ] && tmux_height=${kak_opt_fzf_tmux_height:-}
# if popup is enabled use popup otherwise split-window
tmux_command="split-window"
if [ "${kak_opt_fzf_tmux_popup:-}" = "true" ]; then
tmux_command="popup -E"
measure="-h" # popup supports both number of lines or a percentage
popup_width_measure="-w"
popup_width="${kak_opt_fzf_tmux_popup_width}"
# if height contains `%' then `-p' will be used and strip the '%' from tmux_height
elif [ -n "${tmux_height%%*%}" ]; then
measure="-l"
else
measure="-p"
tmux_height="${tmux_height%%%*}"
fi
# `terminal' doesn't support any kind of width and height parameters, so tmux panes are created by tmux itself
cmd="nop %sh{ command tmux ${tmux_command} -t '${kak_client_env_TMUX_PANE:-}' ${measure} ${tmux_height} ${popup_width_measure} ${popup_width} env ${fzfcmd} < /dev/null > /dev/null 2>&1 }"
echo $cmd > /tmp/fzf.kak.test
else
cmd="${kak_opt_fzf_terminal_command%% *} %{${fzfcmd}}"
fi
printf "%s\n" "${cmd}"
# main loop
( while [ -e "${fzfcmd}" ]; do sleep 0.1; done
if [ -s "${result}" ]; then
(
while read -r line; do
case ${line} in
("${kak_opt_fzf_window_map:-ctrl-w}") wincmd="fzf-window" ;;
("${kak_opt_fzf_vertical_map:-ctrl-v}") wincmd="fzf-vertical" ;;
("${kak_opt_fzf_horizontal_map:-ctrl-s}") wincmd="fzf-horizontal" ;;
(*) item=${line} ;;
esac
if [ -n "${item}" ]; then
item=$(printf "%s\n" "${item}" | sed "s/@/@@/g;s/&/&&/g")
kakoune_cmd=$(printf "%s\n" "${kakoune_cmd}" | sed "s/&/&&/g")
printf "%s\n" "evaluate-commands -client ${kak_client:?} ${wincmd} %&${kakoune_cmd} %@${item}@&"
break
fi
done
[ -n "${multiple_cmd}" ] && multiple_cmd=$(printf "%s\n" "${multiple_cmd}" | sed "s/&/&&/g")
while read -r line; do
line=$(printf "%s\n" "${line}" | sed "s/@/@@/g;s/&/&&/g")
printf "%s\n" "evaluate-commands -client ${kak_client} ${wincmd} %&${multiple_cmd} %@${line}@&"
done
if [ -n "${post_action}" ]; then
post_action=$(printf "%s\n" "${post_action}" | sed "s/&/&&/g")
printf "%s\n" "evaluate-commands -client ${kak_client} %&${post_action}&"
fi
) < "${result}" | kak -p "${kak_session:?}"
fi
rm -rf "${fzf_tmp}"
) > /dev/null 2>&1 < /dev/null &
}}
§