summaryrefslogtreecommitdiff
path: root/.config/nvim/lua/custom/lsp.lua
blob: e5943cc8960408fbd95f360b162a6549671abbab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
-- Setup null-ls
local null_ls = require('null-ls')
null_ls.setup({
    sources = {
        null_ls.builtins.formatting.stylua,
    },
})

-- Setup lsp signature
-- FIXME: fork the repo and fix the following issues
-- Remove documentation, show just the signature (in insert AND normal)
-- Make both insert and normal be toggelable rather than insert always showing and normal toggleable
require('lsp_signature').setup({
    bind = true, -- This is mandatory, otherwise border config won't get registered.
    handler_opts = { border = 'single' },
    doc_lines = 0,
    hint_enable = false,
})

require('lspsaga').setup({
    lightbulb = {
        enable = false,
        sign = false,
        virtual_text = true,
    },
    implement = {
        sign = false,
        virtual_text = true,
    },
    floaterm = {
        height = 0.7,
        width = 0.7,
    },
    outline = {
        layout = 'float',
    },
})

-- NOTE: A list of language servers (and potentially their config)
-- Accepts either true to enable, false to disable or a table with settings
local servers = {
    lua_ls = true,                 -- lua
    clangd = true,                 -- C/C++
    gradle_ls = true,              -- java package manager
    jdtls = true,                  -- java eclipse lsp
    kotlin_language_server = true, -- kotlin
    pyright = true,                -- python
    rust_analyzer = true,          -- rust
    bashls = true,                 -- bash
    taplo = true,                  -- toml
    lemminx = true,                -- xml
    yamlls = true,                 -- yaml
    jsonls = true,                 -- json
}

-- NOTE: Not language servers but still make sure mason installs them
local ensure_installed = {
    stylua = true, -- lua formatting
}

local capabilities = nil
if pcall(require, 'cmp_nvim_lsp') then
    capabilities = require('cmp_nvim_lsp').default_capabilities()
end

local servers_to_install = vim.tbl_filter(function(key)
    local server = servers[key]
    if type(server) == 'table' then
        return true
    else
        return server
    end
end, vim.tbl_keys(servers))

require('mason').setup()
vim.list_extend(ensure_installed, servers_to_install)
require('mason-lspconfig').setup({ ensure_installed = servers_to_install })

local lspconfig = require('lspconfig')
for name, config in pairs(servers) do
    if config == true then
        ---@diagnostic disable-next-line: cast-local-type
        config = {}
    end
    config = vim.tbl_deep_extend('force', {}, {
        capabilities = capabilities,
    }, config)

    lspconfig[name].setup(config)
end

vim.api.nvim_create_autocmd('LspAttach', {
    callback = function(args)
        local bufnr = args.buf
        local client = assert(vim.lsp.get_client_by_id(args.data.client_id), 'must have valid client')

        local settings = servers[client.name]
        if type(settings) ~= 'table' then
            ---@diagnostic disable-next-line: cast-local-type
            settings = {}
        end

        -- Override server capabilities
        if settings.server_capabilities then
            for k, v in pairs(settings.server_capabilities) do
                if v == vim.NIL then
                    v = nil
                end
                client.server_capabilities[k] = v
            end
        end
    end,
})

-- TODO: Decide if you want to use conform or not
--
-- -- Autoformatting Setup
-- require('conform').setup({
--     formatters_by_ft = {
--         lua = { 'stylua' },
--     },
-- })
--
-- vim.api.nvim_create_autocmd('BufWritePre', {
--     callback = function(args)
--         require('conform').format({
--             bufnr = args.buf,
--             lsp_fallback = true,
--             quiet = true,
--         })
--     end,
-- })

require('lsp_lines').setup()
vim.diagnostic.config({ virtual_text = false })
vim.keymap.set('', '<Leader>dt', require('lsp_lines').toggle, { desc = '[D]iagnostics [T]oggle inline' })

local lspsaga_diagnostic = require('lspsaga.diagnostic')
local builtin = require('telescope.builtin')
local severity = vim.diagnostic.severity
local show_workspace_diagnostics = '<cmd>Lspsaga show_workspace_diagnostics ++normal<cr>'
local function next_diagnostic(diagnostic_severity)
    return function()
        lspsaga_diagnostic:goto_next({ severity = diagnostic_severity })
    end
end
local function prev_diagnostic(diagnostic_severity)
    return function()
        lspsaga_diagnostic:goto_prev({ severity = diagnostic_severity })
    end
end

-- LSP Keybindings
vim.keymap.set('n', 'gd', builtin.lsp_definitions, { desc = '[G]oto [D]efinition' })
vim.keymap.set('n', 'gu', builtin.lsp_references, { desc = '[G]oto [U]sages' })
vim.keymap.set('n', 'gi', builtin.lsp_implementations, { desc = '[G]oto [I]mplementations' })
-- vim.keymap.set('n', 'gt', builtin.lsp_type_definitions, { desc = '[G]oto [T]ype Definitions' })
-- vim.keymap.set('n', 'gw', builtin.diagnostics, { desc = '[G]oto [W]arnings' })
vim.keymap.set('n', '<leader>ds', builtin.lsp_document_symbols, { desc = '[D]ocument [S]symbols' })
vim.keymap.set('n', '<leader>ps', builtin.lsp_workspace_symbols, { desc = '[P]roject [S]ymbols' })
vim.keymap.set({ 'n', 'i' }, '<C-p>', vim.lsp.buf.signature_help, { desc = 'List [P]arameters' })
vim.keymap.set('n', 'K', '<cmd>Lspsaga hover_doc<cr>', { desc = 'Documentation' })
vim.keymap.set('n', 'R', '<cmd>Lspsaga rename<cr>', { desc = '[R]ename' })
-- vim.keymap.set('n', '<leader>os', '<cmd>Lspsaga outline<cr>', { desc = '[T]erminal' })
vim.keymap.set({ 'n', 'i' }, '<M-Enter>', '<cmd>Lspsaga code_action<cr>', { desc = 'Code Actions' })
vim.keymap.set('n', '<leader>ca', '<cmd>Lspsaga code_action<cr><Esc>', { desc = '[C]ode [A]ctions' })
vim.keymap.set('n', 'ge', next_diagnostic(severity.ERROR), { desc = '[G]oto [E]rror' })
vim.keymap.set('n', 'gE', prev_diagnostic(severity.ERROR), { desc = '[G]oto [E]rror (prev)' })
vim.keymap.set('n', 'gw', next_diagnostic(severity.ERROR), { desc = '[G]oto [W]arning' })
vim.keymap.set('n', 'gW', prev_diagnostic(severity.ERROR), { desc = '[G]oto [W]arning (prev)' })
vim.keymap.set('n', '<leader>dw', show_workspace_diagnostics, { desc = '[D]iagnostics for [W]orkspace' })
vim.keymap.set({ 'n', 't' }, '<A-t>', '<cmd>Lspsaga term_toggle<cr>', { desc = '[T]erminal' })