neocaml¶
neocaml is a new Emacs package for programming in
OCaml. Built on
Tree-sitter, it provides major
modes for editing OCaml (.ml) and OCaml Interface (.mli) files with
font-locking, indentation, navigation, and toplevel (REPL) integration.
Beyond OCaml source code, neocaml also supports key parts of the OCaml
ecosystem: dune build files,
opam package definitions,
OCamllex lexer definitions (.mll),
Menhir parser definitions (.mly),
and cram test
files (.t) -- each with a dedicated major mode.
You can also view compiled OCaml artifacts (.cmi, .cmo, .cmx, etc.)
directly in Emacs via ocamlobjinfo.
It's also as cool as Neo from "The Matrix". ;-)
Why?¶
Because caml-mode is ancient, and tuareg, while very powerful, has
grown complex over the years. The time seems ripe for a modern, leaner,
tree-sitter-powered mode for OCaml.
There have been two earlier attempts at tree-sitter OCaml modes for Emacs:
Both provided useful early exploration of what a tree-sitter OCaml mode could look like, and helped inspire this project. neocaml aims to take the idea further with a more complete feature set and active maintenance.
They say that third time's the charm, right?
One last thing - we really need more Emacs packages with fun names! :D
Features¶
- Tree-sitter based font-locking (4 levels) for
.mland.mlifiles - Tree-sitter based indentation with cycle-indent support
- Navigation (
beginning-of-defun,end-of-defun,forward-sexp, sentence movement withM-a/M-e) - Imenu with language-specific categories for
.mland.mli - Toggling between implementation and interface via
ff-find-other-file(C-c C-a) - OCaml toplevel (REPL) integration (
neocaml-repl) - Comment support:
fill-paragraph(M-q), comment continuation (M-j), andcomment-dwim(M-;) - Electric indentation on delimiter characters
- opam file editing (
neocaml-opam-mode) with font-lock, indentation, imenu, andopam lintintegration (flymake and flycheck) - dune file editing (
neocaml-dune-mode) for dune, dune-project, and dune-workspace files - dune build commands (
neocaml-dune-interaction-mode) -- build, test, clean, promote, fmt, exec (with watch mode via prefix arg) - OCamllex file editing (
neocaml-ocamllex-mode) with font-lock, indentation, imenu, and OCaml language injection (Emacs 30+) - Menhir file editing (
neocaml-menhir-mode) with font-lock, indentation, imenu, and OCaml language injection (Emacs 30+) - Cram test file editing (
neocaml-cram-mode) with font-lock for commands, output, modifiers, and prose - Easy installation of
ocamlandocaml-interfacetree-sitter grammars viaM-x neocaml-install-grammars - Compilation error regexp for
M-x compile(errors, warnings, alerts, backtraces) _builddirectory awareness (offers to switch to source when opening build artifacts, configurable vianeocaml-redirect-build-files)- Eglot integration (with ocaml-eglot support)
- Debugging via dape + ocamlearlybird (bytecode)
- Prettify-symbols for common OCaml operators
Comparison with Other Modes¶
| Feature | neocaml | caml-mode | tuareg |
|---|---|---|---|
| Required Emacs version | 29.1+ (30+ recommended) | 24+ | 26+ |
| Font-lock | Tree-sitter (4 levels) | Regex | Regex |
| Indentation | Tree-sitter + cycle-indent | Custom engine | SMIE |
| REPL integration | Yes | Yes | Yes |
| Navigation (defun, sexp) | Yes | Yes | Yes |
| Imenu | Yes (.ml and .mli) | Yes | Yes |
| .ml/.mli toggle | Yes | Yes | Yes |
| LSP (Eglot) integration | Yes (auto-configured) | Yes (manual) | Yes (manual) |
| Debugger | Yes (dape + ocamlearlybird) | Yes (ocamldebug) | Yes (ocamldebug) |
| Compilation commands | Error regexp + C-c C-c | Yes | Yes |
_build directory aware |
Yes | No | Yes |
| opam file support | Yes | No | Yes |
| dune file support | Yes | No | No |
| OCamllex support | Yes (with OCaml injection) | No | Yes |
| Menhir support | Yes (with OCaml injection) | No | Yes |
| Cram test support | Yes | No | No |
| Code templates / skeletons | No | Yes | Yes |
Keep in mind also that tuareg uses caml-mode internally for some functionality.
I think both modes will probably be folded into one down the road.
The impact of LSP on major modes¶
Historically, caml-mode and tuareg bundled features like type display,
completion, jump-to-definition, error checking, and refactoring support
-- all driven by Merlin. Today, ocamllsp provides all of these through
the standard LSP protocol, and Eglot (built into Emacs 29+) acts as the
client. There is no reason for a major mode to reimplement any of this.
For OCaml-specific LSP extensions that go beyond the standard protocol -- type enclosing, case analysis (destruct), hole navigation -- ocaml-eglot is the recommended companion package.
Why Tree-sitter?¶
Tree-sitter provides incremental, error-tolerant parsing that is significantly faster and more accurate than regex-based font-lock and SMIE-based indentation. It parses the full syntax tree, so fontification and indentation rules can reference actual language constructs rather than fragile regular expressions. This results in fewer edge-case bugs and simpler, more maintainable code.
Funding¶
While neocaml is free software and will always be, the project would benefit from some funding. Consider supporting its ongoing development if you find it useful.
You can support the development of neocaml via:
License¶
Copyright (c) 2025-2026 Bozhidar Batsov and contributors.
Distributed under the GNU General Public License, version 3 or later. See LICENSE for details.