summaryrefslogtreecommitdiffstats
path: root/plugin/50-lsp.lua
blob: 129437821ed2862c26f81d56bcd7a78a13fc2a24 (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
--
-- 50-lsp.lua
--
-- * Configures and enables the LSP servers (lua_ls, bashls, marksman, vimls, basedpyright, ruff).
-- * On attach, enables completion for clients that support it. Inlay hints default off; toggle them
--   with `LspHintToggle`.
--
-- User commands:
--   `LspInspect`: inspect the first LSP client's server capabilities
--   `LspHintToggle`: toggle LSP inlay hints globally
--

-- Notify the first attached LSP client's server capabilities.
local function inspect_lsp()
	local client = vim.lsp.get_clients()[1]
	if client == nil then
		vim.notify("No LSP client loaded")
		return
	end
	vim.notify(vim.inspect(client.server_capabilities), vim.log.levels.INFO)
end

-- Enable LSP server capabilities if available when attaching, see `:help lsp-attach`.
local function on_lsp_attach(ev)
	local client = assert(vim.lsp.get_client_by_id(ev.data.client_id))
	if client:supports_method("textDocument/completion") then
		vim.lsp.completion.enable(true, client.id, ev.buf, { autotrigger = true })
	else
		vim.notify("Client " .. client.name .. " does not support completion", vim.log.levels.WARN)
	end
end

-- Toggle LSP inlay hints globally, across all buffers.
local function toggle_lsp_hints()
	vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled())
end

----------------------------------------------------------------------------------------------------
-- Lua
----------------------------------------------------------------------------------------------------

vim.lsp.config("lua_ls", {
	on_init = function(client)
		-- A `.luarc.json` at the workspace root is authoritative: lua_ls reads it itself and its
		-- settings take precedence over anything the client sends, so don't fight it here.
		local root = client.root_dir
		local luarc
		if root then
			for _, name in ipairs({ ".luarc.json", ".luarc.jsonc" }) do
				local path = vim.fs.joinpath(root, name)
				if vim.uv.fs_stat(path) then
					luarc = path
					break
				end
			end
		end
		if luarc then
			vim.notify("lua_ls: using " .. luarc, vim.log.levels.INFO)
		else
			-- No `.luarc.json`: nothing says this is a Neovim project, so don't impose Neovim
			-- assumptions (LuaJIT, the nvim runtime as library, the `vim` global). Let lua_ls use
			-- its own defaults; add a `.luarc.json` to the workspace for Neovim-aware settings.
			vim.notify("lua_ls: no .luarc.json found, using lua_ls defaults", vim.log.levels.WARN)
		end
	end,
})
vim.lsp.enable("lua_ls")

----------------------------------------------------------------------------------------------------
-- Bash
----------------------------------------------------------------------------------------------------

vim.lsp.enable("bashls")

----------------------------------------------------------------------------------------------------
-- Markdown
----------------------------------------------------------------------------------------------------

vim.lsp.config("marksman", { filetypes = { "markdown" } })
vim.lsp.enable("marksman")

----------------------------------------------------------------------------------------------------
-- Vimscript
----------------------------------------------------------------------------------------------------

vim.lsp.enable("vimls")

----------------------------------------------------------------------------------------------------
-- Python
----------------------------------------------------------------------------------------------------

vim.lsp.enable("basedpyright")
vim.lsp.enable("ruff")

----------------------------------------------------------------------------------------------------

vim.api.nvim_create_autocmd("LspAttach", {
	desc = "Enable LSP capabilities",
	group = vim.g.dotfiles.augroup,
	callback = on_lsp_attach,
})

vim.api.nvim_create_user_command("LspInspect", inspect_lsp, { desc = "Inspect LSP client" })

vim.api.nvim_create_user_command(
	"LspHintToggle",
	toggle_lsp_hints,
	{ desc = "Toggle LSP inlay hints" }
)