Function: neocaml--setup-mode
neocaml--setup-mode is a natively compiled function defined in
neocaml.el.
Signature
(neocaml--setup-mode LANGUAGE)
Documentation
Set up tree-sitter font-lock, indentation, and navigation for LANGUAGE.
Called from neocaml-mode and neocaml-interface-mode to configure
the language-specific parts of the mode.
Source Code
;; Defined in /nix/store/ahssdx4rwzyxhyhavpn0bkznk13xrggi-emacs-packages-deps/share/emacs/site-lisp/elpa/neocaml-20260907.2015/neocaml.el
(defun neocaml--setup-mode (language)
"Set up tree-sitter font-lock, indentation, and navigation for LANGUAGE.
Called from `neocaml-mode' and `neocaml-interface-mode' to configure
the language-specific parts of the mode."
;; Offer to install missing grammars
(when-let* ((missing (seq-filter (lambda (r) (not (treesit-language-available-p (car r))))
neocaml-grammar-recipes)))
(when (y-or-n-p "OCaml tree-sitter grammars are not installed. Install them now?")
(neocaml-install-grammars)))
;; Warn if installed grammars are outdated
(neocaml--check-grammar-compatibility)
(when (treesit-ready-p language)
;; Emacs 31+ uses treesit-primary-parser to identify the main parser
;; when multiple parsers are active.
(let ((parser (treesit-parser-create language)))
(when (boundp 'treesit-primary-parser)
(setq-local treesit-primary-parser parser)))
(when neocaml--debug
(setq-local treesit--indent-verbose t)
(when (eq neocaml--debug 'font-lock)
(setq-local treesit--font-lock-verbose t))
;; show the node at point in the minibuffer
(treesit-inspect-mode))
;; font-lock settings
(setq-local treesit-font-lock-settings
(neocaml-mode--font-lock-settings language))
;; indentation
(setq-local treesit-simple-indent-rules (neocaml--indent-rules language))
;; Navigation
(when (boundp 'treesit-thing-settings)
(setq-local treesit-thing-settings
(neocaml--thing-settings language)))
(treesit-major-mode-setup)
;; Emacs 31's treesit-forward-comment has an off-by-one bug that
;; breaks uncomment-region on multi-line regions. Override with
;; the corrected version.
(when (and (>= emacs-major-version 31)
(boundp 'forward-comment-function))
(setq-local forward-comment-function #'neocaml--forward-comment))
;; treesit-major-mode-setup picks a `forward-sexp-function' for us, but
;; neither choice is right for OCaml:
;;
;; - Emacs 30 uses `treesit-forward-sexp', which doesn't fall back to
;; scan-sexps for delimiter characters, breaking `delete-pair'.
;; - Emacs 31 sees our `list' thing and uses `treesit-forward-sexp-list',
;; which moves across lists but delegates *atoms* to
;; `forward-sexp-default-function', ignoring the `sexp' thing entirely.
;; Keyword-led forms are then treated as bare words, so C-M-f stops
;; after `fun', `function', `if', `match' or `external' instead of
;; moving over the whole construct.
;;
;; Use the hybrid on every version: it walks sexps with tree-sitter and
;; delegates to scan-sexps only on delimiters, which keeps `delete-pair'
;; working without giving up sexp navigation.
(setq-local forward-sexp-function #'neocaml--forward-sexp-hybrid)
;; Workaround for treesit-transpose-sexps being broken on Emacs 30
;; (bug#60655). Emacs 31 rewrites the function to work correctly.
(when (and (fboundp 'transpose-sexps-default-function)
(< emacs-major-version 31))
(setq-local transpose-sexps-function
#'transpose-sexps-default-function))))