Archives

 

Erlang compilation with Emacs - Code

There are two implications which need to be considered before adapting this approach:

An application must contain specific code which can be called by emacs and that code must be able to determine the location of the Emakefile.

The approach can't be used for initial compilation, because emacs calls a function from an application module, which must be compiled already.

And of course you must have distel installed. Below a code snippet showing the Emacs Lisp code, which goes into emacs.el (or Preferences.el in case of aquamacs):

(defun my-erlang-compile ()
(interactive)
(save-some-buffers (not compilation-ask-about-save) nil)
(save-excursion
(let ((thisdir default-directory))
(setq src-file-name buffer-file-name)
(with-current-buffer (get-buffer-create "*erl-output*")
(setq default-directory thisdir)
(erase-buffer)
(compilation-mode)
(toggle-read-only nil)
(setq compilation-current-error nil)
(display-buffer (current-buffer))
(erl-spawn
(erl-send-rpc (erl-target-node)
'distel
'eval_expression
(list (format "myapp_make:all(%S)." src-file-name)))
(erl-receive ()
((['rex ['ok string]]
(insert string))
(['rex ['error reason]]
(insert reason))
(other
(message "Unexpected: %S" other)))))))))

(add-hook 'erlang-mode-hook 'my-erlang-mode-hook)
(defun my-erlang-mode-hook ()
;; when starting an Erlang shell in Emacs, default in the node name
(setq inferior-erlang-machine-options '("-sname" "emacs"))

(define-key erlang-mode-map [f13]
(lambda () (interactive)
(progn
(my-erlang-compile))))
)

;; just to illustrate how to use custom erlang compilation
;; from within other modes
(add-hook 'foo-helper-mode-hook
(lambda ()            
(define-key foo-helper-mode-map [f13]
(lambda () (interactive)
(progn
(my-erlang-compile))))))

With the elisp snippet from above, the corresponding Erlang application must contain a module myapp_make which implements the function all/1 :

all(Path) ->
case filename:extension(Path) of
".erl" ->
{ok, OldDir} = file:get_cwd(),
ok = file:set_cwd(my_find_emakefile_dir()),
make:all([load]),
ok = file:set_cwd(OldDir);
Ext ->
maybe_my_custom_stuff
end.