1 ;;; erlang-edoc.el --- Erlang programs documenting support for Semantic
3 ;; Copyright (C) 2002, 2004, 2007 Vladimir G. Sekissov
5 ;; Author: <svg@surnet.ru>
6 ;; Keywords: languages, docs
7 ;; $Id: erlang-edoc.el,v 1.5 2007/02/19 13:35:04 zappo Exp $
9 ;; This file is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; This file is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 ;; Boston, MA 02110-1301, USA.
26 ;; Derived from document.el of Eric M. Ludlam <zappo@gnu.org>
29 (require 'document-vars
)
32 (defcustom erlang-edoc-function-comment
"
34 %m @spec %F( %P ) -> Return
42 "See `document-function-comment'"
46 (defcustom erlang-edoc-record-comment
"
56 "See `document-function-comment'"
60 (defcustom erlang-edoc-type-spec
"%P = %D"
62 %P - align parameter name to longest,
68 (defcustom erlang-edoc-desc-spec
"<dt>%P</dt><dd>%D</dd>"
69 "Parameter description spec.
70 %P - align parameter name to longest,
76 (defsubst erlang-edoc--tag-name
(nonterm)
78 (if (stringp nonterm
) nonterm
(semantic-tag-name nonterm
)))
80 (defun erlang-edoc-inline ()
81 "Document the current nonterminal with an inline comment."
84 (let ((ct (semantic-brute-find-tag-by-position (point) (current-buffer))))
85 (erlang-edoc-insert-comment ct
(current-buffer))))
87 (defun erlang-edoc-insert-comment-new (nonterm template
)
88 "Insert a new comment which explains the function found in NONTERM."
93 ;; nonterm should always be correct.
94 (goto-char (semantic-tag-start nonterm
))
96 (insert (funcall template nonterm
'zpnt
'pnt
))
97 (goto-char (+ zpnt st
))
98 (message "Setting fill prefix to: \"%s\""
100 (concat (document-comment-line-prefix)
103 (length (document-comment-line-prefix)))
105 (goto-char (+ pnt st
))
109 (defun erlang-edoc-insert-comment (nonterm buffer
)
110 "Insert mode-comment documentation about NONTERM from BUFFER."
111 (let ((tt (semantic-tag-class nonterm
)))
114 (erlang-edoc-insert-comment-new nonterm
#'erlang-edoc--function-template
)
117 (erlang-edoc-insert-comment-new nonterm
#'erlang-edoc--record-template
)
120 (error "Type %S is not yet managed by document `erlang-edoc-inline'" tt
))
123 (defun erlang-edoc--function-template (nonterm pref-var focus-var
)
124 "Generate NONTERM function template for insertion."
125 (let ((fname (erlang-edoc--strip-arity (semantic-tag-name nonterm
)))
126 (params (semantic-tag-function-arguments nonterm
)))
127 (Sformat (list (list ?F fname
)
128 (list ?P
(erlang-edoc--param-specs params
))
130 (erlang-edoc--type-specs
133 (set pref-var
(Sformat-point)) ""))
135 (setq focus-var
(Sformat-point)) ""))
136 (list ?b
(document-comment-start))
137 (list ?m
(document-comment-line-prefix))
138 (list ?e
(document-comment-end)))
139 erlang-edoc-function-comment
)
142 (defun erlang-edoc--record-template (nonterm pref-var focus-var
)
143 "Generate NONTERM record template for insertion."
144 (let ((tname (semantic-tag-name nonterm
))
145 (params (semantic-tag-type-members nonterm
)))
146 (Sformat (list (list ?F tname
)
148 (erlang-edoc--type-specs
149 params t erlang-edoc-desc-spec
)))
150 (list ?f
'(lambda () (set pref-var
(Sformat-point)) ""))
151 (list ?p
'(lambda () (set focus-var
(Sformat-point)) ""))
152 (list ?b
(document-comment-start))
153 (list ?m
(document-comment-line-prefix))
154 (list ?e
(document-comment-end)))
155 erlang-edoc-record-comment
)
158 (defun erlang-edoc--strip-arity (tag-name)
159 "Strip arity from TAG-NAME"
161 (substring tag-name
0 (string-match "/[0-9]+$" tag-name
)))
163 (defun erlang-edoc--param-specs (params)
164 "Parameters specification string for PARAMS"
165 (apply 'concat
(cons (erlang-edoc--tag-name (car params
))
168 (erlang-edoc--tag-name p
)))
172 (defun erlang-edoc--type-specs (params &optional add-comment template
)
173 "Convert a parameter list PARAMS into a vertical list separated by =es."
174 (let* ((tmpl (if template
176 erlang-edoc-type-spec
))
177 (col (if Sformat-formatting
(Sformat-column) (current-column)))
179 (longest (document-longest-name newl
))
182 (let* ((n (car newl
))
183 (nn (erlang-edoc--tag-name n
))
185 (or (erlang-edoc--nonterm-comment n
)
189 (let ((nextp (Sformat
202 (concat "\n" (document-comment-line-prefix)
204 (- col
(length (document-comment-line-prefix)))
206 (setq newl
(cdr newl
)))
207 (if (= (length newp
) 0) "" newp
)
210 (defun erlang-edoc--nonterm-comment (nonterm)
211 "Extract inline comment for NONTERM."
212 (cond ((stringp nonterm
) nil
)
213 ((not (semantic-tag-end nonterm
)) nil
)
214 ((not (semantic-tag-start nonterm
)) nil
)
217 (goto-char (semantic-tag-start nonterm
))
219 ((le (line-end-position))
220 (ss (cond ((re-search-forward ",\\s-*" le t
1)
222 ((re-search-forward "%" le t
1)
225 (str (if ss
(buffer-substring-no-properties ss le
) ""))
227 (and (string-match "^\\(\\s-*\\s<+\\)\\s-*" str
)
229 (de (or (string-match "\\s-+$" str
)
234 (t (let ((ret (substring str ds de
)))
235 (if (= (length ret
) 0) nil ret
)))
239 (provide 'erlang-edoc
)
240 ;;; erlang-edoc.el ends here