Skip to content
Ivan Gotovchits edited this page May 21, 2015 · 8 revisions

Setting up Emacs

There is a new initiative in the community -- user-setup package, I personally didn't try it, but on a first glance it looks pretty nice and prominent. You can try it yourself on your risk, and actually I'm encouraging everyone to do this, but here I will share my setup, as it is what I've tested personally. But, maybe later we will rewrite this page to user-setup.

Dependencies

Our setup will depend on three packages:

  • Tuareg - major mode for editing OCaml source code;
  • Merlin - Tuareg minor mode that adds incremental compilation, intellisense-like completion, and other neat stuff;
  • ocp-indent - external indentation program that knows OCaml very well in comparison with the default tuaregs indentation engine that is just a set of regular expressions.

To install them from OPAM use:

opam install tuareg merlin ocp-indent

You will also need auto-complete mode for EMacs, available in elpa and melpa. To enable this (and also marmalade) you need the following at the start of your .emacs:

(setq package-archives '(("gnu" . "http://elpa.gnu.org/packages/")
                         ("marmalade" . "http://marmalade-repo.org/packages/")
                         ("melpa" . "http://melpa.milkbox.net/packages/")))
(package-initialize)

After this issue M-x package-list-packages and find out auto-complete package with the latest version, and install it.

Main configuration file

After everything is ready, you can store the following in ocaml.el, put it into your emacs search path, and load in .emacs with (require 'ocaml) instruction. (Of course, you can just copy-paste this directly into your .emacs, but I prefer to keep it clean).

(defun opam-path (path) 
  (let ((opam-share-dir 
         (shell-command-to-string "echo -n `opam config var share`")))
    (concat opam-share-dir "/" path)))

(add-to-list 'load-path (opam-path "emacs/site-lisp"))
(add-to-list 'load-path (opam-path "tuareg"))

(load "tuareg-site-file")
(require 'ocp-indent)
(require 'merlin)

;; uncomment the following for fancy greek letters
; (setq tuareg-font-lock-symbols t)
(setq merlin-use-auto-complete-mode 'easy)
(setq merlin-locate-preference 'mli)

(add-hook 'tuareg-mode-hook
          (lambda () 
            (merlin-mode)
            (local-set-key (kbd "C-c c") 'recompile)
            (local-set-key (kbd "C-c C-c") 'recompile)
            ; workaround for https://github.com/ocaml/tuareg/issues/45
            (tuareg-make-indentation-regexps)
            (auto-fill-mode)))

(defun opam-env ()
  (interactive nil)
  (dolist (var
           (car (read-from-string
                 (shell-command-to-string "opam config env --sexp"))))
    (setenv (car var) (cadr var))))

(provide 'ocaml)

Configuring Merlin

Merlin should work out of box, but it only knows vanilla OCaml by default. So, we need to teach him to use BAP and Core_kernel. Merlin is pretty clever, so it won't take to much time, you just need to create .merlin file in the project root, and describe what libraries are you using and how you structured your project. Something like this should work:

PKG core_kernel
PKG bap
PKG ocamlgraph

B _build
FLG -short-paths
FLG -w -4-33-40-41-42-43-34-44

Sometimes Merlin gets very confused, especially when after you've made opam update. In that case it can be healed by killing him and starting from scratch with M-x merlin-restart-process command.