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.upstream,v 1.1 2007-11-26 15:11:52 michaels 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