-
Notifications
You must be signed in to change notification settings - Fork 39
Expand file tree
/
Copy pathhandler.lua
More file actions
280 lines (252 loc) · 7.88 KB
/
handler.lua
File metadata and controls
280 lines (252 loc) · 7.88 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
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
278
279
280
---@class BqfQfWinHandler
local M = {}
local api = vim.api
local cmd = vim.cmd
local fn = vim.fn
local qfs = require('bqf.qfwin.session')
local utils = require('bqf.utils')
function M.signReset()
local qwinid = api.nvim_get_current_win()
local qs = qfs:get(qwinid)
local qlist = qs:list()
local sign = qlist:sign()
sign:reset()
end
---
---@param rel number
---@param lnum? number
---@param bufnr? number
function M.signToggle(rel, lnum, bufnr)
local lnums = {}
local count = vim.v.count1
if not lnum then
local cursor = api.nvim_win_get_cursor(0)
local step = rel > 0 and 1 or -1
local endI
if step == 1 then
endI = math.min(cursor[1] + count - 1, api.nvim_buf_line_count(0))
else
endI = math.max(cursor[1] - count + 1, 1)
end
for i = cursor[1], endI, step do
table.insert(lnums, i)
end
end
bufnr = bufnr or api.nvim_get_current_buf()
local qwinid = api.nvim_get_current_win()
local qs = qfs:get(qwinid)
local qlist = qs:list()
local sign = qlist:sign()
sign:toggle(lnums, bufnr)
if rel ~= 0 then
cmd(('norm! %d%s'):format(count, rel > 0 and 'j' or 'k'))
end
end
---
---@param lnum? number
---@param bufnr? number
function M.signToggleBuf(lnum, bufnr)
bufnr = bufnr or api.nvim_get_current_buf()
lnum = lnum or api.nvim_win_get_cursor(0)[1]
local qwinid = api.nvim_get_current_win()
local qs = qfs:get(qwinid)
local qlist = qs:list()
local items = qlist:items()
local entryBufnr = items[lnum].bufnr
local lnumList = {}
for l, entry in ipairs(items) do
if entry.bufnr == entryBufnr then
table.insert(lnumList, l)
end
end
local sign = qlist:sign()
sign:toggle(lnumList, bufnr)
end
--- only work under map with <Cmd>
---@param bufnr? number
function M.signVMToggle(bufnr)
local mode = api.nvim_get_mode().mode
vim.validate({
mode = {
mode, function(m)
-- ^V = 0x16
return m:lower() == 'v' or m == ('%c'):format(0x16)
end, 'visual mode'
}
})
-- ^[ = 0x1b
cmd(('norm! %c'):format(0x1b))
bufnr = bufnr or api.nvim_get_current_buf()
local startLnum = api.nvim_buf_get_mark(bufnr, '<')[1]
local endLnum = api.nvim_buf_get_mark(bufnr, '>')[1]
local lnumList = {}
for i = startLnum, endLnum do
table.insert(lnumList, i)
end
local qwinid = api.nvim_get_current_win()
local qs = qfs:get(qwinid)
local qlist = qs:list()
local sign = qlist:sign()
sign:toggle(lnumList, bufnr)
end
---
---@param bufnr number
function M.signClear(bufnr)
local qwinid = api.nvim_get_current_win()
local qs = qfs:get(qwinid)
local qlist = qs:list()
local sign = qlist:sign()
sign:clear(bufnr)
end
function M.restoreWinView()
local qwinid = api.nvim_get_current_win()
local qs = qfs:get(qwinid)
local qlist = qs:list()
local wv = qlist:getWinView()
if wv then
fn.winrestview(wv)
end
end
---
---@param next boolean
function M.navHistory(next)
local qwinid = api.nvim_get_current_win()
local qs = qfs:get(qwinid)
local qlist = qs:list()
qlist:setWinView(fn.winsaveview())
local prefix = qlist.type == 'loc' and 'l' or 'c'
local curNr, lastNr = qlist:getQfList({nr = 0}).nr, qlist:getQfList({nr = '$'}).nr
if lastNr <= 1 then
return
end
local count = vim.v.count1
local histNum = (curNr - 1 + (next and count or lastNr - count)) % lastNr + 1
cmd(([[sil exe '%d%shi']]):format(histNum, prefix))
cmd([[norm! m']])
M.restoreWinView()
local qinfo = qlist:getQfList({nr = 0, size = 0, title = 0})
local nr, size, title = qinfo.nr, qinfo.size, qinfo.title
if vim.o.cmdheight > 0 then
api.nvim_echo({
{'('}, {tostring(nr), 'Identifier'}, {' of '}, {tostring(lastNr), 'Identifier'}, {') ['},
{tostring(size), 'Type'}, {'] '}, {' >> ' .. title, 'Title'}
}, false, {})
end
end
---
---@param next boolean
function M.navFile(next)
local lnum, col = unpack(api.nvim_win_get_cursor(0))
local qwinid = api.nvim_get_current_win()
local qs = qfs:get(qwinid)
local qlist = qs:list()
local items, size = qlist:items(), qlist:getQfList({size = 0}).size
local curBufnr = items[lnum].bufnr
local start, stop, step = unpack(next and {lnum + 1, size, 1} or {lnum - 1, 1, -1})
for i = start, stop, step do
if items[i].valid == 1 and items[i].bufnr ~= curBufnr then
qlist:changeIdx(i)
api.nvim_win_set_cursor(0, {i, col})
return
end
end
if vim.o.cmdheight > 0 then
api.nvim_echo({{'No more items', 'WarningMsg'}}, true, {})
end
end
local function doEdit(qwinid, idx, close, action)
qwinid = qwinid or api.nvim_get_current_win()
local qs = qfs:get(qwinid)
local pwinid = qs:previousWinid()
local qlist = qs:list()
local size = qlist:getQfList({size = 0}).size
if size <= 0 then
api.nvim_err_writeln('E42: No Errors')
return false
end
if not utils.isWinValid(pwinid) then
vim.notify('file window is invalid', vim.log.levels.WARN)
cmd([[exe "norm! \<CR>"]])
api.nvim_win_set_height(qwinid, math.min(10, size))
return false
end
idx = idx or api.nvim_win_get_cursor(qwinid)[1]
qlist:changeIdx(idx)
local entry = qlist:item(idx)
local bufnr, lnum, col = entry.bufnr, entry.lnum, entry.col
if bufnr == 0 then
api.nvim_err_writeln('Buffer not found')
return
end
if close then
api.nvim_win_close(qwinid, true)
end
api.nvim_set_current_win(pwinid)
local lastBufnr = api.nvim_get_current_buf()
local lastBufname = api.nvim_buf_get_name(lastBufnr)
local lastBufoff = api.nvim_buf_get_offset(0, 1)
if action and not utils.isUnNameBuf(lastBufnr, lastBufname, lastBufoff) then
action(bufnr)
else
api.nvim_set_current_buf(bufnr)
end
vim.bo.buflisted = true
pcall(api.nvim_win_set_cursor, 0, {lnum, math.max(0, col - 1)})
if vim.wo.foldenable and vim.o.fdo:match('quickfix') then
cmd('norm! zv')
end
utils.zz()
if utils.isUnNameBuf(lastBufnr, lastBufname, lastBufoff) then
api.nvim_buf_delete(lastBufnr, {})
end
return true
end
---
---@param close boolean
---@param jumpCmd string|fun(fname: string)
---@param qwinid number
---@param idx number
function M.open(close, jumpCmd, qwinid, idx)
doEdit(qwinid, idx, close, function(bufnr)
if not jumpCmd then
api.nvim_set_current_buf(bufnr)
return
end
local fname = fn.fnameescape(api.nvim_buf_get_name(bufnr))
if type(jumpCmd) == 'string' then
if jumpCmd == 'drop' then
local bufInfo = fn.getbufinfo(bufnr)
if fname == '' or #bufInfo == 1 and #bufInfo[1].windows == 0 then
api.nvim_set_current_buf(bufnr)
return
end
end
cmd(('%s %s'):format(jumpCmd, fname))
elseif type(jumpCmd) == 'function' then
pcall(jumpCmd, fname)
end
end)
end
---
---@param stay boolean
---@param qwinid? number
---@param idx number
function M.tabedit(stay, qwinid, idx)
local lastTabPage = api.nvim_get_current_tabpage()
qwinid = qwinid or api.nvim_get_current_win()
local unnameBuf = true
if doEdit(qwinid, idx, false, function(bufnr)
unnameBuf = false
local fname = fn.fnameescape(api.nvim_buf_get_name(bufnr))
cmd(('tabedit %s'):format(fname))
end) then
local curTabPage = api.nvim_get_current_tabpage()
if not unnameBuf then
api.nvim_set_current_win(qwinid)
end
if lastTabPage ~= curTabPage and not stay then
api.nvim_set_current_tabpage(curTabPage)
end
end
end
return M