diff --git a/modules/lang/ocaml/README.org b/modules/lang/ocaml/README.org index 53fa6db12..9154077b8 100644 --- a/modules/lang/ocaml/README.org +++ b/modules/lang/ocaml/README.org @@ -2,7 +2,8 @@ This module adds [[https://ocaml.org/][OCaml]] support, powered by [[https://github.com/ocaml/tuareg][tuareg-mode]]. -+ Code completion, look up documentation, and code navigation ([[https://github.com/ocaml/merlin/wiki/emacs-from-scratch][merlin]]) ++ Code completion, documentation look-up, code navigation and refactoring ([[https://github.com/ocaml/merlin/wiki/emacs-from-scratch][merlin]]) ++ Type, documentation and function argument display on idle ([[https://github.com/Khady/merlin-eldoc][merlin-eldoc]]) + REPL ([[https://github.com/ocaml-community/utop][utop]]) + Syntax-checking (~merlin~ with [[https://github.com/flycheck/flycheck-ocaml][flycheck-ocaml]]) + Auto-indentation ([[https://github.com/OCamlPro/ocp-indent][ocp-indent]]) @@ -52,25 +53,32 @@ opam install merlin utop ocp-indent dune ocamlformat + when =:feature syntax-checker= is enabled then =flycheck-ocaml= is activated to do on-the-fly syntax/type checking via =merlin=, otherwise this is only done when the file is saved. -+ spell checking is activated in comments if =:feature spellcheck= is actived -+ a REPL is provided if =utop= is installed and =:feature eval= is actived ++ spell checking is activated in comments if =:feature spellcheck= is active ++ a REPL is provided if =utop= is installed and =:feature eval= is active + if =:editor format= is enabled, the =ocamlformat= executable is available and there is an =.ocamlformat= file present then =format-all-buffer= is bound to =ocamlformat=, otherwise to =ocp-indent= ++ if =:editor multiple-cursors= is enabled then identifiers can be refactored + with =v R= and multiple cursors (this correctly matches identifier occurrences + according to scope, it is not purely a textual match) ++ if =:emacs imenu= is enabled then top level symbols (modules, type, functions, etc.) can + be looked up using =SPC / i= Run =make install= to install all packages, and =make doctor= to diagnose missing tools. * Appendix ** Commands - | command | key / ex command | description | - |------------------------------+------------------+------------------------------------| - | =merlin-type-enclosing= | =SPC m t= | display type under point | - | =tuareg-find-alternate-file= | =SPC m a= | switch between =.ml= and =.mli= | - | =merlin-locate= | =gd= | lookup definition | - | =merlin-occurences= | =SPC c D= | lookup references | - | =merlin-document= | =K= | lookup documentation | - | =utop= | =SPC o r= | open =utop= as REPL | - | =utop-eval-region= | =SPC c e= | evaluate selected region in =utop= | + | command | key / ex command | description | + |------------------------------+------------------+-----------------------------------------------------------| + | =merlin-type-enclosing= | =SPC m t= | display type under point | + | =tuareg-find-alternate-file= | =SPC m a= | switch between =.ml= and =.mli= | + | =merlin-locate= | =gd= | lookup definition | + | =merlin-occurences= | =SPC c D= | lookup references | + | =merlin-document= | =K= | lookup documentation | + | =merlin-imenu= | =SPC / i= | symbol lookup in file | + | =merlin-iedit-occurrences= | =v R= | visual refactor identifier under point (multiple cursors) | + | =utop= | =SPC o r= | open =utop= as REPL | + | =utop-eval-region= | =SPC c e= | evaluate selected region in =utop= | ** Hacks + =set-pretty-symbols!= is called with the full tuareg prettify symbol list, this diff --git a/modules/lang/ocaml/config.el b/modules/lang/ocaml/config.el index 302c083a0..f44e2f1b2 100644 --- a/modules/lang/ocaml/config.el +++ b/modules/lang/ocaml/config.el @@ -21,10 +21,8 @@ :defer t :init (defun +ocaml|init-merlin () - "Activate `merlin-mode' if the ocamlmerlin executable exists and the -current project possesses a .merlin file." - (when (and (projectile-locate-dominating-file default-directory ".merlin") - (executable-find "ocamlmerlin")) + "Activate `merlin-mode' if the ocamlmerlin executable exists." + (when (executable-find "ocamlmerlin") (merlin-mode))) (add-hook 'tuareg-mode-hook #'+ocaml|init-merlin) @@ -44,12 +42,32 @@ current project possesses a .merlin file." (def-package! flycheck-ocaml :when (featurep! :feature syntax-checker) - :after merlin + :init + (defun +ocaml|init-flycheck () + "Activate `flycheck-ocaml` if the current project possesses a .merlin file." + (when (projectile-locate-dominating-file default-directory ".merlin") + ;; Disable Merlin's own error checking + (setq merlin-error-after-save nil) + ;; Enable Flycheck checker + (flycheck-ocaml-setup))) + (add-hook 'merlin-mode-hook #'+ocaml|init-flycheck)) + + + (def-package! merlin-eldoc + :hook (merlin-mode . merlin-eldoc-setup)) + + + (def-package! merlin-iedit + :when (featurep! :editor multiple-cursors) + :hook (merlin-mode . merlin-use-merlin-imenu) :config - ;; Disable Merlin's own error checking - (setq merlin-error-after-save nil) - ;; Enable Flycheck checker - (flycheck-ocaml-setup)) + (map! :map tuareg-mode-map + :v "R" #'merlin-iedit-occurrences)) + + + (def-package! merlin-imenu + :when (featurep! :emacs imenu) + :hook (merlin-mode . merlin-use-merlin-imenu)) (def-package! utop diff --git a/modules/lang/ocaml/packages.el b/modules/lang/ocaml/packages.el index 27af6197d..71128923f 100644 --- a/modules/lang/ocaml/packages.el +++ b/modules/lang/ocaml/packages.el @@ -3,6 +3,7 @@ (package! tuareg) (package! merlin) +(package! merlin-eldoc) (package! ocp-indent) (when (featurep! :feature syntax-checker)