views:

214

answers:

2

Let's say that I have an Erlang function, with spec.

-spec foo(integer(), string()) ->
      boolean().
foo(_Integer, _String) ->
      true.

My dream would be to generate the edoc from this information within Emacs automatically. The generated code should look like:

%%--------------------------------------------------------------------
%% @doc
%% Your description goes here
%% @spec foo(_Integer::integer(), _String::string()) ->
%%%      boolean()
%% @end
%%--------------------------------------------------------------------
-spec foo(integer(), string()) ->
      boolean().
foo(_Integer, _String) ->
      true.

Does a similar feature already exist?

+4  A: 

I don't know Erlang, but this might get you started:

EDIT: Closer, but will only work if args are on the same line :(

EDIT: Seems to work for args on separate lines now

(defun my-erlang-insert-edoc ()
  "Insert edoc."
  (interactive)
  (save-excursion
    (when (re-search-forward "^\\s *-spec\\s +\\([a-zA-Z0-9_]+\\)\\s *(\\(\\(.\\|\n\\)*?\\))\\s *->[ \t\n]*\\(.+?\\)\\." nil t)
      (let* ((beg (match-beginning 0))
             (funcname (match-string-no-properties 1))
             (arg-string (match-string-no-properties 2))
             (retval (match-string-no-properties 4))
             (args (split-string arg-string "[ \t\n,]" t)))
        (when (re-search-forward (concat "^\\s *" funcname "\\s *(\\(\\(.\\|\n\\)*?\\))\\s *->") nil t)
          (let ((arg-types (split-string (match-string-no-properties 1) "[ \t\n,]" t)))
            (goto-char beg)
            (insert "%%-----------------------------------------------------------------------------\n")
            (insert "%% @doc\n")
            (insert "%% Your description goes here\n")
            (insert "%% @spec " funcname "(")
            (dolist (arg args)
              (insert (car arg-types) "::" arg)
              (setq arg-types (cdr arg-types))
              (when arg-types
                (insert ", ")))
            (insert ") ->\n")
            (insert "%%       " retval "\n")
            (insert "%% @end\n")
            (insert "%%-----------------------------------------------------------------------------\n")))))))
scottfrazer
+1. Thank you very much for this. Apart from the Integer::integer() part is working fine for a couple of sample functions :)
Roberto Aloi
It's a little closer now, but if you put args on separate lines you'll have to parse them differently. Does erlang-mode have any parsing you could take advantage of?
scottfrazer
Seems to work for args on separate lines now.
scottfrazer
Thank you for this :)
Roberto Aloi
A: 

The CEDET suite has supported Erlang at some level for quite a while. Older versions of CEDET, such as 1.0pre3 or thereabout also had edoc support for automatically generating comments similar to the ones you discuss above. The comment generation system changed recently, so that support is no longer there, so it would be great of someone wanted to pitch in templates for the new comment generation system that works through the CEDET subpackage SRecode. No knowledge of Emacs Lisp required.

http://cedet.sourceforge.net/

http://cedet.sourceforge.net/codegen.shtml

Eric