summary refs log tree commit diff
path: root/.vim/lua/internal/lsp.lua
diff options
context:
space:
mode:
authorRobert Günzler <r@gnzler.io>2022-10-14 20:57:03 +0200
committerRobert Günzler <r@gnzler.io>2022-10-14 21:01:15 +0200
commit2d2009413f8be624a7cca95cf702e32d9315cbef (patch)
treef024c1b5b27b886530e86221593e3cfdc3672d7e /.vim/lua/internal/lsp.lua
parent6d7e524d3d7a71da2cea61b335a59e9544e2a6f7 (diff)
vim: move custom modules under internal/
Diffstat (limited to '.vim/lua/internal/lsp.lua')
-rw-r--r--.vim/lua/internal/lsp.lua299
1 files changed, 299 insertions, 0 deletions
diff --git a/.vim/lua/internal/lsp.lua b/.vim/lua/internal/lsp.lua
new file mode 100644
index 0000000..669c2c7
--- /dev/null
+++ b/.vim/lua/internal/lsp.lua
@@ -0,0 +1,299 @@
+local lsp         = require('lspconfig')
+local lspstatus   = require('lsp-status')
+
+local my_attach = function(client, bufnr)
+  if vim.opt.diff:get() then
+    vim.notify('not running LSP client in diff mode', vim.log.levels.WARN)
+    vim.lsp.stop_client()
+    return
+  end
+
+  local group = vim.api.nvim_create_augroup('LspOnAttach', {})
+  vim.api.nvim_create_autocmd('CursorHold', {
+    buffer = bufnr,
+    group = group,
+    callback = function()
+      if not _G.diagnostic_hidden then
+        vim.diagnostic.open_float(nil, {
+          focusable = false,
+          close_events = {'BufLeave', 'CursorMoved', 'InsertEnter', 'FocusLost'},
+          border = _G.floating_win_border,
+          source = 'always',
+          prefix = ' ',
+          scope = 'cursor',
+        })
+      end
+    end,
+  })
+
+  lspstatus.on_attach(client)
+  if client.supports_method('textDocument/documentSymbol') then
+    require('nvim-navic').attach(client, bufnr)
+    -- require('aerial').on_attach(client, bufnr)
+    -- vim.keymap.set('n', 'g0', vim.lsp.buf.document_symbol, {buffer = bufnr})
+  end
+  if client.supports_method('workspace/symbol') then
+    vim.keymap.set('n', 'gW'        , vim.lsp.buf.workspace_symbol, {buffer = bufnr, desc = 'goto symbol'})
+    vim.keymap.set('n', ';s'        , require('telescope.builtin').lsp_workspace_symbols, {desc='lsp workspace symbols'})
+  end
+  if client.supports_method('textDocument/definition') then
+    vim.keymap.set('n', '<C-]>'     , vim.lsp.buf.definition, {buffer = bufnr, desc = 'goto definition'})
+    vim.keymap.set('n', 'gd'        , vim.lsp.buf.definition, {buffer = bufnr, desc = 'goto definition'})
+    vim.keymap.set('n', 'gR'        , vim.lsp.buf.references, {buffer = bufnr, desc = 'goto references'})
+    vim.keymap.set('n', ';R'        , require('telescope.builtin').lsp_references, {desc='lsp references'})
+  end
+  if client.supports_method('textDocument/hover') then
+    vim.keymap.set('n', 'K'         , vim.lsp.buf.hover, {buffer = bufnr, desc = 'hover'})
+  end
+  if client.supports_method('textDocument/rename') then
+    vim.keymap.set('n', 'grr'       , vim.lsp.buf.rename, {buffer = bufnr, desc = 'rename'})
+  end
+  if client.supports_method('signatureHelp') then
+    vim.keymap.set('n', '<c-h>'     , vim.lsp.buf.signature_help, {buffer = bufnr, desc = 'signature help'})
+  end
+  if client.supports_method('textDocument/formatting') then
+    vim.api.nvim_buf_set_option(bufnr, 'formatexpr', 'v:lua.vim.lsp.formatexpr()')
+    vim.keymap.set('n', '<leader>f' , vim.lsp.buf.format, {buffer = bufnr, desc = 'format'})
+    vim.api.nvim_create_autocmd('BufWritePre', {
+      buffer = bufnr,
+      group = group,
+      callback = function() require('internal.lsp').format(vim.fn.expand('<afile>:p')) end,
+    })
+  end
+  if client.supports_method('textDocument/typeDefinition') then
+    vim.keymap.set('n', 'gT'        , vim.lsp.buf.type_definition, {buffer = bufnr, desc = 'goto typedef'})
+  end
+  if client.supports_method('textDocument/declaration') then
+    vim.keymap.set('n', 'gD'        , vim.lsp.buf.declaration, {buffer = bufnr, desc = 'goto declaration'})
+  end
+  if client.supports_method('textDocument/implementation') then
+    vim.keymap.set('n', 'gI'        , vim.lsp.buf.implementation, {buffer = bufnr, desc = 'goto implementation'})
+  end
+  if client.supports_method('textDocument/codeAction') then
+    vim.keymap.set('n', 'ga', vim.lsp.buf.code_action, {buffer = bufnr, desc = 'code action'})
+  end
+
+  if client.supports_method('textDocument/documentHighlight') then
+    vim.keymap.set('n', '<leader>8', vim.lsp.buf.document_highlight, {buffer = bufnr, desc = 'document highlight'})
+    -- vim.keymap.set('n', '', vim.lsp.buf.clear_references, {buffer = bufnr, desc = 'clear references'})
+    vim.api.nvim_create_autocmd('CursorMoved', {
+      callback = vim.lsp.buf.clear_references,
+      buffer = bufnr,
+    })
+  end
+end
+
+local my_exit = function(_, _, _)
+end
+
+local capabilities = function()
+  local caps = vim.lsp.protocol.make_client_capabilities()
+  -- enable lsp-based snippets
+  caps.textDocument.completion.completionItem.snippetSupport = true
+  caps.textDocument.completion.completionItem.resolveSupport = {
+    properties = {
+      'documentation',
+      'detail',
+      'additionalTextEdits',
+    }
+  }
+  -- add window/workDoneProgress capability
+  caps = vim.tbl_extend('keep', caps or {}, lspstatus.capabilities)
+  return caps
+end
+
+local servers = {
+  ccls = { disabled = true,
+    root_dir = lsp.util.root_pattern('.ccls','meson.build','.git'),
+    init_options = {
+      compilationDatabaseDirectory = "build",
+      index = { threads = 0 },
+      completion = {
+        filterAndSort = false,
+      },
+      clang = { excludeArgs = { '-frounding-math' } },
+    },
+  },
+  clangd = {
+    root_dir = lsp.util.root_pattern('.ccls','meson.build','.git'),
+  },
+  elixirls = {
+    cmd = { 'elixir-ls' },
+    settings = {
+      elixirLS = {
+        dialyzerEnabled = false,
+      }
+    }
+  },
+  gopls = {
+    settings = {
+      gopls = {
+        analyses = {
+          --  composites = false,
+          fieldalignment = true,
+          nilness = true,
+          shadow = false,
+          unusedparams = true,
+          unusedwrite = true,
+        },
+        gofumpt = true,
+        -- hoverKind = 'Structured',
+      }
+    }
+  },
+  sumneko_lua = {
+    cmd = { 'lua-language-server' },
+    settings = {
+      Lua = {
+        runtime = {
+          version = 'LuaJIT',
+          path = vim.split(package.path, ';'),
+        },
+        diagnostics = {
+          globals = {
+            '_G',
+            'assert',
+            'error',
+            'os',
+            'package',
+            'pairs', 'ipairs',
+            'pcall',
+            'require',
+            'string',
+            'table',
+            'type',
+            'vim',
+          },
+          neededFileStatus = {
+            ['code-style-check'] = 'Any',
+          }
+        },
+        format = {
+          enable =  true,
+          defaultConfig = {
+            indent_style = 'space',
+            indent_size = '2',
+          }
+        },
+        workspace = {
+          -- library = vim.api.nvim_get_runtime_file("", true),
+          library = {
+            [vim.env.VIMRUNTIME .. '/lua'] = true,
+            [vim.env.VIMRUNTIME .. '/lua/vim/lsp'] = true,
+            [vim.fn.stdpath('config') .. '/lua'] = true,
+          }
+        },
+        telemetry = {
+          enable = false,
+        },
+      },
+    },
+  },
+  rust_analyzer = {
+    cmd = { 'env', 'CARGO_TARGET_DIR=/tmp', 'RUST_SRC_PATH=/usr/src/rustlib/library', 'rust-analyzer' },
+    settings = {
+      ['rust-analyzer'] = {
+        checkOnSave = {
+          command = 'clippy'
+        }
+      }
+    },
+  },
+  tsserver = { disabled = true,
+    cmd = {
+      'toolbox', 'run', '--',
+      'sh', '-c',
+      '. /etc/profile.d/nvm.sh && typescript-language-server --stdio'
+    },
+  },
+  zls = { disabled = true,
+  },
+  zk = { disabled = true,
+    root_dir = lsp.util.root_pattern('.zk'),
+  },
+}
+
+local setup = function()
+  -- configure floating win handlers
+  vim.lsp.handlers['textDocument/hover'] = vim.lsp.with(
+    vim.lsp.handlers.hover, { border = _G.floating_win_border })
+  vim.lsp.handlers['textDocument/signature_help'] = vim.lsp.with(
+    vim.lsp.handlers.signature_help, { border = _G.floating_win_border })
+
+  local caps = capabilities()
+  for server, opts in pairs(servers) do
+    if not opts.disabled then
+      opts = vim.tbl_extend('error', opts, {
+        on_attach    = my_attach,
+        on_exit      = my_exit,
+        capabilities = caps,
+      })
+      -- lsp-status custom handlers
+      local ok, lspstatus_ext = pcall(lspstatus.extensions[server])
+      if ok then
+        opts = vim.tbl_extend('error', opts, {
+          handlers = lspstatus_ext.setup(),
+        })
+      end
+      lsp[server].setup(opts)
+    end
+  end
+end
+
+local format = function(afile)
+  if vim.g.nofmt then return end
+  if not string.match(afile, '^/home/robert/devel/upstream') then
+    vim.lsp.buf.format()
+    if string.match(afile, '.go$') then
+      vim.lsp.buf.code_action({ only = {'source.organizeImports'} })
+    end
+    -- vim.notify('%#MoreMsg#󰃢%#Italic# fmt')
+    vim.notify('%#MoreMsg#󰃢%#Italic# fmt')
+  end
+end
+
+local symbols = {
+  -- 󰆼  󱆃
+  Array = '󰨾 ',
+  Boolean = '󰦍 ',
+  Class = '󰙀 ',
+  Color = '󰉦 ',
+  Constant = ' ',
+  Constructor = '󱇿 ',
+  Enum = ' ',
+  EnumMember = ' ',
+  Event = '󱐋 ',
+  -- Field = '󰽜 ',
+  Field = '󰆈 ',
+  File = '󰈔 ',
+  Folder = '󰝰 ',
+  Function = ' ',
+  Interface = '󱦜 ',
+  Key = '󰌋 ',
+  Keyword = '󰓽 ',
+  Method = '󰒓 ',
+  Module = '󰏖 ',
+  Namespace = '󰆧 ',
+  Null = '󰎣 ',
+  Object = '󰘦 ',
+  Operator = '󱓉 ',
+  Property = '󰐱 ',
+  Package = '󰏗 ',
+  Reference = '󰌹 ',
+  Snippet = '󰯁 ',
+  Struct = '󰙅 ',
+  Text = '󰉿 ',
+  TypeParameter = '󰌨 ',
+  Unit = '󰠱 ',
+  Value = '󰎠 ',
+  Variable = '󱄑 ',
+}
+
+return {
+  my_attach    = my_attach,
+  my_exit      = my_exit,
+  capabilities = capabilities,
+  setup        = setup,
+  format       = format,
+  symbols       = symbols,
+}