[erlang-questions] Emacs 'erlang-mode-hook

Daniel Pezely dpezely@REDACTED
Mon Jul 14 20:19:23 CEST 2014


I might be doing this the hard-way, but it works well enough to share and ask for feedback:
having Emacs erlang-shell play nice with multiple components built by rebar (invoked from Makefiles).

First, the elisp code followed by more explanation.

  ;; Add paths to ../../*/deps/ebin for running & compiling:
  (add-hook 'erlang-mode-hook
      (lambda ()
        (setq inferior-erlang-machine-options
          (append (remove nil
                  (mapcan (lambda (app-path)
                        (let ((ebin (concat app-path "/ebin")))
                          (when (file-readable-p ebin)
                        (list "-pa" ebin))))
                      (directory-files "../.." t "[^.]$")))
              (remove nil
                  (mapcan (lambda (dep)
                        (let ((dep-path (concat dep "/deps")))
                          (when (file-readable-p dep-path)
                        (mapcan (lambda (dir)
                              (list "-pa" (concat dir "/ebin")))
                            (directory-files dep-path t "[^.]$")))))
                      (directory-files "../.." t "[^.]$"))))

          erlang-compile-extra-opts
          (append (remove nil
                  (mapcan (lambda (app-path)
                        (let ((ebin (concat app-path "/ebin")))
                          (when (file-readable-p ebin)
                        (list "-pa" ebin))))
                      (directory-files "../.." t "[^.]$")))
              (remove nil
                  (mapcan (lambda (dep)
                        (let ((dep-path (concat dep "/deps")))
                          (when (file-readable-p dep-path)
                        (mapcar (lambda (dir)
                              (cons 'i (concat dir "/ebin")))
                            (directory-files dep-path t "[^.]$")))))
                      (directory-files "../.." t "[^.]$")))))))

We have a source tree on disk that roughly looks like the following with names changed to protect the innocent, etc.

ls
  app1/ebin  app1/deps  app1/src  app2/ebin  app2/deps  app2/src

Our top-level application relies upon Cowboy & friends, and the division between app1 versus app2 is largely to isolate HTTP-related logic for a future alternate Erlang-specific entry point.

This division introduces problems for *erlang-shell* within Emacs because default values for erlang-mode.el are such that it can't find dependencies across ../app* boundaries without telling the inferior-shell about paths.

The  'erlang-mode-hook above relies upon rebar related directory tree and should work for an arbitrary number of sibling apps.  (Of course, it will require restarting *erlang-shell* if any new dependencies are added.)

The beauty of this is that you can compile everything via `make` and then do incremental file compilation from within Emacs and run within *erlang-shell*.  The generated .beam files from an Emacs-initiated compilation also appear within ../ebin subdirectories rather than the src directory.

There may be subtle interaction issues depending upon which app's source is compiled and possibly depositing the .beam file into the wrong ../ebin, but an occasional 'make clean' is useful during development anyway, I suppose.  From my early C days, I tend to `make clean` at least once daily.


Why I believe that there may be a cleaner or more concise way is that this is likely to be a common Erlang idiom if not also shared by other languages for which there are Emacs functions like inferior-erlang-compile.  Anyone have suggestions about this?

Thanks,
-Daniel

--
dpezely@REDACTED

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20140714/083a2fc0/attachment.htm>


More information about the erlang-questions mailing list