Changelog
July 10, 2026 · View on GitHub
main (unreleased)
0.10.0 (2026-07-10)
New features
- Add
neocaml-utop, an alternative toplevel backend that drives utop through its native editor protocol (utop -emacs). It runs in a comint-based transcript with input history and completion-at-point backed by utop's own engine, separates output/results/errors/warnings, and underlines the exact sub-expression a parse or type error points at in the source buffer (with the error message as the overlay's tooltip; the underline clears when you edit the code). Source evaluations cover every;;-separated phrase in the region, and the result is shown both in the minibuffer (SLIME/CIDER style; toggle withneocaml-utop-echo-eval-result) and inline in the source buffer as a=> ...overlay (toggle withneocaml-utop-inline-eval-result). In the transcript,RETsubmits a complete phrase and otherwise inserts a newline, so multi-line phrases can be entered naturally, and typed input is fontified with tree-sitter (toggle withneocaml-utop-fontify-input). Enableneocaml-utop-minor-modein OCaml buffers to use it; the keybindings mirrorneocaml-repl-minor-mode.
0.9.0 (2026-06-24)
New features
- #63: Flesh out the mode and REPL menus:
- Add an "Edit" submenu (comment/uncomment region, fill comment paragraph, indent region).
- Add an "OCaml REPL" menu to the REPL buffer (
neocaml-repl-mode) for switching back to the source, interrupting, and clearing the buffer. - Add a "Toggle" submenu (prettify symbols, subword mode, outline minor mode) and a "Start/Switch to REPL" entry to the mode menu.
- Add help strings (tooltips) and "Customize" entries to the menus, and disable REPL commands that need an active region or a running process when those aren't available.
- Add
neocaml-set-font-lock-leveland a "Font-Lock Level" submenu for switching the tree-sitter fontification level (1-4) in the current buffer. - #65: Add
neocaml-format-buffer(bound toC-c C-f) to format OCaml source withocamlformat, plus an opt-inneocaml-format-on-save. - #65: Make URLs and bug references in comments clickable across the OCaml source and tool modes via
goto-address-prog-modeandbug-reference-prog-mode. Setbug-reference-url-format(e.g. via.dir-locals.el) to resolve issue references. - #65: Add
neocaml-repl-restartto kill and restart the OCaml toplevel, with a matching entry in the REPL menu. - #68: Add
neocaml-repl-send-phrase-and-step(bound toC-c C-n), which sends the phrase at point to the REPL and advances to the next one, andneocaml-repl-requirefor loading a findlib package via#require. - #69: Give each project its own dedicated REPL. The REPL buffer is now named per project (e.g.
*OCaml: myproject*, derived fromneocaml-repl-buffer-name), and the send commands route to the current buffer's project REPL, so multiple projects can run side by side. This also fixesneocaml-dune-utopso the send commands reach its toplevel. - #70: Add
neocaml-repl-flavorfor choosing which toplevel the REPL runs (ocaml,utop, ordune-utop); set it globally or per project via.dir-locals.el. The active flavor is shown in the REPL's mode line. - #71: Integrate with
project.el: a directory containing adune-projectfile is recognized as a project root (for non-VC projects),_build/and_opam/are ignored, andcompile-commanddefaults todune buildin dune projects. - #72: Add
completion-at-pointsupport toneocaml-dune-modeandneocaml-opam-mode. dune files complete stanza names, the field names valid for the enclosing stanza, and library names insidelibraries/ppsfields (both the project's own libraries and the installed findlib libraries); opam files complete field and section names and, insidedepends/depopts/conflicts, package names (viaopam list). The external candidate sources are gathered from the project root, so a project-local opam switch (_opam/) is detected and used automatically (viaopam exec --); they are cached per project and can be toggled withneocaml-dune-complete-librariesandneocaml-opam-complete-packages.
Bug fixes
- #66: Correctly handle character literals and quoted strings at the syntactic layer via a
syntax-propertize-function. Characters like'"','(', and')', and the contents of{|...|}/{id|...|id}quoted strings, no longer confuse sexp motion,electric-pair-mode,delete-pair, orsyntax-ppss.
Changes
- Switch the
ocamlandocaml-interfacegrammars to tree-sitter-ocaml v0.25.0, pinned to the upstreamv0.25.0-abi14tag (an ABI 14 regeneration of the same grammar, since v0.25.0 itself generates an ABI 15 parser most Emacs builds can't load yet). This brings in the OCaml 5.5 grammar support. - #60: Highlight function-typed
valspecifications in.mlifiles with the function face, matching how functionletbindings are highlighted in implementations. - Handle OCaml 5.5 external type declarations (
type t = external "caml_foo") in sexp navigation, soC-M-f/C-M-bstep over the whole declaration body instead of just theexternalkeyword.
0.8.1 (2026-05-13)
Bug fixes
- #57: Stop passing
-emacsto utop inneocaml-dune-utop(and drop it from the recommended config in the docs). That flag activates utop's structured protocol intended for the oldutop.el, whichneocaml-repldoesn't implement, so the protocol output was leaking into the REPL buffer. - #58:
neocaml-backward-up-listnow jumps out of optional parameters with defaults (e.g.,?(foo = 123)) instead of erroring with "At top level". - #53: Capture stderr separately when running
dune format-dune-file, so theEntering directory/Leaving directorymarkers newer dune versions emit on stderr no longer wrap the formatted buffer.
Changes
- #42: Lower the tree-sitter ABI requirement from 15 to 14 across
neocaml-opam-mode,neocaml-dune-mode, andneocaml-ocamllex-mode, so they work on Emacs built against tree-sitter 0.24 (e.g., the homebrew Emacs 30 on macOS). Switch the menhir recipe to tmcgilchrist/tree-sitter-menhir and pin the ocamllex recipe back to v0.24.0, both of which target ABI 14.
0.8.0 (2026-04-10)
New features
- #47: Add
neocaml-backward-up-list, bound toC-M-u, for jumping out of the enclosing OCaml block (struct/sig/object, records, arrays, etc.). The built-inbackward-up-listdoesn't understand keyword-delimited constructs on Emacs 29/30. - #41:
neocaml-dune-modenow activates fordune-workspacefile variants likedune-workspace.cianddune-workspace.5.3. - Add
neocaml-cram-modefor editing cram test (.t) files with tree-sitter font-lock, indentation, and imenu. - Add
neocaml-dune-format-bufferfor formatting dune files viadune format-dune-file. - Register neocaml modes with
dapeforocamlearlybirddebugging support. - Register file associations for
.ocamlinit,.ocamlformat, and.ocp-indentfiles. - Extend
neocaml-opam-modeto activate for.opam.templatefiles. - Include per-grammar ABI version in
neocaml-bug-report-infooutput.
Changes
- The
_build/directory redirect is now optional (controlled byneocaml-redirect-build-files).
0.7.1 (2026-03-31)
Bug fixes
- Fix malformed
eglot-server-programsentry that preventedeglot-ensurefrom startingocamllspfor neocaml modes.
0.7.0 (2026-03-31)
New features
- #36: Add
neocaml-ocamllex-modefor editing OCamllex (.mll) files with tree-sitter font-lock, indentation, imenu, and defun navigation. Embedded OCaml code inside{ }blocks gets full syntax highlighting via language injection when the OCaml grammar is installed. Based on the tree-sitter-ocamllex grammar. - #36: Add
neocaml-menhir-modefor editing Menhir (.mly) files with tree-sitter font-lock, indentation, imenu, and defun navigation. Embedded OCaml code inside{ }and%{ %}blocks gets full syntax highlighting via language injection. Based on the tree-sitter-menhir grammar. - Register
neocaml-modeandneocaml-interface-modewitheglot-server-programssoeglot-ensureworks out of the box withocamllsp.
Bug fixes
- #37: Guard ABI 15 grammars (ocamllex, menhir) on Emacs 30+ and include ABI version in
neocaml-bug-report-info. - Language injection in ocamllex and menhir modes now requires Emacs 30+ (injection queries are not supported on Emacs 29).
0.6.0 (2026-03-25)
Bug fixes
- #34: Fix indentation of continuation lines inside multi-line comments. Lines now align with the body text after the opening delimiter.
New features
- Add
neocaml-dune-modefor editing dune, dune-project, and dune-workspace files with tree-sitter font-lock, indentation, imenu, and defun navigation. Based on the tree-sitter-dune grammar. - Add
neocaml-opam-modefor editing opam package files with tree-sitter font-lock, indentation, and imenu. Based on the tree-sitter-opam grammar. - Add
neocaml-dune-interaction-mode, a minor mode for running dune commands (build, test, clean, promote, fmt, utop, exec) from any neocaml buffer viacompile. Includes watch mode support via prefix argument and a Dune menu. - Add flymake backend for
opam lintinneocaml-opam-mode. Enabled by default when theopamexecutable is found. - Add tree-sitter font-locking for REPL input via
comint-fontify-input-mode. Code typed in the REPL now gets the same syntax highlighting as regular.mlbuffers. Controlled byneocaml-repl-fontify-input(defaultt).
0.5.0 (2026-03-16)
Bug fixes
- #26: Preserve list items and odoc tags as paragraph boundaries when filling comments.
- #27:
neocaml-install-grammarsnow accepts a prefix argument (C-u) to force reinstallation of grammars, even if they are already installed. - Avoid the superfluous spaces after the prompt of the REPL when sending code to
the REPL via the commands
neocaml-repl-send-*. - #28: Fix
delete-pairdeleting the wrong closing delimiter. Add alistthing totreesit-thing-settingsand a hybridforward-sexpthat falls back to syntax-table matching on delimiter characters.
New features
- Support
outline-minor-modefor folding top-level definitions (Emacs 30+). - Support
which-func-modefor displaying the current definition name in the mode line. - Add
neocaml-objinfo-modefor viewing OCaml compiled artifacts (.cmi,.cmo,.cmx,.cma,.cmxa,.cmxs,.cmt,.cmti) viaocamlobjinfo. Includes font-lock, imenu navigation, and revert support. - Set
treesit-primary-parserfor Emacs 31+ compatibility.
0.4.1 (2026-03-10)
Bug fixes
- #24: Fix grammar compatibility check always warning even with up-to-date grammars.
treesit-query-compiledoesn't validate field names, so the check now usestreesit-node-child-by-field-nameon an actual parse tree instead.
0.4.0 (2026-03-10)
Bug fixes
- #20: Work around broken
transpose-sexpson Emacs 30 (bug#60655). Falls back to default transpose behavior; Emacs 31 has a proper fix. - #22: Fix compilation regexp to handle arbitrary leading whitespace in OCaml error messages.
- #22: Fix off-by-one in compilation column positions. OCaml uses 0-indexed columns; the begin-column is now correctly converted to Emacs's 1-indexed columns.
Changes
- Bump required tree-sitter-ocaml grammar from v0.24.0 to v0.24.2. Users must reinstall their grammars via
M-x neocaml-install-grammars. The upstream release includes breaking changes to the parse tree structure (see tree-sitter-ocaml#126). - neocaml now warns at startup if the installed grammar is older than expected.
- Reorganize font-lock feature levels to align with Emacs conventions:
typemoved to level 2,numbermoved to level 3,escape-sequencesplit into its own feature at level 3, andpropertyandlabelsplit into their own features at level 4.
New features
- Add
neocaml-mark-sentencecommand to mark the current statement around point. - Add
neocaml-bug-report-infocommand for collecting debug information in bug reports. - Add "Navigate" submenu to the OCaml menu with structural navigation commands.
- Add mark and transpose commands to the OCaml menu.
- Highlight escape sequences (
\n,\t, etc.) in strings withfont-lock-escape-face. - Highlight conversion specifications (
%d,%s, etc.) in format strings withfont-lock-regexp-face. - Highlight
match+and similar binding operators as keywords in match expressions. - #23: Add
iarrayto the list of builtin types.
0.3.0 (2026-02-26)
Bug fixes
- Fix
M-q(fill-paragraph) not indenting continuation lines in comments. - Fix
M-;(comment-dwim) failing to remove*)when uncommenting a region.
New features
- Add
comment-indent-new-linesupport:M-jinside comments continues the comment with proper indentation. - Highlight binding operators (
let*,let+,and*,and+) as keywords. - Add
electric-indent-charsfor{}()soelectric-indent-modereindents after typing delimiters. - Add
fill-paragraphsupport for OCaml(* ... *)comments via tree-sitter. - Document
outline-minor-modeandtreesit-foldfor code folding in README.
0.2.0 (2026-02-17)
Bug fixes
- Fix
compile-goto-errorlanding one column before the actual error position. OCaml uses 0-indexed columns;compilation-first-columnis now set to 0 accordingly. - Fix
neocaml-repl-send-definitionsignaling an error when point is not inside a definition. - Fix
;;terminator detection: only check whether input ends with;;instead of searching anywhere in the string, avoiding false positives from;;inside strings or comments. - Fix
neocaml-repl-send-phraseto skip;;inside strings and comments when locating phrase boundaries.
New features
- Add
neocaml-repl-load-file(C-c C-l): load the current file into the REPL via the#usedirective. - Add REPL input history persistence across sessions via
neocaml-repl-history-fileandneocaml-repl-history-size. - Flash the sent region when evaluating code in the REPL (
send-region,send-definition,send-phrase,send-buffer).
Changes
- Introduce
neocaml-base-modeas the shared parent forneocaml-modeandneocaml-interface-mode. Users can hook intoneocaml-base-mode-hookto configure both modes at once. - Improve
utopsupport: strip ANSI escape sequences and recognize utop's prompt format so point is correctly placed after the prompt. - Make
C-c C-zreversible: from a source buffer it switches to the REPL, from the REPL it switches back. - Add
_builddirectory awareness: when opening a file under_build/, offer to switch to the source copy (supports dune and ocamlbuild layouts). - Split
neocaml-prettify-symbols-alistinto a column-width-safe base list andneocaml-prettify-symbols-extra-alist(fun->λ,->->→,not->¬). Control extra symbols with theneocaml-prettify-symbols-fulltoggle. - Register OCaml build artifact extensions (
.cmo,.cmx,.cmi, etc.) incompletion-ignored-extensionsto declutterfind-filecompletion. - Bind
C-c C-ctocompileinneocaml-mode(shadowed byneocaml-repl-send-definitionwhen the REPL minor mode is active). - Extend
neocaml-other-file-alistto support.mll,.mly, and.eliom/.eliomifile pairs forff-find-other-file. - Register OCaml compilation error regexp for
M-x compilesupport (errors, warnings, alerts, backtraces). - Add
treesit-thing-settingsfor sexp, sentence, text, and comment navigation (Emacs 30+). - Add sentence navigation (
M-a/M-e) for moving between top-level definitions. transpose-sexpsnow works with tree-sitter awareness (Emacs 30+).- Replace automatic grammar installation with the interactive command
M-x neocaml-install-grammars. - Remove
neocaml-ensure-grammarsdefcustom. - Remove
neocaml-use-prettify-symbolsandneocaml-repl-use-prettify-symbolsdefcustoms.prettify-symbols-alistis now always set; users enableprettify-symbols-modevia hooks.
0.1.0 (2026-02-13)
Initial release.
Features
- Tree-sitter based font-locking with 4 levels of highlighting for
.mland.mlifiles. - Tree-sitter based indentation with cycle-indent support.
- Imenu integration with language-specific categories for
.mland.mli. - Navigation support (
beginning-of-defun,end-of-defun,forward-sexp). - OCaml toplevel (REPL) integration via
neocaml-repl. - Automatic grammar installation via
treesit-install-language-grammar. - Switch between
.mland.mlifiles withff-find-other-file. - Prettify-symbols support for common OCaml operators.
- Eglot integration for LSP support (e.g.
ocamllsp).