diff options
Diffstat (limited to '.config/nvim/lsp/ocamllsp.lua')
-rw-r--r-- | .config/nvim/lsp/ocamllsp.lua | 88 |
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, +} |