Erlang mode in Emacs

Luke Gorrie luke@REDACTED
Sun Dec 15 22:39:39 CET 2002

Ingela Anderton <ingela@REDACTED> writes:

> Hello everyone!
> I have been doing some corrections to the erlang-mode. This updated
> version will not be officially released until the next Erlang/OTP
> release. But as it is so hard to test emacs-modes with automatic
> test-suits I have put it into the contribution area so that you may
> test it right away. This way I get it properly tested and you get the
> benefit of my fixes already today :)

Nice! Working well thus far.

I have a command for aligning the arrows in function heads that I've
been meaning to send in for years - maybe something we can add to the
mode and assign a key?

Here's the command w/ description:

(defun erlang-align-arrows (start end)
  "Align arrows (\"->\") in function clauses from START to END.
When called interactively, aligns arrows inside the region.


sum(L) -> sum(L, 0).
sum([H|T], Sum) -> sum(T, Sum + H);
sum([], Sum) -> Sum.


sum(L)          -> sum(L, 0).
sum([H|T], Sum) -> sum(T, Sum + H);
sum([], Sum)    -> Sum."
  (interactive "r")
    (let (;; regexp matching a function head (without newlines..)
	  (re (concat "^" erlang-atom-regexp ".*\\(\\)->"))
	  ;; part of regexp matching directly before the arrow
	  (arrow-match-pos (1+ erlang-atom-regexp-matches))
	  ;; accumulator for positions where arrows are found, ordered
	  ;; by buffer position (from greatest to smallest)
	  (arrow-positions '())
	  ;; accumulator for longest distance from start of line to arrow
	  (most-indent 0)
	  ;; marker to track the end of the region we're aligning
	  (end-marker (progn (goto-char end)
      ;; Pass 1: Find the arrow positions, adjust the whitespace
      ;; before each arrow to one space, and find the greatest
      ;; indentation level.
      (goto-char start)
      (while (re-search-forward re end-marker t)
	(goto-char (match-beginning arrow-match-pos))
	(just-one-space)		; adjust whitespace
	(setq arrow-positions (cons (point) arrow-positions))
	(setq most-indent (max most-indent
			       (- (point) (line-beginning-position)))))
      (set-marker end-marker nil)	; free the marker
      ;; Pass 2: Insert extra padding so that all arrow indentation is
      ;; equal. This is done last-to-first by buffer position, so that
      ;; inserting spaces before one arrow doesn't change the
      ;; positions of the next ones.
      (mapcar (lambda (arrow-pos)
		(goto-char arrow-pos)
		(let* ((indent (- arrow-pos (line-beginning-position)))
		       (pad    (- most-indent indent)))
		  (when (> pad 0)
		    (insert (make-string pad ? )))))

More information about the erlang-questions mailing list