When I released neocaml 0.1last month, I thought I was more or less done with the (main) features for theforeseeable future. The original scope was deliberately small — a couple ofTree-sitter-powered OCaml major modes (for .ml and .mli), a REPLintegration, and not much else. I was quite happy with how things turned out andfigured the next steps would be mostly polish and bug fixes.Versions 0.2-0.5 brought polish and bug fixes, but fundamentally the featureset stayed the same. I was even more convinced a grand 1.0 release was justaround the corner.I was wrong.Of course, OCaml files don’t exist in isolation. They live alongsideOpam files that describe packages andDune files that configure builds. And as I waspoking around the Tree-sitter ecosystem, I discovered that there were alreadygrammars for bothOpam andDune files. Given howsimple both formats are (Opam is mostly key-value pairs, Dune iss-expressions), adding support for them turned out to be fairlystraightforward.So here we are with neocaml 0.6, which is quite a bit bigger than I expectedoriginally.Note: One thing worth mentioning — all the new modes are completelyisolated from the core OCaml modes. They’re separate files with no harddependency on neocaml-mode, loaded only when you open the relevant filetypes. I didn’t want to force them upon anyone — for me it’s convenient to getOpam and Dune support out-of-the-box (given how ubiquitous they are in the OCamlecosystem), but I totally get it if someone doesn’t care about this.Let me walk you through what’s new.neocaml-opam-modeThe new neocaml-opam-mode activates automatically for .opam and opamfiles. It provides: Tree-sitter-based font-lock (field names, strings, operators, versionconstraints, filter expressions, etc.) Indentation (lists, sections, option braces) Imenu for navigating variables and sections A flymake backend that runs opam lint on the current buffer, giving youinline diagnostics for missing fields, deprecated constructs, and syntaxerrorsThe flymake backend registers automatically when opam is found in your PATH,but you need to enable flymake-mode yourself:1(add-hook 'neocaml-opam-mode-hook #'flymake-mode)Flycheck users get opam lint supportout of the box via Flycheck’s built-in opam checker — no extra configurationneeded.This bridges some of the gap with Tuareg,which also bundles an Opam major mode (tuareg-opam-mode). The Tree-sitter-basedapproach gives us more accurate highlighting, and the flymake integration is anice bonus on top.neocaml-dune-modeneocaml-dune-mode handles dune, dune-project, and dune-workspace files— all three use the same s-expression syntax and share a single Tree-sittergrammar. You get: Font-lock for stanza names, field names, action keywords, strings, modulenames, library names, operators, and brackets Indentation with 1-space offset Imenu for stanza navigation Defun navigation and which-func supportThis removes the need to install the separatedune package (the standalone dune-mode maintainedby the Dune developers) from MELPA. If you prefer to keep using it, that’s finetoo — neocaml’s README hasinstructionsfor overriding the auto-mode-alist entries.neocaml-dune-interaction-modeBeyond editing Dune files, I wanted a simple way to run Dune commands from anyneocaml buffer. neocaml-dune-interaction-mode is a minor mode that provideskeybindings (under C-c C-d) and a “Dune” menu for common operations: Keybinding Command C-c C-d b Build C-c C-d t Test C-c C-d c Clean C-c C-d p Promote C-c C-d f Format C-c C-d u Launch utop with project libraries C-c C-d r Run an executable C-c C-d d Run any Dune command C-c C-d . Find the nearest dune file All commands run via Emacs’s compile, so you get error navigation, clickablesource locations, and the full compilation-mode interface for free. With aprefix argument (C-u), build, test, and fmt run in watch mode(--watch), automatically rebuilding when files change.The utop command is special — it launches through neocaml-repl, so you getthe full REPL integration (send region, send definition, etc.) with yourproject’s libraries preloaded.This mode is completely independent from neocaml-dune-mode — it doesn’t carewhich major mode you’re using. You can enable it in OCaml buffers like this:1(add-hook 'neocaml-base-mode-hook #'neocaml-dune-interaction-mode)Rough EdgesBoth the Opam and Dune Tree-sitter grammars are relatively young and will needsome more work for optimal results. I’ve been filing issues and contributingpatches upstream to improve them — for instance, the Dune grammar currentlyflattens field-valuepairs in a waythat makes indentation less precise than it could be, and neither grammarsupports variableinterpolation(%{...}) yet. These are very solvable problems and I expect the grammars toimprove over time.What’s Next?At this point I think I’m (finally!) out of ideas for new functionality. Thistime I mean it! Neocaml now covers pretty much everything I ever wanted,especially when paired with the awesomeocaml-eglot.Down the road there might be support for OCamllex (.mll) or Menhir (.mly)files, but only if adding them doesn’t bring significant complexity — both aremixed languages with embedded OCaml code, which makes them fundamentally harderto support well than the simple Opam and Dune formats.I hope OCaml programmers will find the new functionality useful. If you’re using neocaml,I’d love to hear how it’s working for you — bug reports, feature requests, andgeneral feedback are all welcome onGitHub. You can find the full list ofchanges in thechangelog.As usual — update from MELPA, kick the tires,and let me know what you think.That’s all I have for you today! Keep hacking!