forked from seletskiy/zsh-fuzzy-search-and-edit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplugin.zsh
129 lines (106 loc) · 3.65 KB
/
plugin.zsh
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
if [[ "$OSTYPE" == "freebsd"* ]]; then
grep_bin='/usr/local/bin/grep'
if [[ ! -f $grep_bin ]]; then
echo "Try install GNU grep: pkg install gnugrep"
return
fi
pattern='s/^([^:]+:[^:]+):\s*(.*)/\1: \2/'
else
grep_bin='grep'
pattern='s/^([^:]+:[^:]+):\s*(.*)/\x1b[35m\1\x1b[0m: \2/'
fi
function :fuzzy-search-and-edit:get-files() {
local directory="$1"
local fifo="$2"
cd "$directory"
command $grep_bin -r -nEHI '[[:alnum:]]' "." --exclude-dir=".git" \
| cut -b3- \
| command sed -ru $pattern > "$fifo"
}
function :fuzzy-search-and-edit:abort-job() {
local match
read -r match
printf "%s\n" "$match"
async_flush_jobs ":fuzzy-search-and-edit:worker"
}
function fuzzy-search-and-edit() {
local dir="$(mktemp -d /tmp/fuzzy-search-and-edit.XXXXXX)"
local fifo="$dir/fifo"
mkfifo "$fifo"
async_job ":fuzzy-search-and-edit:worker" ":fuzzy-search-and-edit:get-files" "$(pwd)" "$fifo"
local match=$(
fzf --ansi -1 < "$fifo" \
| :fuzzy-search-and-edit:abort-job
)
if [ "$match" ]; then
local file
local line
IFS=: read -r file line _ <<< "$match"
# set defaults for the editor opening
local editortouse='${EDITOR}'
local linefmt="+%L"
local filefmt="%F"
local usetty=true
# high level options
if zstyle -t ':fuzzy-search-and-edit:editor' use-visual ; then
usetty=false
# only if VISUAL_EDITOR variable is set
if [ -v VISUAL_EDITOR ] ; then
editortouse='${VISUAL_EDITOR}'
fi
# else keep the default
fi
if zstyle -t ':fuzzy-search-and-edit:editor' alternate-line-syntax ; then
linefmt=""
filefmt="%F:%L"
fi
local tmpval=''
# low-level options that will override all others
if zstyle -s ':fuzzy-search-and-edit:editor:invocation-format' editor tmpval ; then
editortouse="${tmpval}"
fi
if zstyle -s ':fuzzy-search-and-edit:editor:invocation-format' line tmpval ; then
linefmt="${tmpval}"
fi
if zstyle -s ':fuzzy-search-and-edit:editor:invocation-format' file tmpval ; then
filefmt="${tmpval}"
fi
if zstyle -t ':fuzzy-search-and-edit:editor:invocation-format' without-tty ; then
usetty=false
fi
# parse the file and line format specifiers
local linetouse=""
local filetouse=""
zformat -f linetouse "${linefmt}" L:${line} F:${file}
zformat -f filetouse "${filefmt}" L:${line} F:${file}
# construct the command-line.
local cmdtorun=()
# split the full expansion of editortouse and put each space separated argument into the array separately
for A in ${(z)${(e)editortouse}} ; do
cmdtorun+=(${A})
done
# append the options only if they aren't blank to avoid cases that don't parse properly like:
# myeditor "" "myfile.txt:80"
if [ -n "${linetouse}" ] ; then
cmdtorun+=(${linetouse})
fi
if [ -n "${filetouse}" ] ; then
cmdtorun+=(${filetouse})
fi
# run it, quoting each array element and providing tty if necessary
if ${usetty} ; then
"${cmdtorun[@]}" </dev/tty
else
"${cmdtorun[@]}"
fi
fi
rm -r "$dir"
zle -I
}
:fuzzy-search-and-edit:completed() {
:
}
async_start_worker ":fuzzy-search-and-edit:worker"
async_register_callback ":fuzzy-search-and-edit:worker" \
":fuzzy-search-and-edit:completed"
zle -N fuzzy-search-and-edit