neovim

Personal neovim configuration files
git clone git://gtms.dev/neovim
Log | Files | Refs

lsp.lua (6148B)


      1 vim.lsp.enable {
      2   'bashls',
      3   'css-lsp',
      4   'dartls',
      5   'html',
      6   'intelephense',
      7   'jsonls',
      8   'lua_ls',
      9   'typescript-language-server',
     10   'yamlls',
     11 }
     12 
     13 vim.api.nvim_create_augroup('my.lsp', {
     14   clear = false
     15 })
     16 
     17 local function keymap(client, buf)
     18   local function opts(desc)
     19     return { buffer = buf, desc = desc }
     20   end
     21 
     22   -- client.server_capabilities.semanticTokensProvider = nil
     23 
     24   local prefix = 'gl'
     25 
     26   if client:supports_method('textDocument/hover') then
     27     vim.keymap.set('n', 'K', function() vim.lsp.buf.hover { border = 'single' } end,
     28       opts 'LSP Hover')
     29   end
     30 
     31   if client:supports_method('textDocument/definition') then
     32     vim.keymap.set('n', prefix .. 'd', vim.lsp.buf.definition, opts 'LSP Definition')
     33     vim.keymap.set('n', '<c-s><c-]>', function()
     34       vim.cmd.vsplit()
     35       vim.lsp.buf.definition()
     36     end, opts 'LSP Definition (VSplit)')
     37   end
     38 
     39   if client:supports_method('textDocument/typeDefinition') then
     40     vim.keymap.set('n', prefix .. 't', vim.lsp.buf.type_definition, opts 'LSP Type Definition')
     41   end
     42 
     43   if client:supports_method('callHierarchy/incomingCalls') then
     44     vim.keymap.set('n', ']c', vim.lsp.buf.incoming_calls, opts 'LSP Incoming calls')
     45   end
     46 
     47   if client:supports_method('callHierarchy/outgoingCalls') then
     48     vim.keymap.set('n', '[c', vim.lsp.buf.outgoing_calls, opts 'LSP Outgoing calls')
     49   end
     50 
     51   if client:supports_method('textDocument/implementation') then
     52     vim.keymap.set('n', prefix .. 'm', vim.lsp.buf.implementation, opts 'LSP Implementation')
     53     vim.keymap.set('n', '<c-w>' .. prefix .. 'm', function()
     54       vim.cmd.split()
     55       vim.lsp.buf.implementation()
     56     end, opts 'LSP Implementation (Split)')
     57     vim.keymap.set('n', '<c-s>' .. prefix .. 'm', function()
     58       vim.cmd.vsplit()
     59       vim.lsp.buf.implementation()
     60     end, opts 'LSP Implementation (VSplit)')
     61   end
     62 
     63   if client:supports_method('textDocument/signatureHelp') then
     64     vim.keymap.set('i', '<c-s>', function()
     65       vim.lsp.buf.signature_help { border = 'single' }
     66     end, opts 'LSP Signature Help')
     67   end
     68 
     69   if client:supports_method('textDocument/references') then
     70     local references = {
     71       all = function() vim.lsp.buf.references { includeDeclaration = false } end,
     72       first_in_file = function()
     73         vim.lsp.buf.references(nil,
     74           { on_list = require 'tms.lsp.references'.first_in_file })
     75       end,
     76       curr_file = function()
     77         vim.lsp.buf.references(nil,
     78           { on_list = require 'tms.lsp.references'.curr_file })
     79       end,
     80       after_line = function()
     81         vim.lsp.buf.references(nil,
     82           { on_list = require 'tms.lsp.references'.after_line })
     83       end,
     84       next = function()
     85         vim.lsp.buf.references(nil, { on_list = require 'tms.lsp.references'.next })
     86       end,
     87       prev = function()
     88         vim.lsp.buf.references(nil, { on_list = require 'tms.lsp.references'.prev })
     89       end
     90     }
     91 
     92     vim.keymap.set('n', '[<c-r>', references.all, opts 'All References')
     93     vim.keymap.set('n', '[R', references.first_in_file, opts 'First References in File')
     94     vim.keymap.set('n', ']R', references.curr_file, opts 'Local References')
     95     vim.keymap.set('n', '[r', references.prev, opts 'Previous Reference')
     96     vim.keymap.set('n', ']r', references.next, opts 'Next Reference')
     97   end
     98 
     99   if client:supports_method('textDocument/codeAction') then
    100     vim.keymap.set({ 'n', 'v' }, prefix .. 'a', vim.lsp.buf.code_action, opts 'LSP Code Actions')
    101   end
    102 
    103   if client:supports_method('textDocument/documentHighlight') then
    104     vim.keymap.set('n', '<leader>k', vim.lsp.buf.document_highlight, opts 'LSP Highlight')
    105     vim.api.nvim_create_autocmd('CursorMoved',
    106       { group = 'my.lsp', buffer = buf, callback = vim.lsp.buf.clear_references })
    107   end
    108 
    109   if client:supports_method('textDocument/inlayHint') then
    110     vim.keymap.set('n', prefix .. 'h', function()
    111       ---@diagnostic disable-next-line: missing-parameter
    112       vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled())
    113     end, opts 'LSP Inlay hints')
    114   end
    115 
    116   if client:supports_method('textDocument/rename') then
    117     vim.keymap.set('n', 'cd', vim.lsp.buf.rename, opts 'LSP Rename (Change Definition)')
    118     vim.keymap.set('n', prefix .. 'n', vim.lsp.buf.rename, opts 'LSP Rename')
    119   end
    120 
    121   if client:supports_method('typeHierarchy/supertypes') then
    122     vim.keymap.set('n', prefix .. 'p', function()
    123       vim.lsp.buf.typehierarchy('supertypes')
    124     end, opts 'LSP Supertypes (Parents)')
    125   end
    126 
    127   if client:supports_method('typeHierarchy/subtypes') then
    128     vim.keymap.set('n', prefix .. 'c', function()
    129       vim.lsp.buf.typehierarchy('subtypes')
    130     end, opts 'LSP Subtypes (Children)')
    131   end
    132 end
    133 
    134 vim.api.nvim_create_autocmd('LspAttach', {
    135   group = 'my.lsp',
    136   callback = function(args)
    137     local client = vim.lsp.get_client_by_id(args.data.client_id)
    138     if not client then
    139       return
    140     end
    141 
    142     keymap(client, args.buf)
    143   end,
    144 })
    145 
    146 local handlers = vim.lsp.handlers
    147 handlers['callHierarchy/outgoingCalls'] =
    148     function(_, result)
    149       if not result then
    150         return
    151       end
    152       local items = {}
    153       for _, call_hierarchy_call in pairs(result) do
    154         local call_hierarchy_item = call_hierarchy_call['to']
    155         table.insert(items, {
    156           filename = assert(vim.uri_to_fname(call_hierarchy_item.uri)),
    157           text = call_hierarchy_item.name,
    158           lnum = call_hierarchy_item.selectionRange.start.line + 1,
    159           col = call_hierarchy_item.selectionRange.start.character + 1,
    160         })
    161       end
    162       vim.fn.setqflist({}, ' ', { title = 'LSP call hierarchy', items = items })
    163       vim.cmd('botright copen')
    164     end
    165 
    166 local crc = handlers['client/registerCapability']
    167 handlers['client/registerCapability'] = function(_, result, ctx)
    168   local r = crc(_, result, ctx)
    169 
    170   local client = vim.lsp.get_client_by_id(ctx.client_id)
    171   keymap(client, ctx.bufnr)
    172 
    173   return r
    174 end
    175 -- local cuc = handlers['client/unregisterCapability']
    176 -- handlers['client/unregisterCapability'] = function(_, result, ctx)
    177 --   return cuc(_, result, ctx)
    178 --   -- TODO(tms) 08.06.23: Remove bindings
    179 -- end
    180 
    181 -- mason
    182 if pcall(require, 'mason') then
    183   require 'mason'.setup()
    184 end