aboutsummaryrefslogtreecommitdiff
path: root/.config/nvim/lsp/ocamllsp.lua
diff options
context:
space:
mode:
authorawy <awy@awy.one>2025-10-14 18:27:29 +0300
committerawy <awy@awy.one>2025-10-14 18:27:29 +0300
commitde009fd679e10d053fdcc10785f91ad5317449ea (patch)
tree60918a488b579588596cf4d509fde298dccbf15d /.config/nvim/lsp/ocamllsp.lua
parent9ea6cf81adb5d6abc59843de1db45913210f9320 (diff)
downloadhyprdots-de009fd679e10d053fdcc10785f91ad5317449ea.tar.gz
nvim revamp
Diffstat (limited to '.config/nvim/lsp/ocamllsp.lua')
-rw-r--r--.config/nvim/lsp/ocamllsp.lua88
1 files changed, 88 insertions, 0 deletions
diff --git a/.config/nvim/lsp/ocamllsp.lua b/.config/nvim/lsp/ocamllsp.lua
new file mode 100644
index 0000000..d7a2726
--- /dev/null
+++ b/.config/nvim/lsp/ocamllsp.lua
@@ -0,0 +1,88 @@
+---@brief
+---
+--- https://github.com/ocaml/ocaml-lsp
+---
+--- `ocaml-lsp` can be installed as described in [installation guide](https://github.com/ocaml/ocaml-lsp#installation).
+---
+--- To install the lsp server in a particular opam switch:
+--- ```sh
+--- opam install ocaml-lsp-server
+--- ```
+
+-- https://github.com/ocaml/ocaml-lsp/blob/master/ocaml-lsp-server/docs/ocamllsp/switchImplIntf-spec.md
+local function switch_impl_intf(bufnr, client)
+ local method_name = 'ocamllsp/switchImplIntf'
+ ---@diagnostic disable-next-line:param-type-mismatch
+ if not client or not client:supports_method(method_name) then
+ return vim.notify(('method %s is not supported by any servers active on the current buffer'):format(method_name))
+ end
+ local uri = vim.lsp.util.make_given_range_params(nil, nil, bufnr, client.offset_encoding).textDocument.uri
+ if not uri then
+ return vim.notify('could not get URI for current buffer')
+ end
+ local params = { uri }
+ ---@diagnostic disable-next-line:param-type-mismatch
+ client:request(method_name, params, function(err, result)
+ if err then
+ error(tostring(err))
+ end
+ if not result or #result == 0 then
+ vim.notify('corresponding file cannot be determined')
+ elseif #result == 1 then
+ vim.cmd.edit(vim.uri_to_fname(result[1]))
+ else
+ vim.ui.select(
+ result,
+ { prompt = 'Select an implementation/interface:', format_item = vim.uri_to_fname },
+ function(choice)
+ if choice then
+ vim.cmd.edit(vim.uri_to_fname(choice))
+ end
+ end
+ )
+ end
+ end, bufnr)
+end
+
+local language_id_of = {
+ menhir = 'ocaml.menhir',
+ ocaml = 'ocaml',
+ ocamlinterface = 'ocaml.interface',
+ ocamllex = 'ocaml.ocamllex',
+ reason = 'reason',
+ dune = 'dune',
+}
+
+local language_id_of_ext = {
+ mll = language_id_of.ocamllex,
+ mly = language_id_of.menhir,
+ mli = language_id_of.ocamlinterface,
+}
+
+local get_language_id = function(bufnr, ftype)
+ if ftype == 'ocaml' then
+ local path = vim.api.nvim_buf_get_name(bufnr)
+ local ext = vim.fn.fnamemodify(path, ':e')
+ return language_id_of_ext[ext] or language_id_of.ocaml
+ else
+ return language_id_of[ftype]
+ end
+end
+
+local root_markers1 = { 'dune-project', 'dune-workspace' }
+local root_markers2 = { '*.opam', 'opam', 'esy.json', 'package.json' }
+local root_markers3 = { '.git' }
+
+---@type vim.lsp.Config
+return {
+ cmd = { 'ocamllsp' },
+ filetypes = { 'ocaml', 'menhir', 'ocamlinterface', 'ocamllex', 'reason', 'dune' },
+ root_markers = vim.fn.has('nvim-0.11.3') == 1 and { root_markers1, root_markers2, root_markers3 }
+ or vim.list_extend(vim.list_extend(root_markers1, root_markers2), root_markers3),
+ get_language_id = get_language_id,
+ on_attach = function(client, bufnr)
+ vim.api.nvim_buf_create_user_command(bufnr, 'LspOcamllspSwitchImplIntf', function()
+ switch_impl_intf(bufnr, client)
+ end, { desc = 'Switch between implementation/interface' })
+ end,
+}