-
Notifications
You must be signed in to change notification settings - Fork 366
feat: add docs for neovim setup #3322
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,7 +49,7 @@ | |
1. Go to `File` > `Preferences` > `Settings` view (or press `Ctrl ,`) | ||
2. Select `User` > `Extensions` > `OCaml Platform` | ||
3. Uncheck `OCaml: Use OCaml Env`. That's it! | ||
|
||
Check failure on line 52 in data/tutorials/getting-started/2_00_editor_setup.md
|
||
## Emacs | ||
|
||
Using Emacs to work with OCaml requires at least two modes: | ||
|
@@ -73,7 +73,7 @@ | |
:mode (("\\.ocamlinit\\'" . tuareg-mode))) | ||
``` | ||
|
||
|
||
Check failure on line 76 in data/tutorials/getting-started/2_00_editor_setup.md
|
||
#### Melpa and `use-package` | ||
|
||
If your version of Emacs does not support the `use-package` macro (or is not set up to take MELPA packages into account), please update it and follow these instructions to install [`use-package`](https://github.com/jwiegley/use-package) and [MELPA](https://melpa.org/#/getting-started). | ||
|
@@ -110,7 +110,7 @@ | |
|
||
OCaml-eglot can be finely configured, the project [README](https://github.com/tarides/ocaml-eglot/blob/main/README.md) gives several configuration paths to adapt perfectly to your workflow. You will also find there an exhaustive presentation of the different functions offered by the mode. | ||
|
||
|
||
Check failure on line 113 in data/tutorials/getting-started/2_00_editor_setup.md
|
||
#### Getting Type Information | ||
|
||
Opening an OCaml file should launch an `ocaml-lsp` server, and you can convince yourself that it's working by using, for example, the `ocaml-eglot-type-enclosing` command (or using the `C-c C-t` binding) on an expression of your choice: | ||
|
@@ -119,7 +119,7 @@ | |
|
||
OCaml-eglot [README](https://github.com/tarides/ocaml-eglot/blob/main/README.md) provides a comprehensive overview of all the functions available in this mode! | ||
|
||
|
||
Check failure on line 122 in data/tutorials/getting-started/2_00_editor_setup.md
|
||
## Vim | ||
|
||
For Vim, we won't use the LSP server but rather directly talk to Merlin. | ||
|
@@ -136,7 +136,7 @@ | |
|
||
### Talking to Merlin | ||
|
||
#### Getting Type Information | ||
Check failure on line 139 in data/tutorials/getting-started/2_00_editor_setup.md
|
||
|
||
 | ||
|
||
|
@@ -145,3 +145,110 @@ | |
- Type `:MerlinTypeOf` and press <kbd>Enter</kbd>. | ||
- 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 | ||
Check failure on line 156 in data/tutorials/getting-started/2_00_editor_setup.md
|
||
opam install ocaml-lsp-server ocamlformat | ||
``` | ||
|
||
There are two main ways to install and manage LSP servers. | ||
- A newer, more recommended way is to use the new Neovim LSP API for versions newer than v0.11.0 via `vim.lsp`. | ||
Check failure on line 161 in data/tutorials/getting-started/2_00_editor_setup.md
|
||
- A more traditional way is to use `nvim-lspconfig`. For more info, `kickstart.nvim` has a great example setup. | ||
|
||
### Using vim.lsp: | ||
Check failure on line 164 in data/tutorials/getting-started/2_00_editor_setup.md
|
||
|
||
Add this to your toplevel `init.lua`. | ||
```lua | ||
Check failure on line 167 in data/tutorials/getting-started/2_00_editor_setup.md
|
||
vim.lsp.config['ocamllsp'] = { | ||
cmd = { 'ocamllsp' }, | ||
filetypes = { | ||
'ocaml', | ||
'ocaml.interface', | ||
'ocaml.menhir', | ||
'ocaml.ocamllex', | ||
'dune', | ||
'reason' | ||
}, | ||
root_markers = { | ||
{ 'dune-project', 'dune-workspace' }, | ||
{ "*.opam", "esy.json", "package.json" }, | ||
'.git' | ||
}, | ||
settings = {}, | ||
} | ||
|
||
vim.lsp.enable 'ocamllsp' | ||
``` | ||
|
||
See `:h lsp-config` for more detail on configuration options. | ||
|
||
#### Using vim.lsp With runtimepath | ||
|
||
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/<some_name>.lua` or `after/lsp/<some_name>.lua` will allow Neovim to search for them automatically. | ||
|
||
See `:h runtimepath` for more detail. | ||
|
||
Run the following at the root of your config. | ||
```text | ||
Check failure on line 198 in data/tutorials/getting-started/2_00_editor_setup.md
|
||
mkdir lsp | ||
touch 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' }, | ||
filetypes = { | ||
'ocaml', | ||
'ocaml.interface', | ||
'ocaml.menhir', | ||
'ocaml.ocamllex', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one doesn't actually seem to work on NeoVim 0.11.4 and ocamllsp 1.23.0. The rest seems to work. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #3322 (comment) workaround, but |
||
'dune', | ||
'reason' | ||
}, | ||
root_markers = { | ||
{ 'dune-project', 'dune-workspace' }, | ||
{ "*.opam", "esy.json", "package.json" }, | ||
'.git' | ||
}, | ||
settings = {}, | ||
} | ||
``` | ||
|
||
Then enable them in the toplevel `init.lua`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. another nit: Can we explain what
Not sure if we want to mention There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like this is a bit out of scope for the purpose of this doc. I think the curious readers will go out and research this further on their own. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe instead of calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are already mentioning it. |
||
```lua | ||
vim.lsp.enable 'ocamllsp' | ||
``` | ||
|
||
### Using nvim-lspconfig | ||
|
||
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 {} | ||
This comment was marked as resolved.
Sorry, something went wrong. |
||
end, | ||
}, | ||
``` | ||
|
||
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. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we explain about tree-sitter? (with
It isn't strictly required, although might help with performance on large files, before the LSP finishes parsing it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good. Let me know if you have more updates 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I figured out how to configure tree-sitter for ocamllex, but it is quite complicated: ocaml/vim-ocaml#61 (comment). For now I'd leave out tree-sitter from the official docs, until that PR is merged (and an equivalent PR is merged into NeoVim). The workaround is (fixes both picking the right tree-sitter syntax and the LSP errors): vim.filetype.add({
extension = {
mll = 'ocamllex',
mly = 'menhir',
mli = 'ocamlinterface'
}
}) followed by the usual tree-sitter config: local treesitter_langs = {
'menhir', 'ocaml', 'ocaml_interface', 'ocamllex'
}
require('nvim-treesitter').install(treesitter_langs) (This doesn't require a new release of NeoVim to work, but if your tree-sitter grammar fails to install you'll be without syntax highlighting, so I wouldn't propose it in the official docs, even though I'll start using it myself). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
I proposed this simplification to the upstream
nvim-lspconfig
, which was using aroot_dir
function andlspconfig.util
instead (which appears deprecated).