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.
Example:
sum(L) -> sum(L, 0).
sum([H|T], Sum) -> sum(T, Sum + H);
sum([], Sum) -> Sum.
becomes:
sum(L) -> sum(L, 0).
sum([H|T], Sum) -> sum(T, Sum + H);
sum([], Sum) -> Sum."
(interactive "r")
(save-excursion
(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)
(point-marker))))
;; 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 ? )))))
arrow-positions))))
More information about the erlang-questions
mailing list