-
-
Notifications
You must be signed in to change notification settings - Fork 154
Expand file tree
/
Copy pathquickfix.vim
More file actions
145 lines (122 loc) · 4.05 KB
/
quickfix.vim
File metadata and controls
145 lines (122 loc) · 4.05 KB
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
function! phpactor#quickfix#vim(entries) abort
call setqflist(a:entries)
cw
endfunction
function! phpactor#quickfix#build(entries) abort
try
let strategy = g:phpactorQuickfixStrategy
call call(strategy, [a:entries])
catch /E117/
redraw!
echo 'The strategy "'. string(strategy) .'" is unknown, check the value of "g:phpactorQuickfixStrategy".'
endtry
endfunction
function! phpactor#quickfix#fzf(entries) abort
" Associate each entry data with a unique key
let entries = {}
" Keep track of the order of the entries by their key
let sortedKeys = []
for entry in a:entries
let key = s:relative_path(entry['filename'])
\ .':'. entry['lnum']
\ .':'. (entry['col'])
\ .':'. entry['text']
let entries[key] = entry
call add(sortedKeys, key)
endfor
let formatedEntries = s:align_pairs(sortedKeys, '^\(.\{-}:\d\+:\d\+:\)\s*\(.*\)\s*$', 100)
let tmp = copy(entries)
let entries = {}
let source = [] " Need a list to keep the order (dict does not guarantee it)
for key in sortedKeys
let newKey = formatedEntries[key]
let entries[newKey] = tmp[key]
call add(source, newKey)
endfor
unlet tmp
let actions = {
\ 'ctrl-t': 'tab split',
\ 'ctrl-x': 'split',
\ 'ctrl-v': 'vsplit',
\ 'ctrl-q': function('phpactor#quickfix#vim')
\ }
call fzf#run(fzf#wrap('find_references', fzf#vim#with_preview({
\ 'source': source,
\ 'down': '60%',
\ '_action': actions,
\ 'sink*': function('<SID>quickfix_sink', [entries, actions]),
\ 'options': [
\ '--exit-0',
\ '--expect='. join(keys(actions), ','),
\ '--multi',
\ '--bind=ctrl-a:select-all,ctrl-d:deselect-all',
\ '--inline-info',
\ '--header', ":: Press \x1b[35mCTRL-Q\x1b[m to open the quickfix with your selection",
\ '--delimiter=:', '--nth=1,4',
\ '--reverse'
\ ]}, 'up', '?'), 1))
endfunction
function! s:quickfix_sink(results, actions, lines) abort
if 2 > len(a:lines)
" Don't know how to handle this, should not append
return
endif
let actionKey = remove(a:lines, 0)
let Action = get(a:actions, actionKey, 'e')
let items = map(copy(a:lines), {key, value -> a:results[value]})
if type(function('call')) == type(Action)
return Action(items)
endif
if len(a:lines) > 1
augroup fzf_swap
autocmd SwapExists * let v:swapchoice='o' | echohl WarningMsg
\| echom 'fzf: E325: swap file exists: '. expand('<afile>')
\| echohl None
augroup END
endif
try
let empty = empty(expand('%')) && 1 == line('$') && empty(getline(1)) && !&modified
let autochdir = &autochdir
set noautochdir
for item in items
let filename = fnameescape(item.filename)
let Action = empty ? 'e' : Action " Use the current buffer if empty
execute Action '+'.item.lnum filename
execute 'normal!' item.col .'|'
normal! zz
if empty
let empty = v:false
endif
if !has('patch-8.0.0177') && !has('nvim-0.2') && exists('#BufEnter')
\ && isdirectory(item.filename)
doautocmd BufEnter
endif
endfor
catch /^Vim:Interrupt$/
finally
let &autochdir = autochdir
silent! autocmd! fzf_swap
endtry
endfunction
function! s:align_pairs(list, regexp, ...) abort
let maxlen = 0
let pairs = {}
for elem in a:list
let match = matchlist(elem, a:regexp)
let [filename, text] = match[1:2]
let maxlen = max([maxlen, len(filename)])
let pairs[elem] = [filename, text]
endfor
let args = copy(a:000)
let max = 60
if 0 < len(args) && type(v:t_number) == type(args[0])
let max = remove(args, 0)
endif
let maxlen = min([maxlen, max])
return map(pairs, "printf('%-'.maxlen.'s', v:val[0]).' '.v:val[1]")
endfunction
function! s:relative_path(absolute_path)
let l:cwd = getcwd()
return substitute(a:absolute_path, l:cwd .'/', '', '')
endfunction
" vim: et ts=4 sw=4 fdm=marker