Initial Commit
[temp.git] / site-lisp / cedet-1.0pre4 / semantic / bovine / erlang-edoc.el
blob53a7a96e73cf3ed326cc789e3e281a086ab6cbfe
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)
12 ;; any later version.
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.
24 ;;; Commentary:
26 ;; Derived from document.el of Eric M. Ludlam <zappo@gnu.org>
28 (require 'document)
29 (require 'document-vars)
31 ;;; Code:
32 (defcustom erlang-edoc-function-comment "
34 %m @spec %F( %P ) -> Return
36 %m %T
37 %m @doc %f%p
39 %m @end
42 "See `document-function-comment'"
43 :group 'document
44 :type 'string)
46 (defcustom erlang-edoc-record-comment "
48 %m @type %F().
49 %m <dl>
50 %m %T
51 %m </dl>
52 %m %f%p
53 %m @end
56 "See `document-function-comment'"
57 :group 'document
58 :type 'string)
60 (defcustom erlang-edoc-type-spec "%P = %D"
61 "Parameter type spec.
62 %P - align parameter name to longest,
63 %p - as is,
64 %D - description."
65 :group 'semantic
66 :type 'string)
68 (defcustom erlang-edoc-desc-spec "<dt>%P</dt><dd>%D</dd>"
69 "Parameter description spec.
70 %P - align parameter name to longest,
71 %p - as is,
72 %D - description."
73 :group 'semantic
74 :type 'string)
76 (defsubst erlang-edoc--tag-name (nonterm)
77 "Nonterminal name."
78 (if (stringp nonterm) nonterm (semantic-tag-name nonterm)))
80 (defun erlang-edoc-inline ()
81 "Document the current nonterminal with an inline comment."
82 (interactive)
83 (semantic-fetch-tags)
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."
89 (let ((pnt 0)
90 (st 0)
91 (zpnt 0)
93 ;; nonterm should always be correct.
94 (goto-char (semantic-tag-start nonterm))
95 (setq st (point))
96 (insert (funcall template nonterm 'zpnt 'pnt))
97 (goto-char (+ zpnt st))
98 (message "Setting fill prefix to: \"%s\""
99 (setq fill-prefix
100 (concat (document-comment-line-prefix)
101 (make-string
102 (- (current-column)
103 (length (document-comment-line-prefix)))
104 ? ))))
105 (goto-char (+ pnt st))
106 (auto-fill-mode 1)
109 (defun erlang-edoc-insert-comment (nonterm buffer)
110 "Insert mode-comment documentation about NONTERM from BUFFER."
111 (let ((tt (semantic-tag-class nonterm)))
112 (cond
113 ((eq tt 'function)
114 (erlang-edoc-insert-comment-new nonterm #'erlang-edoc--function-template)
115 (message "Done..."))
116 ((eq tt 'type)
117 (erlang-edoc-insert-comment-new nonterm #'erlang-edoc--record-template)
118 (message "Done..."))
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))
129 (list ?T '(lambda ()
130 (erlang-edoc--type-specs
131 params t)))
132 (list ?f '(lambda ()
133 (set pref-var (Sformat-point)) ""))
134 (list ?p '(lambda ()
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)
147 (list ?T '(lambda ()
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"
160 ;;stripping arity
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))
166 (mapcar (lambda (p)
167 (concat ", "
168 (erlang-edoc--tag-name p)))
169 (cdr params))))
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
175 template
176 erlang-edoc-type-spec))
177 (col (if Sformat-formatting (Sformat-column) (current-column)))
178 (newl params)
179 (longest (document-longest-name newl))
180 (newp ""))
181 (while newl
182 (let* ((n (car newl))
183 (nn (erlang-edoc--tag-name n))
184 (nc (if add-comment
185 (or (erlang-edoc--nonterm-comment n)
186 "undocumented")
187 ""))
189 (let ((nextp (Sformat
190 (list (list ?P
191 (substring (concat
193 " ")
194 0 longest))
195 (list ?D nc)
196 (list ?p n)
198 tmpl)))
199 (setq newp
200 (concat
201 newp nextp
202 (concat "\n" (document-comment-line-prefix)
203 (make-string
204 (- col (length (document-comment-line-prefix)))
205 ? ))))))
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)
216 (save-excursion
217 (goto-char (semantic-tag-start nonterm))
218 (let*
219 ((le (line-end-position))
220 (ss (cond ((re-search-forward ",\\s-*" le t 1)
221 (match-end 0))
222 ((re-search-forward "%" le t 1)
223 (- (match-end 0) 1))
224 (t nil)))
225 (str (if ss (buffer-substring-no-properties ss le) ""))
226 (ds (progn
227 (and (string-match "^\\(\\s-*\\s<+\\)\\s-*" str)
228 (match-end 0))))
229 (de (or (string-match "\\s-+$" str)
230 (length str)))
232 (cond ((not ds) nil)
233 ((<= de ds ) nil)
234 (t (let ((ret (substring str ds de)))
235 (if (= (length ret) 0) nil ret)))
237 ))))
239 (provide 'erlang-edoc)
240 ;;; erlang-edoc.el ends here