From af40ef5e20bf840499e914b3ca4e90dbf0e4a540 Mon Sep 17 00:00:00 2001 From: jpoly1219 Date: Fri, 19 Sep 2025 00:40:56 -0700 Subject: [PATCH 1/5] feat: add docs for neovim setup --- .../getting-started/2_00_editor_setup.md | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/data/tutorials/getting-started/2_00_editor_setup.md b/data/tutorials/getting-started/2_00_editor_setup.md index 73c106ab2a..0257210125 100644 --- a/data/tutorials/getting-started/2_00_editor_setup.md +++ b/data/tutorials/getting-started/2_00_editor_setup.md @@ -145,3 +145,95 @@ opam user-setup install - Type `:MerlinTypeOf` and press Enter. - The type information will be displayed in the command bar. Other Merlin commands for Vim are available and you can checkout their usage on the [Merlin official documentation for Vim](https://ocaml.github.io/merlin/editor/vim/). + +## Neovim + +Neovim comes with an LSP client. + +One note here is that is that `ocaml-lsp-server` is sensitive to versioning, and often does not play well with the sometimes outdated sources in Mason, a popular package manager for language services. We recommend you install the LSP server directly in the switch, and pointing your Neovim config to use that. + +To install the LSP server and the formatter, run the following. +```shell +opam install ocaml-lsp-server ocamlformat +``` + +There are two main ways to install and manage LSP servers. +- A more traditional way is to use `nvim-lspconfig`, which is a package used for this purpose. For more info, `kickstart.nvim` has a great example setup. +- A newer way is to use the new Neovim LSP API for versions newer than v0.11.0 via `vim.lsp`. + +Using the Lazy package manager with `nvim-lspconfig`: +```lua +require('lazy').setup({ + -- other packages... + { + 'neovim/nvim-lspconfig', + config = function() + vim.api.nvim_create_autocmd('LspAttach', { + -- your keybindings here... + }) + + -- this part may contain your existing LSP setup that play along nicely with Mason... + + -- add this line specifically for OCaml + require('lspconfig').ocamllsp.setup {} + end, + }, + -- other packages... +}) +``` + +Using `vim.lsp`: +```lua +-- add this to your toplevel init.lua +vim.lsp.config['ocamllsp'] = { + cmd = { 'ocamllsp' }, + filetypes = { 'ocaml', 'ocaml.interface', 'ocaml.menhir', 'reason' }, + root_markers = { { 'dune-project', 'dune-workspace' }, '.git' }, + settings = {}, +} + +vim.lsp.enable 'ocamllsp' +``` + +You can also use `vim.lsp` with a modular config. + +Assume that your config has the following structure. The internal structure of `lua` does not matter much. +```text +. +├── init.lua +└── lua + ├── custom + │   └── plugins + │   └── some-plugin.lua + └── kickstart +    ├── health.lua +    └── plugins +    └── some-plugin.lua +``` + +Then run the following. +```text +cd lua +mkdir lsp +touch lsp/init.lua +touch lsp/servers.lua +``` + +We now add our LSP configs to `lsp/servers.lua`, export them from `lsp/init.lua`, and import them in the toplevel `init.lua`. +```lua +-- path/to/config/lua/lsp/servers.lua +vim.lsp.config['ocamllsp'] = { + cmd = { 'ocamllsp' }, + filetypes = { 'ocaml', 'ocaml.interface', 'ocaml.menhir', 'reason' }, + root_markers = { { 'dune-project', 'dune-workspace' }, '.git' }, + settings = {}, +} + +vim.lsp.enable 'ocamllsp' + +-- path/to/config/lua/lsp/init.lua +require("lsp.servers") + +-- path/to/config/init.lua +require("lsp") +``` From be18a82df7d3336844e09027550008a2ee26aeb9 Mon Sep 17 00:00:00 2001 From: jpoly1219 Date: Fri, 19 Sep 2025 09:16:26 -0700 Subject: [PATCH 2/5] fix: trim docs --- .../getting-started/2_00_editor_setup.md | 60 ++++++++----------- 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/data/tutorials/getting-started/2_00_editor_setup.md b/data/tutorials/getting-started/2_00_editor_setup.md index 0257210125..40330be310 100644 --- a/data/tutorials/getting-started/2_00_editor_setup.md +++ b/data/tutorials/getting-started/2_00_editor_setup.md @@ -158,33 +158,13 @@ opam install ocaml-lsp-server ocamlformat ``` There are two main ways to install and manage LSP servers. -- A more traditional way is to use `nvim-lspconfig`, which is a package used for this purpose. For more info, `kickstart.nvim` has a great example setup. -- A newer way is to use the new Neovim LSP API for versions newer than v0.11.0 via `vim.lsp`. +- A newer, more recommended way is to use the new Neovim LSP API for versions newer than v0.11.0 via `vim.lsp`. +- A more traditional way is to use `nvim-lspconfig`. For more info, `kickstart.nvim` has a great example setup. -Using the Lazy package manager with `nvim-lspconfig`: -```lua -require('lazy').setup({ - -- other packages... - { - 'neovim/nvim-lspconfig', - config = function() - vim.api.nvim_create_autocmd('LspAttach', { - -- your keybindings here... - }) - - -- this part may contain your existing LSP setup that play along nicely with Mason... - - -- add this line specifically for OCaml - require('lspconfig').ocamllsp.setup {} - end, - }, - -- other packages... -}) -``` +### Using vim.lsp: -Using `vim.lsp`: +Add this to your toplevel `init.lua`. ```lua --- add this to your toplevel init.lua vim.lsp.config['ocamllsp'] = { cmd = { 'ocamllsp' }, filetypes = { 'ocaml', 'ocaml.interface', 'ocaml.menhir', 'reason' }, @@ -211,29 +191,39 @@ Assume that your config has the following structure. The internal structure of `    └── some-plugin.lua ``` -Then run the following. +Then run the following at the root of your config. ```text -cd lua mkdir lsp -touch lsp/init.lua -touch lsp/servers.lua +touch lsp/ocamllsp.lua ``` -We now add our LSP configs to `lsp/servers.lua`, export them from `lsp/init.lua`, and import them in the toplevel `init.lua`. +We now add our LSP configs to `lsp/ocamllsp.lua`... ```lua --- path/to/config/lua/lsp/servers.lua -vim.lsp.config['ocamllsp'] = { +return { cmd = { 'ocamllsp' }, filetypes = { 'ocaml', 'ocaml.interface', 'ocaml.menhir', 'reason' }, root_markers = { { 'dune-project', 'dune-workspace' }, '.git' }, settings = {}, } +``` +...and import them in the toplevel `init.lua`. +```lua vim.lsp.enable 'ocamllsp' +``` --- path/to/config/lua/lsp/init.lua -require("lsp.servers") +### Using nvim-lspconfig --- path/to/config/init.lua -require("lsp") +Add this to your `nvim-lspconfig` setup. +```lua +{ + 'neovim/nvim-lspconfig', + config = function() + -- rest of config... + + -- add this line specifically for OCaml + require('lspconfig').ocamllsp.setup {} + end, +}, ``` + From 21015539c3937d3a86d777d9299cc64e0bb7fa6b Mon Sep 17 00:00:00 2001 From: jpoly1219 Date: Fri, 19 Sep 2025 22:51:41 -0700 Subject: [PATCH 3/5] fix: wording --- .../getting-started/2_00_editor_setup.md | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/data/tutorials/getting-started/2_00_editor_setup.md b/data/tutorials/getting-started/2_00_editor_setup.md index 40330be310..a169421c42 100644 --- a/data/tutorials/getting-started/2_00_editor_setup.md +++ b/data/tutorials/getting-started/2_00_editor_setup.md @@ -175,29 +175,30 @@ vim.lsp.config['ocamllsp'] = { vim.lsp.enable 'ocamllsp' ``` -You can also use `vim.lsp` with a modular config. +See `:h lsp-config` for more detail on configuration options. -Assume that your config has the following structure. The internal structure of `lua` does not matter much. -```text -. -├── init.lua -└── lua - ├── custom - │   └── plugins - │   └── some-plugin.lua - └── kickstart -    ├── health.lua -    └── plugins -    └── some-plugin.lua -``` +#### Modular Config With Runtimepath + +You can also use `vim.lsp` with a modular config via `runtimepath`. Putting your config table inside `lsp/.lua` or `after/lsp/.lua` will allow Neovim to search for them automatically. + +See `:h runtimepath` for more detail. -Then run the following at the root of your config. +Run the following at the root of your config. ```text mkdir lsp touch lsp/ocamllsp.lua ``` -We now add our LSP configs to `lsp/ocamllsp.lua`... +Your Neovim config should have the following structure now. +```text +. +├── init.lua +├── lsp +│ └── ocamllsp.lua +└── ... +``` + +Add your LSP config to `lsp/ocamllsp.lua`. ```lua return { cmd = { 'ocamllsp' }, @@ -207,7 +208,7 @@ return { } ``` -...and import them in the toplevel `init.lua`. +Then enable them in the toplevel `init.lua`. ```lua vim.lsp.enable 'ocamllsp' ``` @@ -227,3 +228,5 @@ Add this to your `nvim-lspconfig` setup. }, ``` +There is no need to pass more settings to `setup` because `nvim-lspconfig` provides reasonable defaults. See [here](https://github.com/neovim/nvim-lspconfig/blob/master/lsp/ocamllsp.lua) for more info. + From d2f6eeeb8bfcfb668c3d31dc7b50c0b387804509 Mon Sep 17 00:00:00 2001 From: jpoly1219 Date: Fri, 19 Sep 2025 23:34:02 -0700 Subject: [PATCH 4/5] fix: reword modular --- data/tutorials/getting-started/2_00_editor_setup.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/tutorials/getting-started/2_00_editor_setup.md b/data/tutorials/getting-started/2_00_editor_setup.md index a169421c42..68c06fa320 100644 --- a/data/tutorials/getting-started/2_00_editor_setup.md +++ b/data/tutorials/getting-started/2_00_editor_setup.md @@ -177,9 +177,9 @@ vim.lsp.enable 'ocamllsp' See `:h lsp-config` for more detail on configuration options. -#### Modular Config With Runtimepath +#### Using vim.lsp With runtimepath -You can also use `vim.lsp` with a modular config via `runtimepath`. Putting your config table inside `lsp/.lua` or `after/lsp/.lua` will allow Neovim to search for them automatically. +You can also move your LSP config to a separate file via `runtimepath` if you'd like to keep your `init.lua` minimal. Putting your config table inside `lsp/.lua` or `after/lsp/.lua` will allow Neovim to search for them automatically. See `:h runtimepath` for more detail. From 58a5b907d23b5cd84bb645894d29fe138eed2d07 Mon Sep 17 00:00:00 2001 From: jpoly1219 Date: Sat, 20 Sep 2025 12:54:45 -0700 Subject: [PATCH 5/5] fix: add more filetypes and root paths --- .../getting-started/2_00_editor_setup.md | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/data/tutorials/getting-started/2_00_editor_setup.md b/data/tutorials/getting-started/2_00_editor_setup.md index 68c06fa320..ef24c24b70 100644 --- a/data/tutorials/getting-started/2_00_editor_setup.md +++ b/data/tutorials/getting-started/2_00_editor_setup.md @@ -167,8 +167,19 @@ Add this to your toplevel `init.lua`. ```lua vim.lsp.config['ocamllsp'] = { cmd = { 'ocamllsp' }, - filetypes = { 'ocaml', 'ocaml.interface', 'ocaml.menhir', 'reason' }, - root_markers = { { 'dune-project', 'dune-workspace' }, '.git' }, + filetypes = { + 'ocaml', + 'ocaml.interface', + 'ocaml.menhir', + 'ocaml.ocamllex', + 'dune', + 'reason' + }, + root_markers = { + { 'dune-project', 'dune-workspace' }, + { "*.opam", "esy.json", "package.json" }, + '.git' + }, settings = {}, } @@ -202,8 +213,19 @@ Add your LSP config to `lsp/ocamllsp.lua`. ```lua return { cmd = { 'ocamllsp' }, - filetypes = { 'ocaml', 'ocaml.interface', 'ocaml.menhir', 'reason' }, - root_markers = { { 'dune-project', 'dune-workspace' }, '.git' }, + filetypes = { + 'ocaml', + 'ocaml.interface', + 'ocaml.menhir', + 'ocaml.ocamllex', + 'dune', + 'reason' + }, + root_markers = { + { 'dune-project', 'dune-workspace' }, + { "*.opam", "esy.json", "package.json" }, + '.git' + }, settings = {}, } ```