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.1 2007-11-26 15:11:51 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>
28 (provide 'erlang-edoc)
31 (require 'document-vars)
34 (defcustom erlang-edoc-function-comment "
36 %m @spec %F( %P ) -> Return
44 "See `document-function-comment'"
48 (defcustom erlang-edoc-record-comment "
58 "See `document-function-comment'"
62 (defcustom erlang-edoc-type-spec "%P = %D"
64 %P - align parameter name to longest,
70 (defcustom erlang-edoc-desc-spec "<dt>%P</dt><dd>%D</dd>"
71 "Parameter description spec.
72 %P - align parameter name to longest,
78 (defsubst erlang-edoc--tag-name (nonterm)
80 (if (stringp nonterm) nonterm (semantic-tag-name nonterm)))
82 (defun erlang-edoc-inline ()
83 "Document the current nonterminal with an inline comment."
86 (let ((ct (semantic-brute-find-tag-by-position (point) (current-buffer))))
87 (erlang-edoc-insert-comment ct (current-buffer))))
89 (defun erlang-edoc-insert-comment-new (nonterm template)
90 "Insert a new comment which explains the function found in NONTERM."
95 ;; nonterm should always be correct.
96 (goto-char (semantic-tag-start nonterm))
98 (insert (funcall template nonterm 'zpnt 'pnt))
99 (goto-char (+ zpnt st))
100 (message "Setting fill prefix to: \"%s\""
102 (concat (document-comment-line-prefix)
105 (length (document-comment-line-prefix)))
107 (goto-char (+ pnt st))
111 (defun erlang-edoc-insert-comment (nonterm buffer)
112 "Insert mode-comment documentation about NONTERM from BUFFER."
113 (let ((tt (semantic-tag-class nonterm)))
116 (erlang-edoc-insert-comment-new nonterm #'erlang-edoc--function-template)
119 (erlang-edoc-insert-comment-new nonterm #'erlang-edoc--record-template)
122 (error "Type %S is not yet managed by document `erlang-edoc-inline'" tt))
125 (defun erlang-edoc--function-template (nonterm pref-var focus-var)
126 "Generate NONTERM function template for insertion."
127 (let ((fname (erlang-edoc--strip-arity (semantic-tag-name nonterm)))
128 (params (semantic-tag-function-arguments nonterm)))
129 (Sformat (list (list ?F fname)
130 (list ?P (erlang-edoc--param-specs params))
132 (erlang-edoc--type-specs
135 (set pref-var (Sformat-point)) ""))
137 (setq focus-var (Sformat-point)) ""))
138 (list ?b (document-comment-start))
139 (list ?m (document-comment-line-prefix))
140 (list ?e (document-comment-end)))
141 erlang-edoc-function-comment)
144 (defun erlang-edoc--record-template (nonterm pref-var focus-var)
145 "Generate NONTERM record template for insertion."
146 (let ((tname (semantic-tag-name nonterm))
147 (params (semantic-tag-type-members nonterm)))
148 (Sformat (list (list ?F tname)
150 (erlang-edoc--type-specs
151 params t erlang-edoc-desc-spec)))
152 (list ?f '(lambda () (set pref-var (Sformat-point)) ""))
153 (list ?p '(lambda () (set focus-var (Sformat-point)) ""))
154 (list ?b (document-comment-start))
155 (list ?m (document-comment-line-prefix))
156 (list ?e (document-comment-end)))
157 erlang-edoc-record-comment)
160 (defun erlang-edoc--strip-arity (tag-name)
161 "Strip arity from TAG-NAME"
163 (substring tag-name 0 (string-match "/[0-9]+$" tag-name)))
165 (defun erlang-edoc--param-specs (params)
166 "Parameters specification string for PARAMS"
167 (apply 'concat (cons (erlang-edoc--tag-name (car params))
170 (erlang-edoc--tag-name p)))
174 (defun erlang-edoc--type-specs (params &optional add-comment template)
175 "Convert a parameter list PARAMS into a vertical list separated by =es."
176 (let* ((tmpl (if template
178 erlang-edoc-type-spec))
179 (col (if Sformat-formatting (Sformat-column) (current-column)))
181 (longest (document-longest-name newl))
184 (let* ((n (car newl))
185 (nn (erlang-edoc--tag-name n))
187 (or (erlang-edoc--nonterm-comment n)
191 (let ((nextp (Sformat
204 (concat "\n" (document-comment-line-prefix)
206 (- col (length (document-comment-line-prefix)))
208 (setq newl (cdr newl)))
209 (if (= (length newp) 0) "" newp)
212 (defun erlang-edoc--nonterm-comment (nonterm)
213 "Extract inline comment for NONTERM."
214 (cond ((stringp nonterm) nil)
215 ((not (semantic-tag-end nonterm)) nil)
216 ((not (semantic-tag-start nonterm)) nil)
219 (goto-char (semantic-tag-start nonterm))
221 ((le (line-end-position))
222 (ss (cond ((re-search-forward ",\\s-*" le t 1)
224 ((re-search-forward "%" le t 1)
227 (str (if ss (buffer-substring-no-properties ss le) ""))
229 (and (string-match "^\\(\\s-*\\s<+\\)\\s-*" str)
231 (de (or (string-match "\\s-+$" str)
236 (t (let ((ret (substring str ds de)))
237 (if (= (length ret) 0) nil ret)))
241 ;;; erlang-edoc.el ends here