Add custom code actions to Neovim
Minimal config
{
'taybart/code-actions.nvim',
opts= {
actions= {
{
command='hello world', -- what will show up in the pickerfn=function(action) -- action is passed back with contextvim.notify( 'from '..action.command, vim.log.levels.INFO, { title='hello!' })
end,
}
},
},
}{
'taybart/code-actions.nvim',
opts= {
register_keymap=true, -- register nmap("ca") for code actions in buffer-- ie: vim.keymap.set("n", "ca", vim.lsp.buf.code_action, { buffer = ev.buf })filetypes= {
exclude= {},
include= {},
},
-- a server "global" context where additonal functions or modules can be added-- this can be a function that returns a table or a tablectx= {
happy=true,
}
actions= {
{
command='hello world', -- what will show up in the picker-- check whether to show the action, this defaults always show if not providedshow=function(ctx) -- here only ctx is passed in-- here we are checking if the global ctx has happy and if we are in a markdown filereturnctx.g.happyorctx.filetype=='markdown'end,
-- show can also be a table with conditions such as filetypeshow= { ft= { 'markdown' }} -- only show in markdown filesfn=function(action) -- action is passed back to the fn including ctxvim.notify(
'from: '..action.command,
vim.log.levels.INFO,
{ title='hello!' }
)
end,
}
},
-- named servers to differentiate action groups, see below for exampleservers= {
server_name= {
-- copy of upper config, filetypes/ctx/actions
}
}
},
}This would be the context generated from a code action on the install example on the fn line:
action.ctx= {
buf=1,
bufname="/path/to/taybart/code-actions.nvim/README.md",
col=4,
filetype="markdown",
g= { -- global context, see gitsigns implementation as an example of using g
},
line=" fn = function(params) -- action is passed back with context ",
range= {
["end"] =<1>{
character=4,
line=16
},
rc= { 16, 4, 16, 4 },
start=<table1>
},
root="/path/to/code-actions.nvim",
row=16,
ts_range= { 10, 0, 27, 0 },
ts_type="code_fence_content",
win=1000,
word="fn"
},Here is an example of a server that implements gitsigns actions
NOTE: if you are including this as a dependency for your own plugin, make sure to use the add_server option so you don't clobber users default actions
{
'taybart/code-actions.nvim',
opts= {
servers= {
gitsigns= {
ctx= {
action_exists=function(name)
localactions=require('gitsigns').get_actions()
returnactions~=nilandactions[name] ~=nilend,
get_action=function(name)
localactions=require('gitsigns').get_actions()
ifactions~=nilandactions[name] ~=nilthenreturnactions[name]
endreturnfunction() endend,
},
-- stylua: ignoreactions= {
{
command='Preview hunk',
show=function(ctx) returnctx.g.action_exists('preview_hunk') end,
fn=function(a) a.ctx.g.get_action('preview_hunk')() end,
},
{
command='Reset hunk',
show=function(ctx) returnctx.g.action_exists('reset_hunk') end,
fn=function(a) a.ctx.g.get_action('reset_hunk')() end,
},
{
command='Select hunk',
show=function(ctx) returnctx.g.action_exists('select_hunk') end,
fn=function(a) a.ctx.g.get_action('select_hunk')() end,
},
{
command='Stage hunk',
show=function(ctx) returnctx.g.action_exists('stage_hunk') end,
fn=function(a) a.ctx.g.get_action('stage_hunk')() end,
},
},
},
},
},
}Thanks to YaroSpace for the initial lsp code