---Utility for keymap creation. ---@param lhs string ---@param rhs string|function ---@param opts string|table ---@param mode? string|string[] local function keymap(lhs, rhs, opts, mode) opts = type(opts) == 'string' and { desc = opts } or vim.tbl_extend('error', opts --[[@as table]], { buffer = bufnr }) mode = mode or 'n' vim.keymap.set(mode, lhs, rhs, opts) end ---For replacing certain ... keymaps. ---@param keys string local function feedkeys(keys) vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(keys, true, false, true), 'n', true) end ---Is the completion menu open? local function pumvisible() return tonumber(vim.fn.pumvisible()) ~= 0 end -- Enable completion and configure keybindings. if client.supports_method(methods.textDocument_completion) then vim.lsp.completion.enable(true, client.id, bufnr, { autotrigger = true }) -- Use enter to accept completions. keymap('', function() return pumvisible() and '' or '' end, { expr = true }, 'i') -- Use slash to dismiss the completion menu. keymap('/', function() return pumvisible() and '' or '/' end, { expr = true }, 'i') -- Use to navigate to the next completion or: -- - Trigger LSP completion. -- - If there's no one, fallback to vanilla omnifunc. keymap('', function() if pumvisible() then feedkeys '' else if next(vim.lsp.get_clients { bufnr = 0 }) then vim.lsp.completion.trigger() else if vim.bo.omnifunc == '' then feedkeys '' else feedkeys '' end end end end, 'Trigger/select next completion', 'i') -- Buffer completions. keymap('', '', { desc = 'Buffer completions' }, 'i') -- Use to accept a Copilot suggestion, navigate between snippet tabstops, -- or select the next completion. -- Do something similar with . keymap('', function() local copilot = require 'copilot.suggestion' if copilot.is_visible() then copilot.accept() elseif pumvisible() then feedkeys '' elseif vim.snippet.active { direction = 1 } then vim.snippet.jump(1) else feedkeys '' end end, {}, { 'i', 's' }) keymap('', function() if pumvisible() then feedkeys '' elseif vim.snippet.active { direction = -1 } then vim.snippet.jump(-1) else feedkeys '' end end, {}, { 'i', 's' }) -- Inside a snippet, use backspace to remove the placeholder. keymap('', 's', {}, 's') end