Skip to content

Commit 6b31398

Browse files
committed
add shell bindings (copied from fzf and modified)
1 parent 99d4461 commit 6b31398

File tree

6 files changed

+706
-0
lines changed

6 files changed

+706
-0
lines changed

shell/LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2016 Jinzhou Zhang
4+
Copyright (c) 2016 Junegunn Choi
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in
14+
all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
THE SOFTWARE.

shell/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
This direction contains the shell bindings for skim.
2+
3+
Note that the content in this directory is copied from
4+
[fzf](https://github.com/junegunn/fzf/tree/master/shell) and modified to fit
5+
skim.
6+
7+
The scripts in this directory will not be maintained by skim.
8+
9+
But you are welcome to submit PR for update the scripts to the fzf's latest
10+
scripts. Thanks!

shell/completion.bash

Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
#!/bin/bash
2+
# completion.bash
3+
#
4+
# copied and modified from https://github.com/junegunn/fzf/blob/master/shell/completion.bash
5+
#
6+
# - $SKIM_TMUX (default: 0)
7+
# - $SKIM_TMUX_HEIGHT (default: '40%')
8+
# - $SKIM_COMPLETION_TRIGGER (default: '**')
9+
# - $SKIM_COMPLETION_OPTS (default: empty)
10+
11+
# To use custom commands instead of find, override _skim_compgen_{path,dir}
12+
if ! declare -f _skim_compgen_path > /dev/null; then
13+
_skim_compgen_path() {
14+
echo "$1"
15+
command find -L "$1" \
16+
-name .git -prune -o -name .svn -prune -o \( -type d -o -type f -o -type l \) \
17+
-a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
18+
}
19+
fi
20+
21+
if ! declare -f _skim_compgen_dir > /dev/null; then
22+
_skim_compgen_dir() {
23+
command find -L "$1" \
24+
-name .git -prune -o -name .svn -prune -o -type d \
25+
-a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
26+
}
27+
fi
28+
29+
###########################################################
30+
31+
# To redraw line after skim closes (printf '\e[5n')
32+
bind '"\e[0n": redraw-current-line'
33+
34+
__skimcmd_complete() {
35+
[ -n "$TMUX_PANE" ] && [ "${SKIM_TMUX:-0}" != 0 ] && [ ${LINES:-40} -gt 15 ] &&
36+
echo "sk-tmux -d${SKIM_TMUX_HEIGHT:-40%}" || echo "sk"
37+
}
38+
39+
_skim_orig_completion_filter() {
40+
sed 's/^\(.*-F\) *\([^ ]*\).* \([^ ]*\)$/export _skim_orig_completion_\3="\1 %s \3 #\2";/' |
41+
awk -F= '{gsub(/[^A-Za-z0-9_= ;]/, "_", $1); print $1"="$2}'
42+
}
43+
44+
_skim_opts_completion() {
45+
local cur prev opts
46+
COMPREPLY=()
47+
cur="${COMP_WORDS[COMP_CWORD]}"
48+
prev="${COMP_WORDS[COMP_CWORD-1]}"
49+
opts="
50+
-x --extended
51+
-e --exact
52+
--algo
53+
-i +i
54+
-n --nth
55+
--with-nth
56+
-d --delimiter
57+
+s --no-sort
58+
--tac
59+
--tiebreak
60+
-m --multi
61+
--no-mouse
62+
--bind
63+
--cycle
64+
--no-hscroll
65+
--jump-labels
66+
--height
67+
--literal
68+
--reverse
69+
--margin
70+
--inline-info
71+
--prompt
72+
--header
73+
--header-lines
74+
--ansi
75+
--tabstop
76+
--color
77+
--no-bold
78+
--history
79+
--history-size
80+
--preview
81+
--preview-window
82+
-q --query
83+
-1 --select-1
84+
-0 --exit-0
85+
-f --filter
86+
--print-query
87+
--expect
88+
--sync"
89+
90+
case "${prev}" in
91+
--tiebreak)
92+
COMPREPLY=( $(compgen -W "length begin end index" -- "$cur") )
93+
return 0
94+
;;
95+
--color)
96+
COMPREPLY=( $(compgen -W "dark light 16 bw" -- "$cur") )
97+
return 0
98+
;;
99+
--history)
100+
COMPREPLY=()
101+
return 0
102+
;;
103+
esac
104+
105+
if [[ "$cur" =~ ^-|\+ ]]; then
106+
COMPREPLY=( $(compgen -W "${opts}" -- "$cur") )
107+
return 0
108+
fi
109+
110+
return 0
111+
}
112+
113+
_skim_handle_dynamic_completion() {
114+
local cmd orig_var orig ret orig_cmd
115+
cmd="$1"
116+
shift
117+
orig_cmd="$1"
118+
orig_var="_skim_orig_completion_$cmd"
119+
orig="${!orig_var##*#}"
120+
if [ -n "$orig" ] && type "$orig" > /dev/null 2>&1; then
121+
$orig "$@"
122+
elif [ -n "$_skim_completion_loader" ]; then
123+
_completion_loader "$@"
124+
ret=$?
125+
eval "$(complete | command grep "\-F.* $orig_cmd$" | _skim_orig_completion_filter)"
126+
source "${BASH_SOURCE[0]}"
127+
return $ret
128+
fi
129+
}
130+
131+
__skim_generic_path_completion() {
132+
local cur base dir leftover matches trigger cmd skim
133+
skim="$(__skimcmd_complete)"
134+
cmd="${COMP_WORDS[0]//[^A-Za-z0-9_=]/_}"
135+
COMPREPLY=()
136+
trigger=${SKIM_COMPLETION_TRIGGER-'**'}
137+
cur="${COMP_WORDS[COMP_CWORD]}"
138+
if [[ "$cur" == *"$trigger" ]]; then
139+
base=${cur:0:${#cur}-${#trigger}}
140+
eval "base=$base"
141+
142+
dir="$base"
143+
while true; do
144+
if [ -z "$dir" ] || [ -d "$dir" ]; then
145+
leftover=${base/#"$dir"}
146+
leftover=${leftover/#\/}
147+
[ -z "$dir" ] && dir='.'
148+
[ "$dir" != "/" ] && dir="${dir/%\//}"
149+
matches=$(eval "$1 $(printf %q "$dir")" | SKIM_DEFAULT_OPTIONS="--height ${SKIM_TMUX_HEIGHT:-40%} --reverse $SKIM_DEFAULT_OPTIONS $SKIM_COMPLETION_OPTS" $skim $2 -q "$leftover" | while read -r item; do
150+
printf "%q$3 " "$item"
151+
done)
152+
matches=${matches% }
153+
if [ -n "$matches" ]; then
154+
COMPREPLY=( "$matches" )
155+
else
156+
COMPREPLY=( "$cur" )
157+
fi
158+
printf '\e[5n'
159+
return 0
160+
fi
161+
dir=$(dirname "$dir")
162+
[[ "$dir" =~ /$ ]] || dir="$dir"/
163+
done
164+
else
165+
shift
166+
shift
167+
shift
168+
_skim_handle_dynamic_completion "$cmd" "$@"
169+
fi
170+
}
171+
_skim_complete() {
172+
local cur selected trigger cmd skim post
173+
post="$(caller 0 | awk '{print $2}')_post"
174+
type -t "$post" > /dev/null 2>&1 || post=cat
175+
skim="$(__skimcmd_complete)"
176+
cmd="${COMP_WORDS[0]//[^A-Za-z0-9_=]/_}"
177+
trigger=${SKIM_COMPLETION_TRIGGER-'**'}
178+
cur="${COMP_WORDS[COMP_CWORD]}"
179+
if [[ "$cur" == *"$trigger" ]]; then
180+
cur=${cur:0:${#cur}-${#trigger}}
181+
selected=$(cat | SKIM_DEFAULT_OPTIONS="--height ${SKIM_TMUX_HEIGHT:-40%} --reverse $SKIM_DEFAULT_OPTIONS $SKIM_COMPLETION_OPTS" $skim $1 -q "$cur" | $post | tr '\n' ' ')
182+
selected=${selected% } # Strip trailing space not to repeat "-o nospace"
183+
printf '\e[5n'
184+
if [ -n "$selected" ]; then
185+
COMPREPLY=("$selected")
186+
return 0
187+
fi
188+
else
189+
shift
190+
_skim_handle_dynamic_completion "$cmd" "$@"
191+
fi
192+
}
193+
_skim_path_completion() {
194+
__skim_generic_path_completion _skim_compgen_path "-m" "" "$@"
195+
}
196+
# Deprecated. No file only completion.
197+
_skim_file_completion() {
198+
_skim_path_completion "$@"
199+
}
200+
_skim_dir_completion() {
201+
__skim_generic_path_completion _skim_compgen_dir "" "/" "$@"
202+
}
203+
_skim_complete_kill() {
204+
[ -n "${COMP_WORDS[COMP_CWORD]}" ] && return 1
205+
local selected skim
206+
skim="$(__skimcmd_complete)"
207+
selected=$(ps -ef | sed 1d | SKIM_DEFAULT_OPTIONS="--height ${SKIM_TMUX_HEIGHT:-50%} --min-height 15 --reverse $SKIM_DEFAULT_OPTIONS --preview 'echo {}' --preview-window down:3:wrap $SKIM_COMPLETION_OPTS" $skim -m | awk '{print $2}' | tr '\n' ' ')
208+
printf '\e[5n'
209+
if [ -n "$selected" ]; then
210+
COMPREPLY=( "$selected" )
211+
return 0
212+
fi
213+
}
214+
_skim_complete_telnet() {
215+
_skim_complete '-m' "$@" < <(
216+
command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0' |
217+
awk '{if (length($2) > 0) {print $2}}' | sort -u
218+
)
219+
}
220+
_skim_complete_ssh() {
221+
_skim_complete '-m' "$@" < <(
222+
cat <(cat ~/.ssh/config /etc/ssh/ssh_config 2> /dev/null | command grep -i '^host' | command grep -v '*') \
223+
<(command grep -oE '^[a-z0-9.,:-]+' ~/.ssh/known_hosts | tr ',' '\n' | awk '{ print $1 " " $1 }') \
224+
<(command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0') |
225+
awk '{if (length($2) > 0) {print $2}}' | sort -u
226+
)
227+
}
228+
_skim_complete_unset() {
229+
_skim_complete '-m' "$@" < <(
230+
declare -xp | sed 's/=.*//' | sed 's/.* //'
231+
)
232+
}
233+
_skim_complete_export() {
234+
_skim_complete '-m' "$@" < <(
235+
declare -xp | sed 's/=.*//' | sed 's/.* //'
236+
)
237+
}
238+
_skim_complete_unalias() {
239+
_skim_complete '-m' "$@" < <(
240+
alias | sed 's/=.*//' | sed 's/.* //'
241+
)
242+
}
243+
# skim options
244+
complete -o default -F _skim_opts_completion skim
245+
d_cmds="${SKIM_COMPLETION_DIR_COMMANDS:-cd pushd rmdir}"
246+
a_cmds="
247+
awk cat diff diff3
248+
emacs emacsclient ex file ftp g++ gcc gvim head hg java
249+
javac ld less more mvim nvim patch perl python ruby
250+
sed sftp sort source tail tee uniq vi view vim wc xdg-open
251+
basename bunzip2 bzip2 chmod chown curl cp dirname du
252+
find git grep gunzip gzip hg jar
253+
ln ls mv open rm rsync scp
254+
svn tar unzip zip"
255+
x_cmds="kill ssh telnet unset unalias export"
256+
# Preserve existing completion
257+
eval $(complete |
258+
sed -E '/-F/!d; / _skim/d; '"/ ($(echo $d_cmds $a_cmds $x_cmds | sed 's/ /|/g; s/+/\\+/g'))$/"'!d' |
259+
_skim_orig_completion_filter)
260+
if type _completion_loader > /dev/null 2>&1; then
261+
_skim_completion_loader=1
262+
fi
263+
_skim_defc() {
264+
local cmd func opts orig_var orig def
265+
cmd="$1"
266+
func="$2"
267+
opts="$3"
268+
orig_var="_skim_orig_completion_${cmd//[^A-Za-z0-9_]/_}"
269+
orig="${!orig_var}"
270+
if [ -n "$orig" ]; then
271+
printf -v def "$orig" "$func"
272+
eval "$def"
273+
else
274+
complete -F "$func" $opts "$cmd"
275+
fi
276+
}
277+
# Anything
278+
for cmd in $a_cmds; do
279+
_skim_defc "$cmd" _skim_path_completion "-o default -o bashdefault"
280+
done
281+
# Directory
282+
for cmd in $d_cmds; do
283+
_skim_defc "$cmd" _skim_dir_completion "-o nospace -o dirnames"
284+
done
285+
unset _skim_defc
286+
# Kill completion
287+
complete -F _skim_complete_kill -o nospace -o default -o bashdefault kill
288+
# Host completion
289+
complete -F _skim_complete_ssh -o default -o bashdefault ssh
290+
complete -F _skim_complete_telnet -o default -o bashdefault telnet
291+
# Environment variables / Aliases
292+
complete -F _skim_complete_unset -o default -o bashdefault unset
293+
complete -F _skim_complete_export -o default -o bashdefault export
294+
complete -F _skim_complete_unalias -o default -o bashdefault unalias
295+
unset cmd d_cmds a_cmds x_cmds

0 commit comments

Comments
 (0)