Skip to content

Commit

Permalink
split diagnostic jump code action with normal code action
Browse files Browse the repository at this point in the history
  • Loading branch information
glepnir committed Apr 8, 2023
1 parent 3a341e3 commit 298009c
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 59 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -402,14 +402,12 @@ Default options:
keys = {
exec_action = 'o',
quit = 'q',
go_action = 'g',
expand_or_jump = '<CR>',
quit_in_show = { 'q', '<ESC>' },
},
},
```

- Using `go_action`, you can quickly jump to line where actions need to be taken in the diagnostics floating window.
- `jump_num_shortcut` - The default is `true`. After jumping, Lspasga will automatically bind code actions to a number. Afterwards, you can press the number to execute the code action. After the floating window is closed, these numbers will no longer be tied to the same code actions.
- `show_codeaction` default is true it will show available actions in the diagnsotic jump window
- `show_source` default is true extend `source` into the diagnostic message
Expand Down
27 changes: 13 additions & 14 deletions lua/lspsaga/codeaction.lua
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ function act:send_code_action_request(main_buf, options, cb)
end

if cb then
cb()
cb(vim.deepcopy(self.action_tuples))
end
end)
end
Expand All @@ -217,15 +217,12 @@ function act:set_cursor()
self:action_preview(self.action_winid, self.bufnr)
end

function act:num_shortcut(bufnr, callback)
function act:num_shortcut(bufnr)
for num, _ in pairs(self.action_tuples or {}) do
nvim_buf_set_keymap(bufnr, 'n', tostring(num), '', {
noremap = true,
nowait = true,
callback = function()
if callback then
callback()
end
self:do_code_action(num)
end,
})
Expand Down Expand Up @@ -271,7 +268,7 @@ function act:apply_action(action, client)
clean_ctx()
end

function act:do_code_action(num)
function act:do_code_action(num, tuple)
local number
if num then
number = tonumber(num)
Expand All @@ -281,13 +278,14 @@ function act:do_code_action(num)
number = tonumber(number)
end

if not number then
if not number and not tuple then
vim.notify('[Lspsaga] no action number choice', vim.log.levels.WARN)
return
end

local action = vim.deepcopy(self.action_tuples[number][2])
local client = lsp.get_client_by_id(self.action_tuples[number][1])
local action = tuple and tuple[2] or vim.deepcopy(self.action_tuples[number][2])
local id = tuple and tuple[1] or self.action_tuples[number][1]
local client = lsp.get_client_by_id(id)

local curbuf = api.nvim_get_current_buf()
self:close_action_window(curbuf)
Expand All @@ -310,13 +308,14 @@ function act:do_code_action(num)
end
end

function act:get_action_diff(num, main_buf)
local action = self.action_tuples[tonumber(num)][2]
function act:get_action_diff(num, main_buf, tuple)
local action = tuple and tuple[2] or self.action_tuples[tonumber(num)][2]
if not action then
return
end

local client = lsp.get_client_by_id(self.action_tuples[tonumber(num)][1])
local id = tuple and tuple[1] or self.action_tuples[tonumber(num)][1]
local client = lsp.get_client_by_id(id)
if
not action.edit
and client
Expand Down Expand Up @@ -369,7 +368,7 @@ function act:get_action_diff(num, main_buf)
return diff
end

function act:action_preview(main_winid, main_buf, border_hi)
function act:action_preview(main_winid, main_buf, border_hi, tuple)
if self.preview_winid and api.nvim_win_is_valid(self.preview_winid) then
api.nvim_win_close(self.preview_winid, true)
self.preview_winid = nil
Expand All @@ -380,7 +379,7 @@ function act:action_preview(main_winid, main_buf, border_hi)
return
end

local tbl = self:get_action_diff(num, main_buf)
local tbl = self:get_action_diff(num, main_buf, tuple)
if not tbl or #tbl == 0 then
return
end
Expand Down
105 changes: 64 additions & 41 deletions lua/lspsaga/diagnostic.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ local diagnostic = vim.diagnostic
local api, fn, keymap = vim.api, vim.fn, vim.keymap.set
local ns = api.nvim_create_namespace('DiagnosticJump')
local nvim_buf_set_keymap = api.nvim_buf_set_keymap
local nvim_buf_del_keymap = api.nvim_buf_del_keymap

local diag = {}

Expand Down Expand Up @@ -61,7 +62,7 @@ function diag:code_action_cb(hi_name)
config.ui.actionfix .. 'Actions',
}

for index, client_with_actions in pairs(act.action_tuples) do
for index, client_with_actions in pairs(self.action_tuples) do
if #client_with_actions ~= 2 then
vim.notify('There is something wrong in aciton_tuples')
return
Expand Down Expand Up @@ -92,30 +93,38 @@ function diag:code_action_cb(hi_name)
api.nvim_buf_add_highlight(self.bufnr, 0, 'CodeActionText', row, 6, -1)
end

keymap('n', diag_conf.keys.go_action, function()
if self.winid and api.nvim_win_is_valid(self.winid) then
api.nvim_win_set_cursor(self.winid, { start_line + 2, 4 })
if diag_conf.jump_num_shortcut then
for num, _ in pairs(self.action_tuples or {}) do
nvim_buf_set_keymap(self.main_buf, 'n', tostring(num), '', {
noremap = true,
nowait = true,
callback = function()
act:do_code_action(nil, self.action_tuples[num])
end,
})
end
end, { buffer = self.bufnr, nowait = true, noremap = true })
end

if diag_conf.jump_num_shortcut then
act:num_shortcut(self.main_buf, function()
if self.winid and api.nvim_win_is_valid(self.winid) then
api.nvim_win_close(self.winid, true)
end
if self.preview_winid and api.nvim_win_is_valid(self.preview_winid) then
api.nvim_win_close(self.preview_winid, true)
end
clean_ctx()
end)
local function get_num()
local line = api.nvim_get_current_line()
local num = line:match('%[(%d+)%]')
if num then
num = tonumber(num)
end
return num
end

api.nvim_create_autocmd('CursorMoved', {
buffer = self.bufnr,
callback = function()
local curline = api.nvim_win_get_cursor(self.winid)[1]
if curline > 3 then
self.preview_winid = act:action_preview(self.winid, self.main_buf, hi_name)
local num = get_num()
if not num then
return
end
local tuple = vim.deepcopy(self.action_tuples[num])
self.preview_winid = act:action_preview(self.winid, self.main_buf, hi_name, tuple)
end
end,
desc = 'Lspsaga show code action preview in diagnostic window',
Expand All @@ -136,7 +145,15 @@ function diag:code_action_cb(hi_name)
if curlnum > 3 then
api.nvim_buf_add_highlight(self.bufnr, ns, 'FinderSelection', curlnum - 1, 6, -1)
end
self.preview_winid = act:action_preview(self.winid, self.main_buf, hi_name)

local num = get_num()
if not num then
return
end
local tuple = vim.deepcopy(self.action_tuples[num])
if tuple then
self.preview_winid = act:action_preview(self.winid, self.main_buf, hi_name, tuple)
end
end)
end

Expand Down Expand Up @@ -190,21 +207,31 @@ function diag:do_code_action()
if not num then
return
end
act:do_code_action(num)

if self.action_tuples[num] then
act:do_code_action(num, vim.deepcopy(self.action_tuples[num]))
self:close_win()
end
self:clean_data()
end

function diag:clean_data()
window.nvim_close_valid_window({ self.winid, self.preview_winid })
libs.delete_scroll_map(self.main_buf)
for num, _ in pairs(self.action_tuples or {}) do
pcall(nvim_buf_del_keymap, self.main_buf, 'n', tostring(num))
end
clean_ctx()
end

function diag:apply_map()
keymap('n', diag_conf.keys.exec_action, function()
self:do_code_action()
window.nvim_close_valid_window({ self.winid, self.preview_winid })
self:close_win()
end, { buffer = self.bufnr, nowait = true })

keymap('n', diag_conf.keys.quit, function()
for _, id in pairs({ self.winid, self.preview_winid }) do
if api.nvim_win_is_valid(id) then
api.nvim_win_close(id, true)
end
end
self:clean_data()
end, { buffer = self.bufnr, nowait = true })
end

Expand Down Expand Up @@ -281,7 +308,9 @@ function diag:render_diagnostic_window(entry, option)
start = { entry.lnum + 1, entry.col },
['end'] = { entry.lnum + 1, entry.col },
},
}, function()
}, function(action_tuples)
self.action_tuples = action_tuples
act:clean_context()
self:code_action_cb(hi_name)
end)
end
Expand Down Expand Up @@ -377,25 +406,19 @@ function diag:render_diagnostic_window(entry, option)
self:apply_map()

local close_autocmds = { 'CursorMoved', 'InsertEnter' }
local winid = self.winid
vim.defer_fn(function()
libs.close_preview_autocmd(current_buffer, self.winid, close_autocmds)
end, 0)

api.nvim_buf_attach(self.bufnr, false, {
on_detach = vim.schedule_wrap(function()
libs.delete_scroll_map(current_buffer)
if self.preview_winid and api.nvim_win_is_valid(self.preview_winid) then
api.nvim_win_close(self.preview_winid, true)
end
if act.action_tuples and #act.action_tuples > 0 then
for i = 1, #act.action_tuples do
pcall(api.nvim_buf_del_keymap, current_buffer, 'n', tostring(i))
libs.close_preview_autocmd(
current_buffer,
{ self.winid, self.preview_winid or nil },
close_autocmds,
function()
if winid == self.winid then
self:clean_data()
end
end
act:clean_context()
clean_ctx()
end),
})
)
end, 0)
end

function diag:move_cursor(entry)
Expand Down
1 change: 0 additions & 1 deletion lua/lspsaga/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ local default_config = {
keys = {
exec_action = 'o',
quit = 'q',
go_action = 'g',
expand_or_jump = '<CR>',
quit_in_show = { 'q', '<ESC>' },
},
Expand Down
5 changes: 4 additions & 1 deletion lua/lspsaga/libs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,17 @@ function libs.get_config_lsp_filetypes()
return filetypes
end

function libs.close_preview_autocmd(bufnr, winids, events)
function libs.close_preview_autocmd(bufnr, winids, events, callback)
api.nvim_create_autocmd(events, {
group = saga_augroup,
buffer = bufnr,
once = true,
callback = function()
local window = require('lspsaga.window')
window.nvim_close_valid_window(winids)
if callback then
callback()
end
end,
})
end
Expand Down

0 comments on commit 298009c

Please sign in to comment.