Skip to content

Commit 883c4f0

Browse files
nvim: support LSP keybinding only if client support a particular LSP method
1 parent 4f70b3b commit 883c4f0

1 file changed

Lines changed: 275 additions & 41 deletions

File tree

.config/cvim/keymap/03_code_completion.lua

Lines changed: 275 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,50 +4,284 @@ vim.api.nvim_create_autocmd('LspAttach', {
44
group = vim.api.nvim_create_augroup('UserLspConfig', {}),
55
callback = function(ev)
66
-- Enable completion triggered by <c-x><c-o>
7-
-- -- ommi-func: manual completion
7+
-- -- ommi-func : manual completion
88
-- -- nvim-cmp : auto completion
99
-- - Disable ommi-func for nvim-cmp: https://github.com/neovim/nvim-lspconfig/wiki/Autocompletion
1010
-- vim.bo[ev.buf].omnifunc = 'v:lua.vim.lsp.omnifunc'
11+
-- NOTE: See `:help vim.lsp.*` for functions definition
1112

12-
-- Buffer local mappings.
13-
-- See `:help vim.lsp.*` for documentation on any of the below functions
14-
local opts = { buffer = ev.buf }
15-
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, opts)
16-
-- Jump to the definition
17-
vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts)
18-
-- Displays hover information about the symbol under the cursor
19-
vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts)
20-
-- Lists all the implementations for the symbol under the cursor
21-
vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, opts)
22-
-- Displays a function's signature information
23-
vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, opts)
24-
-- Add to workspace
25-
vim.keymap.set('n', '<space>wa', vim.lsp.buf.add_workspace_folder, opts)
26-
-- Remove from workspace
27-
vim.keymap.set('n', '<space>wr', vim.lsp.buf.remove_workspace_folder, opts)
28-
-- List workspaces
29-
vim.keymap.set('n', '<space>wl', function()
30-
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
31-
end, opts)
32-
-- Jumps to the definition of the type symbol
33-
vim.keymap.set('n', '<space>D', vim.lsp.buf.type_definition, opts)
34-
-- Renames all references to the symbol under the cursor
35-
vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename, opts)
36-
-- Selects a code action available at the current cursor position
37-
vim.keymap.set({ 'n', 'v' }, '<space>ca', vim.lsp.buf.code_action, opts)
38-
-- Lists all the references
39-
vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts)
40-
-- Lists all incoming call sites of the symbol under the cursor in the quickfix window
41-
-- User can pick one site in the input list
42-
vim.keymap.set('n', 'gri', vim.lsp.buf.incoming_calls, opts)
43-
-- Lists all outgoing call sites of the symbol under the cursor in the quickfix window
44-
-- User can pick one site in the input list
45-
vim.keymap.set('n', 'gro', vim.lsp.buf.outgoing_calls, opts)
46-
-- Set some key bindings conditional on server capabilities
47-
vim.keymap.set('n', '<space>f', function()
48-
vim.lsp.buf.format { async = true }
49-
end, opts)
50-
51-
-- FIXME: Continue with https://github.com/jdhao/nvim-config/blob/4d8ef868ad0ef7f6433d91332aa6649186d9a2fb/lua/config/lsp.lua
13+
-- NOTE:
14+
-- Q1: How to know if vim.lsp.protocol.Methods.textDocument_completion is defined ?
15+
-- A1: See https://raw.githubusercontent.com/neovim/neovim/d2e445e1bd321ea43b976d6aa7759d90b826ce62/runtime/lua/vim/lsp/protocol.lua
16+
17+
18+
local client = vim.lsp.get_client_by_id(ev.data.client_id)
19+
local buffer = ev.buf
20+
local opts = { buffer = buffer }
21+
22+
-- Enable completion support
23+
if client:supports_method(vim.lsp.protocol.Methods.textDocument_completion) then
24+
vim.opt.completeopt = {'menu', 'menuone', 'noinsert', 'fuzzy', 'popup'}
25+
vim.lsp.completion.enable(true, client.id, buffer, {autotrigger = true})
26+
vim.keymap.set(
27+
'i', '<C-Space>',
28+
function()
29+
-- Retrieve LSP completion candidates
30+
vim.lsp.completion.get()
31+
end,
32+
{
33+
desc = 'Trigger LSP completion'
34+
}
35+
)
36+
end
37+
38+
-- Enable LLM-based completion support
39+
if client:supports_method(vim.lsp.protocol.Methods.textDocument_inlineCompletion) then
40+
vim.opt.completeopt = {'menu', 'menuone', 'noinsert', 'fuzzy', 'popup'}
41+
vim.lsp.inline.completion.enable(true, client.id, buffer, {autotrigger = true})
42+
vim.keymap.set(
43+
'i', '<Tab>',
44+
function()
45+
-- Retrieve LSP completion candidates
46+
if not vim.lsp.completion.get() then
47+
return "<Tab>"
48+
end
49+
end,
50+
{
51+
desc = 'Apply the currently displayed completion suggestion',
52+
expr = true,
53+
buffer = buffer
54+
}
55+
)
56+
57+
-- Show next inline completion suggestion
58+
vim.keymap.set(
59+
'i', '<M-n>',
60+
function()
61+
vim.lsp.inline_completion.select({})
62+
end,
63+
{
64+
desc = 'Show next inline completion suggestion',
65+
buffer = buffer
66+
}
67+
)
68+
-- Show previous inline completion suggestion
69+
vim.keymap.set(
70+
'i', '<M-p>',
71+
function()
72+
vim.lsp.inline_completion.select({count = -1})
73+
end,
74+
{
75+
desc = 'Show previous inline completion suggestion',
76+
buffer = buffer
77+
}
78+
)
79+
end
80+
81+
-- Enable declaration support
82+
if client:supports_method(vim.lsp.protocol.Methods.textDocument_declaration) then
83+
vim.keymap.set(
84+
'n', 'gD',
85+
vim.lsp.buf.declaration,
86+
{
87+
desc = "Jump to declaration",
88+
buffer = buffer
89+
}
90+
)
91+
end
92+
93+
-- Enable definition support
94+
if client:supports_method(vim.lsp.protocol.Methods.textDocument_definition) then
95+
vim.keymap.set(
96+
'n', 'gd',
97+
vim.lsp.buf.definition,
98+
{
99+
desc = "Jump to definition",
100+
buffer = buffer
101+
}
102+
)
103+
end
104+
-- Enable hover support
105+
if client:supports_method(vim.lsp.protocol.Methods.textDocument_hover) then
106+
vim.keymap.set(
107+
'n', 'K',
108+
vim.lsp.buf.hover,
109+
{
110+
desc = "Display symbol info",
111+
buffer = buffer
112+
}
113+
)
114+
end
115+
-- Enable implementation support
116+
if client:supports_method(vim.lsp.protocol.Methods.textDocument_implementation) then
117+
vim.keymap.set(
118+
'n', 'gi',
119+
vim.lsp.buf.implementation,
120+
{
121+
desc = "List symbol implementations",
122+
buffer = buffer
123+
}
124+
)
125+
end
126+
-- Enable signature help completion support
127+
if client:supports_method(vim.lsp.protocol.Methods.textDocument_signatureHelp) then
128+
-- Displays a function's signature information
129+
vim.keymap.set(
130+
'n', '<C-k>',
131+
vim.lsp.buf.signature_help,
132+
{
133+
desc = "Trigger LSP signature help",
134+
buffer = buffer
135+
}
136+
)
137+
end
138+
-- Enable workspace support
139+
if client:supports_method(vim.lsp.protocol.Methods.workspace_didChangeWorkspaceFolders) then
140+
vim.keymap.set(
141+
'n', '<space>wa',
142+
vim.lsp.buf.add_workspace_folder,
143+
{
144+
desc = "Add workspace folder",
145+
buffer = buffer
146+
}
147+
)
148+
vim.keymap.set(
149+
'n', '<space>wr',
150+
vim.lsp.buf.remove_workspace_folder,
151+
{
152+
desc = "Remove workspace folder",
153+
buffer = buffer
154+
}
155+
)
156+
end
157+
if client:supports_method(vim.lsp.protocol.Methods.workspace_workspaceFolders) then
158+
vim.keymap.set(
159+
'n', '<space>wl',
160+
function()
161+
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
162+
end,
163+
{
164+
desc = "List workspaces",
165+
buffer = buffer
166+
}
167+
)
168+
end
169+
-- Enable definition support
170+
if client:supports_method(vim.lsp.protocol.Methods.textDocument_definition) then
171+
vim.keymap.set(
172+
'n', '<space>D',
173+
vim.lsp.buf.type_definition,
174+
{
175+
desc = "Jumps to type symbol definition",
176+
buffer = buffer
177+
}
178+
)
179+
end
180+
-- Enable rename support
181+
if client:supports_method(vim.lsp.protocol.Methods.textDocument_rename) then
182+
vim.keymap.set(
183+
'n', '<space>rn',
184+
vim.lsp.buf.rename,
185+
{
186+
desc = "Renames all references",
187+
buffer = buffer
188+
}
189+
)
190+
end
191+
-- Enable code action support
192+
if client:supports_method(vim.lsp.protocol.Methods.textDocument_codeAction) then
193+
vim.keymap.set(
194+
{ 'n', 'v' }, '<space>ca',
195+
vim.lsp.buf.code_action,
196+
{
197+
desc = "Selects a code action",
198+
buffer = buffer
199+
}
200+
)
201+
end
202+
-- Enable references support
203+
if client:supports_method(vim.lsp.protocol.Methods.textDocument_references) then
204+
vim.keymap.set(
205+
'n', 'gr',
206+
vim.lsp.buf.references,
207+
{
208+
desc = "List all references",
209+
buffer = buffer
210+
}
211+
)
212+
end
213+
-- Enable Document Highlight support
214+
if client.server_capabilities.documentHighlightProvider then
215+
local gid = vim.api.nvim_create_augroup("UserLSPDocumentHighlight", { clear = true })
216+
vim.api.nvim_create_autocmd("CursorHold", {
217+
group = gid,
218+
buffer = buffer,
219+
callback = function()
220+
vim.lsp.buf.document_highlight()
221+
end,
222+
desc = "Highlight current variable and usage in buffer"
223+
})
224+
225+
vim.api.nvim_create_autocmd("CursorMoved", {
226+
group = gid,
227+
buffer = bufnr,
228+
callback = function()
229+
vim.lsp.buf.clear_references()
230+
end,
231+
desc = "Clear references"
232+
})
233+
end
234+
-- Enable Inlay hint support
235+
if client.server_capabilities.inlayHintProvider then
236+
vim.lsp.inlay_hint.enable(true, {buffer = buffer})
237+
local gid = vim.api.nvim_create_augroup("UserLSPDocumentHighlight", { clear = true })
238+
vim.keymap.set(
239+
"n", "<leader>h",
240+
function()
241+
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled())
242+
end,
243+
{
244+
desc = "Toggel inlay hint",
245+
buffer = buffer,
246+
}
247+
)
248+
end
249+
-- Enable Call Hierarchy support
250+
if client:supports_method(vim.lsp.protocol.Methods.callHierarchy_incomingCalls) then
251+
vim.keymap.set(
252+
'n', 'gri',
253+
vim.lsp.buf.incoming_calls,
254+
{
255+
desc = "Lists all incoming call sites",
256+
buffer = buffer
257+
}
258+
)
259+
end
260+
-- Enable call hierarchy support
261+
if client:supports_method(vim.lsp.protocol.Methods.callHierarchy_outgoingCalls) then
262+
vim.keymap.set(
263+
'n', 'gro',
264+
vim.lsp.buf.outgoing_calls,
265+
{
266+
desc = "Lists all outgoing call sites",
267+
buffer = buffer
268+
}
269+
)
270+
end
271+
-- Enable formatting support
272+
if client:supports_method(vim.lsp.protocol.Methods.textDocument_formatting) then
273+
vim.keymap.set(
274+
'n', '<space>f',
275+
function()
276+
vim.lsp.buf.format { async = true }
277+
end,
278+
{
279+
desc = "Format buffer",
280+
buffer = buffer
281+
}
282+
)
283+
end
52284
end,
285+
nested = true,
286+
desc = "Configure buffer keymap and LSP based behaviour"
53287
})

0 commit comments

Comments
 (0)