#+TITLE: Ocaml layer

#+TAGS: general|layer|multi-paradigm|programming

[[file:img/ocaml.png]]

* Table of Contents                     :TOC_5_gh:noexport:
- [[#description][Description]]
  - [[#features][Features:]]
- [[#install][Install]]
  - [[#layer][Layer]]
  - [[#using-merlin-for-error-reporting][Using merlin for error reporting]]
  - [[#opam-packages][OPAM packages]]
  - [[#enabling-formatting-on-save][Enabling formatting on save]]
- [[#key-bindings][Key bindings]]
  - [[#repl-utop][REPL (utop)]]
  - [[#dune][Dune]]
- [[#layer-improvements-list][layer improvements list]]

* Description
This is a very basic layer for editing ocaml files.

** Features:
- Syntax highlighting (major-mode) via [[https://github.com/ocaml/tuareg][tuareg-mode]]
- Error reporting, completion and type display via [[https://github.com/ocaml/merlin][merlin]]
- auto-completion with company mode via [[https://github.com/ocaml/merlin][merlin]]
- syntax-checking via [[https://github.com/flycheck/flycheck-ocaml][flycheck-ocaml]] (or alternatively [[https://github.com/ocaml/merlin][merlin]])
- =dune= file syntax highlighting and template insertion via [[https://github.com/ocaml/dune/][dune-mode]]
- Automatic formatting via [[https://github.com/ocaml-ppx/ocamlformat][ocamlformat]]

* Install
** Layer
To use this configuration layer, add it to your =~/.spacemacs=. You will need to
add =ocaml= to the existing =dotspacemacs-configuration-layers= list in this
file.

** Using merlin for error reporting
By default [[https://github.com/flycheck/flycheck-ocaml][flycheck-ocaml]] is used for error reporting when the
=syntax-checking= layer is also enabled as this is common throughout spacemacs.
You can disable this and switch back to [[https://github.com/ocaml/merlin][merlin]]'s default error reporting method
by adding [[https://github.com/flycheck/flycheck-ocaml][flycheck-ocaml]] to your excluded packages list in =.spacemacs=:

#+BEGIN_SRC emacs-lisp
  dotspacemacs-excluded-packages '(... flycheck-ocaml ... )
#+END_SRC

** OPAM packages
This layer requires some [[http://opam.ocaml.org][opam]] packages:
- =merlin= for auto-completion
- =utop=
- =ocp-indent=
- =ocamlformat= for auto-formatting

To install them, use the following command:

#+BEGIN_SRC sh
  opam install merlin utop ocp-indent ocamlformat
#+END_SRC

Make sure opam is initialized and configured.

#+BEGIN_SRC sh
  opam init
  opam config setup -a
#+END_SRC

** Enabling formatting on save
To enable automatic formatting on save with [[https://github.com/ocaml-ppx/ocamlformat][ocamlformat]], set the layer
variable =ocaml-format-on-save=, e.g.,

#+BEGIN_SRC emacs-lisp
  (ocaml :variables ocaml-format-on-save t)
#+END_SRC

* Key bindings

| Key binding | Description                                              |
|-------------+----------------------------------------------------------|
| ~SPC m =~   | Indent buffer.                                           |
| ~SPC m c c~ | Compile                                                  |
| ~SPC m c p~ | Check .merlin for errors                                 |
| ~SPC m c r~ | Refresh changed .cmis in merlin                          |
| ~SPC m e C~ | Check for errors in current buffer                       |
| ~SPC m e n~ | Jump to next error                                       |
| ~SPC m e N~ | Jump back to previous error                              |
| ~SPC m g a~ | Switch ML <-> MLI                                        |
| ~SPC m g b~ | Go back to the last position where the user did a locate |
| ~SPC m g g~ | Locate the identifier under point (same window)          |
| ~SPC m g G~ | Locate the identifier under point (different window)     |
| ~SPC m g i~ | Prompt for module name and switch to ML file             |
| ~SPC m g I~ | Prompt for module name and switch to MLI file            |
| ~SPC m g l~ | Prompt for identifier and locate                         |
| ~SPC m g o~ | List occurrences for identifier under point              |
| ~SPC m h h~ | Document the identifier under point                      |
| ~SPC m h t~ | Highlight identifier under cursor and print its type     |
| ~SPC m h T~ | Prompt for expression and show its type                  |
| ~SPC m r d~ | Case analyze the current enclosing                       |
| ~SPC m t p~ | Dune run tests and promote.                              |
| ~SPC m t P~ | Dune promote.                                            |

** REPL (utop)

| Key binding | Description                                                      |
|-------------+------------------------------------------------------------------|
| ~C-j~       | (in REPL) next item in history                                   |
| ~C-k~       | (in REPL) previous item in history                               |
| ~SPC m s b~ | Send buffer to the REPL                                          |
| ~SPC m s B~ | Send buffer to the REPL and switch to the REPL in =insert state= |
| ~SPC m s i~ | Start a REPL                                                     |
| ~SPC m s p~ | Send phrase to the REPL                                          |
| ~SPC m s P~ | Send phrase to the REPL and switch to the REPL in =insert state= |
| ~SPC m s r~ | Send region to the REPL                                          |
| ~SPC m s R~ | Send region to the REPL and switch to the REPL in =insert state= |

** Dune

| Key binding | Description                    |
|-------------+--------------------------------|
| ~SPC m c c~ | Compile.                       |
| ~SPC m i a~ | Insert ~alias~ stanza.         |
| ~SPC m i c~ | Insert ~copyfiles~ stanza.     |
| ~SPC m i d~ | Insert ignored subdirs stanza. |
| ~SPC m i e~ | Insert ~executable~ stanza.    |
| ~SPC m i i~ | Insert ~install~ stanza.       |
| ~SPC m i l~ | Insert ~library~ stanza.       |
| ~SPC m i m~ | Insert ~menhir~ stanza.        |
| ~SPC m i p~ | Insert ~ocamllex~ stanza.      |
| ~SPC m i r~ | Insert ~rule~ stanza.          |
| ~SPC m i t~ | Insert ~tests~ stanza.         |
| ~SPC m i v~ | Insert ~env~ stanza.           |
| ~SPC m i x~ | Insert ~executables~ stanza.   |
| ~SPC m i y~ | Insert ~ocamlyacc~ stanza.     |
| ~SPC m t p~ | Dune run tests and promote.    |
| ~SPC m t P~ | Dune promote.                  |

* TODO layer improvements list
1. Add more proper spacemacs key bindings for basic merlin tasks
2. Add proper key bindings for ocamldebug
3. Add more key bindings for tuareg-mode
