We're happy to announce the release of ocaml-lsp-server 1.24.0
, which brings support for OCaml 5.4!
For more details, see the related announcement on the Discuss forums!
Official stable release announcements and updates from the OCaml compiler, OCaml infrastructure and the OCaml Platform Tools.
We're happy to announce the release of ocaml-lsp-server 1.24.0
, which brings support for OCaml 5.4!
For more details, see the related announcement on the Discuss forums!
We're happy to announce the release of ocaml-lsp-server
1.23.1!
This maintenance release fixes three key issues:
.mll
(OCamllex lexer) files in editors like NeoVimUpdate via opam: opam update && opam upgrade ocaml-lsp-server
For more details, see the related announcement on the Discuss forums!
ocaml-eglot
provides full OCaml language support in Emacs through the Language Server Protocol (LSP) instead of direct Merlin integration. It offers the same features as merlin.el
with simplified setup and enhanced capabilities like project-wide search. If you're starting fresh or want a more standardized approach, try ocaml-eglot
, which is actively maintained. If your current merlin.el
setup works well, you can continue using it.
Quick start: Install ocaml-lsp-server
, add ocaml-eglot
to your Emacs config, and get the same OCaml development experience with less configuration.
ocaml-eglot
connects Emacs to ocaml-lsp-server
using the Language Server Protocol, providing a standardized way to get OCaml language support.
Since the recent versions of Emacs (29), eglot
, an LSP client, has been shipped with Emacs. However, merlin.el
provides more features than LSP (which is designed to be generic), so relying solely on the features of LSP and eglot
would limit functionality. Thus, we extended the LSP server to support more features, and ocaml-eglot
allows you to benefit from these features in Emacs.
ocaml-eglot
is a minor mode. It therefore works in conjunction with a major mode to edit Caml code. Examples of major modes include tuareg
, caml-mode
and the recent neocaml
.
Use ocaml-eglot if you:
If your current setup is working perfectly and is heavily customised, merlin.el
will still keep working, so there's no immediate need to migrate. However, for the moment, we don't plan to actively maintain merlin.el
-- unless we receive a lot of requests.
Follow the installation instructions in the ocaml-eglot README.
When migrating from merlin.el
to ocaml-eglot
, your existing keybindings should work immediately!
Error Navigation: Quick jump to next/previous errors
Type Information: Display types under cursor with adjustable verbosity, navigate enclosing expressions
Code Generation: Pattern matching construction, case completion, wildcard refinement via "destruct" feature
Navigation: Jump between language constructs (let, module, function, match), navigate phrases and pattern cases
Search: Find definitions, declarations, and references
For a detailed list of features, see the ocaml-eglot README.
ocaml-eglot
On January 17, 2025, ocaml-eglot version 1.0.0 was released, providing a new minor emacs mode to enable the editor features provided by ocaml-lsp-server. Subsequent releases 1.1.0 and 1.2.0 enable support for flycheck
as a configurable alternative to flymake
(1.0.0
release), Emacs 30.1
support, better user experience and error handling, as well as support for new features.
We're pleased to announce the release of OCaml LSP Server 1.23.0!
inlay-hint
for function parameters configurable (#1515)ocamllsp/jumpToTypedHole
to navigate through typed holes (#1516)yojson_of_t
for Nullable_option
: serialize None
as Null
instead of asserting false (#1525 fixes #1524)class
, class type
, method
and property
for DocumentSymbol
query (#1487 fixes #1449)inlay-hint
for function parameters (#1515)Definition_query
) (#1518)ocamlformat
application after destruct
(that remove some useful parenthesis) (#1519)We're pleased to announce the release of OCaml LSP Server 1.21.0-4.14!
Make inlay-hint
for function parameters configurable (#1515)
Add custom ocamllsp/jumpToTypedHole
to navigate through typed holes (#1516)
Add a code-action for combining pattern cases (just relaying on regex) (#1514)
Allow (by configuration) shortening of diagnostics (just highlighting the first line) (#1513)
Fix yojson_of_t
for Nullable_option
: serialize None
as Null
instead of asserting false (#1525 fixes #1524)
Support for class
, class type
, method
and property
for DocumentSymbol
query (#1487 fixes #1449)
Fix inlay-hint
for function parameters (#1515)
More precise diagnostics in the event of a failed identifier search (Definition_query
) (#1518)
Remove ocamlformat
application after destruct
(that remove some useful parenthesis) (#1519)
Add a new server option standardHover
, that can be used by clients to
disable the default hover provider. When standardHover = false
textDocument/hover
requests always returns with empty result. (#1416)
We're pleased to announce the release of OCaml LSP Server 1.22.0, which enables experimental project-wide renaming of identifiers!
OCaml LSP Server version 1.21.0 is now available. This release introduces a new server option called standardHover
that allows clients to disable the default hover provider functionality.
standardHover
, that can be used by clients tostandardHover = false
textDocument/hover
requests always returns with empty result. (#1416)We are excited to share the release of OCaml-LSP 1.20.1, which introduces powerful new features and vital bug fixes to improve your development workflow. The new typeSearch
request allows you to find values by type signature or polarity, making it easier to locate the functionality you need. Configurable MerlinJump
actions and the custom jump
request give you more control over code navigation. On the bug fix side, we have tackled issues like file descriptor leaks, enhanced method completion, and cleaned up duplicate responses in selectionRange
.
ocamllsp/typeSearch
request (#1369)ocamllsp/jump
request (#1374)merlinJumpCodeActions
configuration option. Alternatively, a custom request is provided for ad hoc use of the feature. (#1411)selectionRange
answers (#1368)We are pleased to announce the release of OCaml LSP 1.19.0. This version brings official support for OCaml 5.2. It also includes a new custom query to get
documentation and a fix regarding the handling of OCamlFormat processes.
ocamllsp/getDocumentation
request (ocaml/ocaml-lsp#1336)sigterm
rather than sigint
or sigkill
(ocaml/ocaml-lsp#1343)We are pleased to announce the release of OCaml LSP 1.18.0. This version comes with a lot of fixes and new features.
Notable features that are included in this release are:
TypeEnclosing
ifthenelse
expressions...and many fixes to a handful of issues.
Feedback is very much welcomed on the the Discuss Announcement post and do not hesistate to report issues in the issue tracker.
Introduce a configuration option to control Dune diagnostics. The option is called duneDiganostics
, and it may be set to { enable: false }
to disable diagnostics. (ocaml/ocaml-lsp#1221)
Support folding of ifthenelse
expressions (ocaml/ocaml-lsp#1031)
Improve hover behavior (ocaml/ocaml-lsp#1245)
Hovers are no longer displayed on useless parse tree nodes such as keywords, comments, etc.
Multiline hovers are now filtered away.
Display expanded PPXs in the hover window.
Improve document symbols (ocaml/ocaml-lsp#1247)
Use the parse tree instead of the typed tree. This means that document symbols will work even if the source code doesn't type check.
Include symbols at arbitrary depth.
Differentiate functions / types / variants / etc.
This now includes PPXs like let%expect_test
or let%bench
in the outline.
Introduce a destruct-line
code action. This is an improved version of the
old destruct
code action. (ocaml/ocaml-lsp#1283)
Improve signature inference to only include types for elements that were absent from the signature. Previously, all signature items would always be inserted. (ocaml/ocaml-lsp#1289)
Add an update-signature
code action to update the types of elements that
were already present in the signature (ocaml/ocaml-lsp#1289)
Add custom
ocamllsp/merlinCallCompatible
request (ocaml/ocaml-lsp#1265)
Add custom ocamllsp/typeEnclosing
request (ocaml/ocaml-lsp#1304)
Detect document kind by looking at Merlin's suffixes
config.
This enables more LSP features for non-.ml/.mli
files. Though it still
depends on Merlin's support. (ocaml/ocaml-lsp#1237)
Correctly accept the --clientProcessId
flag. (ocaml/ocaml-lsp#1242)
Disable automatic completion and signature help inside comments (ocaml/ocaml-lsp#1246)
Includes a new optional/configurable option to toggle syntax documentation. If toggled on, allows display of syntax documentation on hover tooltips. Can be controlled via environment variables and by GUI for VS code. (ocaml/ocaml-lsp#1218)
For completions on labels that the LSP gets from Merlin, take into account
whether the prefix being completed starts with ~
or ?
. Change the label
completions that start with ?
to start with ~
when the prefix being
completed starts with ~
. (ocaml/ocaml-lsp#1277)
Fix document syncing (ocaml/ocaml-lsp#1278, ocaml/ocaml-lsp#1280, fixes ocaml/ocaml-lsp#1207)
Stop generating inlay hints on generated code (ocaml/ocaml-lsp#1290)
Fix parenthesising of function types in SignatureHelp
(ocaml/ocaml-lsp#1296)
Fix syntax documentation rendering (ocaml/ocaml-lsp#1318)
We are pleased to announce the release of OCaml LSP 1.17.0. This version comes packed with fixes and new features.
Notable features that come in this release include:
in
keyword completing to other terms in the editor, we've added auto-completion for this keyword in OCaml LSP. Typing in
will now only suggest auto completion for the in
keyword.--fallback-read-dot-merlin
flag is on. (#1173)in
(#1217)We've released OCaml LSP 1.16.2 with a fix that was introduced in 1.16.1 that prevented users from using preprocessor such as CPPO.
We're thrilled to announce the release of OCaml LSP 1.16.1! 🎉
This release comes with new "Extract local" and "Extract function" code actions to easily refactor your code.
We've also disabled code lenses by default following user feedback. You can follow the discussion on GitHub.
This release is also the first OCaml LSP release to use upstream Merlin. Among other things, this means that it is compatible with all the OCaml versions supported by Merlin: currently OCaml 4.14 and 5.0.0.
We're also releasing numerous bug fixes, including:
And much more! Read the full changelog for a complete list of improvements and bug fixes.
didChangeConfiguration
notification (#1103)merlin-lib
4.9 (#1070)Support building with OCaml 5.0 and 5.1 (#1150)
Disable code lens by default. The support can be re-enabled by explicitly setting it in the configuration. (#1134)
Fix initilization of ocamlformat-rpc
in some edge cases when ocamlformat is
initialized concurrently (#1132)
Kill unnecessary $ dune ocaml-merlin
with SIGTERM rather than SIGKILL
(#1124)
Refactor comment parsing to use odoc-parser
and cmarkit
instead of
octavius
and omd
(#1088)
This allows users who migrated to omd 2.X to install ocaml-lsp-server in the same opam switch.
We also slightly improved markdown generation support and fixed a couple in the generation of inline heading and module types.
Allow opening documents that were already open. This is a workaround for neovim's lsp client (#1067)
Disable type annotation for functions (#1054)
Respect codeActionLiteralSupport capability (#1046)
Fix a document syncing issue when utf-16 is the position encoding (#1004)
Disable "Type-annotate" action for code that is already annotated. (#1037, fixes #1036)
Fix semantic highlighting of long identifiers when using preprocessors (#1049, fixes #1034)
Fix the type of DocumentSelector in cram document registration (#1068)
Accept the --clientProcessId
command line argument. (#1074)
Accept --port
as a synonym for --socket
. (#1075)
Fix connecting to dune rpc on Windows. (#1080)
On behalf of the ocaml-lsp team, I’m pleased to announce ocaml-lsp-server versions 1.15.0-4.14
and 1.15.0-5.0
for OCaml 4.14 and 5.0, respectively. This is the first time we release ocaml-lsp supporting two compiler versions. We look forward to your feedback.
Enable semantic highlighting support by default (#933)
Support connecting over pipes and socket. Pipes on Windows aren't yet supported (#946)
More about communication channels in LSP specification.
Re-enable ocamlformat-rpc
for formatting code snippets (but not files and
not on Windows) (#920, #939)
One needs to have installed either ocamlformat
package version > 0.21.0 or,
otherwise, ocamlformat-rpc
package. Note that previously ocamlformat-rpc
came in a standalone OPAM package, but since ocamlformat
version > 0.21.0,
it comes within ocamlformat
package.
Add custom ocamllsp/hoverExtended
request (#561)
Support utf-8 position encoding clients (#919)
More about position encoding in LSP specification.
Show unwrapped module alias types on hovering over module names. This is due
to upgrading to merlin 4.7 and using merlin's verbosity=smart
by default
(#942)
Respect the client's completion item resolve and preSelect capabilities (#925, #936)
Disable polling for dune's watch mode on Windows and OCaml 4.14.0 (#935)
Fix semantic highlighting of "long identifiers," e.g., Foo.Bar.x
(#932)
Fix syncing of document contents:
Fix random requests failing after switching documents (#904, fixes #898)
Do not offer related diagnostic information unless the user enables in client capabilities (#905)
Do not offer diagnostic tags unless the client supports them (#909)
Do not attach extra data to diagnostics unless the client supports this (#910)
Use /bin/sh instead of /bin/bash. This fixes ocamllsp on NixOS
Fix various server crashes when opening non OCaml/Reason files. Files such as dune, cram, etc. would cause the server to crash. (#884, fixes #871)
Ignore unknown tags in merlin configuration to improve forward compatibility with Dune. (#883)
On behalf of the ocamllsp team, I'm pleased to announce version 1.14.0. This release contains a new code action to help you inline definitions thanks to @jfeser. We look forward to your feedback.
Code action for inlining let bindings within a module or expression. (#847)
Tag "unused code" and "deprecated" warnings, allowing clients to better display them. (#848)
Refresh merlin configuration after every dune build in watch mode (#853)
Respect showDocument
capabilities. Do not offer commands or code actions
that rely on this request without client support. (#836)
Fix signatureHelp on .mll files: avoid "Document.dune" exceptions
.ml
, .mli
, etc.) (#795)Allow cancellation of workspace symbols requests (#777)
Fix unintentionally interleaved jsonrpc IO that would corrupt the session (#786)
Ignore SIGPIPE
. (#788)
Fix a bad interaction between inferred interfaces and promotion code actions in watch mode (#753)
Fix URI parsing (#739 fixes #471 and #459)
Fix preprocessing, ppx, and reason support (#735 fixes #696, #706)
Support include
in folding ranges (#730)
Fix cancellation mechanism for all requests (#707)
Allow cancellation of formatting requests (#707)
Add --fallback-read-dot-merlin
to the LSP Server (#705). If ocamllsp
is
started with this new flag, it will fall back to looking for Merlin
configuration in .merlin
files rather than calling dune ocaml-merlin
.
(#705)
Support folding more ranges (#692)
Fix process termination. Once the lsp server is stepped, the process will gracefully terminate (#697, fixes #694)
Forward stderr from dune's merlin configuration to the lsp server's stderr (#697)
Fix bug with large buffers being resized incorrectly in Lev
Add folding ranges for more AST types (#680)
Fix Uri handling on Windows
Fix build on MSVC 2015
On behalf of the ocamllsp team, I’m excited to announce the availability of version 1.11.0. This release is an important milestone for the project because it introduces integration with our favorite build system. When you run dune in watch mode, you will now be able to see build errors in the diagnostics panel of your editor. It’s all rather experimental for now, so your feedback and bug reports are appreciated.
As usual, the full change log is below.
Happy hacking.
Add support for dune in watch mode. The lsp server will now display build errors in the diagnostics and offer promotion code actions.
Re-introduce ocamlformat-rpc (#599, fixes #495)
Catch merlin desturct exceptions (#626)
Fix broken debouncing (#627)
On behalf of the ocamllsp team, I’m pleased to announce version 1.10.0. The only new feature this release offers is better code folding, but there are some important bug fixes and performance improvements. If you encounter any sluggishness with our server, do not hesitate to report it.
Unless there are serious bugs with this release, this will be the last release for OCaml 4.13.
Happy Hacking.
Fix infer interface code action crash when implementation source does not exist (#597)
Improve error message when the reason plugin for merlin is absent (#608)
Fix chdir
races when running ppx (#550)
More accurate completion kinds. New completion kinds for variants and fields. Removed inaccurate completion kinds for constructors and types. (#510)
Fix handling request cancellation (#616)
Disable functionality reliant on ocamlformat-rpc for now (#555)
4.13 compatiblity
.merlin
files, and as a consequence no longer
depends on dot-merlin-reader. (#523)Fix debouncing of document updates. It was essentially completely broken in all but the most trivial cases. (#509 fixes #504)
Fix completion when passing named and functional arguments (#512)
On behalf of the ocaml-lsp team, I’m pleased to announce version 1.8.0. This release contains some quality of life bug fixes, better diagnostics locations, and a few new code actions. Happy hacking.
Add a new code action Add missing rec keyword
, which is available when
adding a rec
keyword can fix Unbound value ...
error, e.g.,
let fact n = if n = 0 then 1 else n * fact (n - 1)
(* ^^^^ Unbound value fact *)
Adding rec
to the definition of fact
will fix the problem. The new code
action offers adding rec
.
Use ocamlformat to properly format type snippets. This feature requires the
ocamlformat-rpc
opam package to be installed. (#386)
Add completion support for polymorphic variants, when it is possible to pin
down the precise type. Examples (<|>
stands for the cursor) when completion
will work (#473)
Function application:
let foo (a: [`Alpha | `Beta]) = ()
foo `A<|>
Type explicitly shown:
let a : [`Alpha | `Beta] = `B<|>
Note: this is actually a bug fix, since we were ignoring the backtick when constructing the prefix for completion.
Parse merlin errors (best effort) into a more structured form. This allows reporting all locations as "related information" (#475)
Add support for Merlin Construct
command as completion suggestions, i.e.,
show complex expressions that could complete the typed hole. (#472)
Add a code action Construct an expression
that is shown when the cursor is
at the end of the typed hole, i.e., _|
, where |
is the cursor. The code
action simply triggers the client (currently only VS Code is supported) to
show completion suggestions. (#472)
Change the formatting-on-save error notification to a warning notification (#472)
Code action to qualify ("put module name in identifiers") and unqualify ("remove module name from identifiers") module names in identifiers (#399)
Starting from:
open Unix
let times = Unix.times ()
let f x = x.Unix.tms_stime, x.Unix.tms_utime
Calling "remove module name from identifiers" with the cursor on the open statement will produce:
open Unix
let times = times ()
let f x = x.tms_stime, x.tms_utime
Calling "put module name in identifiers" will restore:
open Unix
let times = Unix.times ()
let f x = x.Unix.tms_stime, x.Unix.tms_utime
Handle workspace change notifications. Previously, the server would only use the set of workspaces given at startup to search for workspace symbols. After this change, workspace folders that are added later will also be considered. (#498)
Do not show "random" documentation on hover
Correctly rename a variable used as a named/optional argument (#478)
When reporting an error at the beginning of the file, use the first line not the second (#489)
Add sub-errors as "related" information in diagnostics (#457)
Add support for navigating to a symbol inside a workspace (#398)
Show typed holes as errors
Merlin has a concept of "typed holes" that are syntactically represented as _
. Files
that incorporate typed holes are not considered valid OCaml, but Merlin and OCaml-LSP
support them. One example when such typed holes can occur is when on "destructs" a value,
e.g., destructing (Some 1)
will generate code match Some 1 with Some _ -> _ | None -> _
. While the first underscore is a valid "match-all"/wildcard pattern, the rest of
underscores are typed holes.
Switch verbosity
from 1 to 0. This is the same default that merlin uses.
The old value for verbosity (#433)
Get fresh diagnostics (warning and error messages) on a file save (#438)
Note: If you want the fresh diagnostics to take into account changes in other
files, you likely need to rebuild your project. An easy way to get automatic
rebuilds is to run dune
in a watching mode, e.g.,[dune build --watch].
On behalf of the ocaml-lsp team, I'd like to announce version 1.6.0 of ocaml-lsp-server. The highlight of this release is the updated version of merlin which brings lots of new bug fixes.
Fix interface/implementation switching on Windows (#427)
Correctly parse project paths with spaces and other special characters that must be escaped.
Print types with -short-paths
even if the project wasn't built yet
Support 4.12 and drop support for all earlier versions
Update to the latest version of merlin
Backport fixes from merlin (#382, #383)
Encode request & notification params
in a list. This is required by the
spec. (#351)
On behalf of the ocaml-lsp team, it is my pleasure to announce version 1.4.0. This release introduces support for automatic signature help. Signature help is not yet present in all possible contexts. We intend to improve to support as many relevant language constructs as possible in the future. Many thanks to @mnxn for implementing this feature.
The full change log is replicated at the end of this post for your convenience.
Happy Holidays!
Support cancellation notifications when possible. (#323)
Implement signature help request for functions (#324)
Server LSP requests & notifications concurrently. Requests that require merlin are still serialized. (#330)
On behalf of the ocaml-lsp team, I’d like to announce version 1.3.0.
This release an improvement in keyword completion and a new code action. Keywords are now filtered by the context the user requested the completion, and there’s a new code action to quickly populate .mli files with the the inferred types from the .ml file.
Code action to insert inferred module interface (#308)
Filter keywords by context (#307)