aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorDave Love2000-02-20 18:25:57 +0000
committerDave Love2000-02-20 18:25:57 +0000
commit2505742bda6f24068d16e7cf02329e15049fd2ea (patch)
treee653fceba6f7ee483b25ebddded9a5ece87b7f13 /lisp
parent329eed9f6e44972161dd9cce7a62ca2e68e5c700 (diff)
downloademacs-2505742bda6f24068d16e7cf02329e15049fd2ea.tar.gz
emacs-2505742bda6f24068d16e7cf02329e15049fd2ea.zip
Don't require emacsbug at top level.
(lm-get-header-re): Defun, not defsubst. (lm-get-package-name): Defun, not defsubst. Simplify. (lm-version): Doc fix. Simplify. (lm-header, lm-header-multiline, lm-header-multiline, lm-summary) (lm-crack-address, lm-last-modified-date, lm-commentary) (lm-verify, lm-synopsis): Simplify. (lm-report-bug): Require emacsbug. Use compose-mail.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/emacs-lisp/lisp-mnt.el298
1 files changed, 133 insertions, 165 deletions
diff --git a/lisp/emacs-lisp/lisp-mnt.el b/lisp/emacs-lisp/lisp-mnt.el
index 3e15384d028..0fac9d944ae 100644
--- a/lisp/emacs-lisp/lisp-mnt.el
+++ b/lisp/emacs-lisp/lisp-mnt.el
@@ -1,6 +1,6 @@
1;;; lisp-mnt.el --- minor mode for Emacs Lisp maintainers 1;;; lisp-mnt.el --- minor mode for Emacs Lisp maintainers
2 2
3;; Copyright (C) 1992, 1994, 1997 Free Software Foundation, Inc. 3;; Copyright (C) 1992, 1994, 1997, 2000 Free Software Foundation, Inc.
4 4
5;; Author: Eric S. Raymond <esr@snark.thyrsus.com> 5;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
6;; Maintainer: Eric S. Raymond <esr@snark.thyrsus.com> 6;; Maintainer: Eric S. Raymond <esr@snark.thyrsus.com>
@@ -113,8 +113,6 @@
113 113
114;;; Code: 114;;; Code:
115 115
116(require 'emacsbug)
117
118;;; Variables: 116;;; Variables:
119 117
120(defgroup lisp-mnt nil 118(defgroup lisp-mnt nil
@@ -155,7 +153,7 @@ then $identifier: doc string $ is used by GNU ident(1)"
155 153
156;; These functions all parse the headers of the current buffer 154;; These functions all parse the headers of the current buffer
157 155
158(defsubst lm-get-header-re (header &optional mode) 156(defun lm-get-header-re (header &optional mode)
159 "Return regexp for matching HEADER. 157 "Return regexp for matching HEADER.
160If called with optional MODE and with value `section', 158If called with optional MODE and with value `section',
161return section regexp instead." 159return section regexp instead."
@@ -164,7 +162,7 @@ return section regexp instead."
164 (t 162 (t
165 (concat lm-header-prefix header ":[ \t]*")))) 163 (concat lm-header-prefix header ":[ \t]*"))))
166 164
167(defsubst lm-get-package-name () 165(defun lm-get-package-name ()
168 "Return package name by looking at the first line." 166 "Return package name by looking at the first line."
169 (save-excursion 167 (save-excursion
170 (goto-char (point-min)) 168 (goto-char (point-min))
@@ -172,8 +170,7 @@ return section regexp instead."
172 (progn (goto-char (match-end 0)) 170 (progn (goto-char (match-end 0))
173 (looking-at "\\([^\t ]+\\)") 171 (looking-at "\\([^\t ]+\\)")
174 (match-end 1))) 172 (match-end 1)))
175 (buffer-substring-no-properties (match-beginning 1) (match-end 1)) 173 (match-string-no-properties 1))))
176 )))
177 174
178(defun lm-section-mark (header &optional after) 175(defun lm-section-mark (header &optional after)
179 "Return the buffer location of a given section start marker. 176 "Return the buffer location of a given section start marker.
@@ -186,8 +183,7 @@ If AFTER is non-nil, return the location of the next line."
186 (progn 183 (progn
187 (beginning-of-line) 184 (beginning-of-line)
188 (if after (forward-line 1)) 185 (if after (forward-line 1))
189 (point)) 186 (point))))))
190 nil))))
191 187
192(defsubst lm-code-mark () 188(defsubst lm-code-mark ()
193 "Return the buffer location of the `Code' start marker." 189 "Return the buffer location of the `Code' start marker."
@@ -209,8 +205,7 @@ If AFTER is non-nil, return the location of the next line."
209 ;; RCS ident likes format "$identifier: data$" 205 ;; RCS ident likes format "$identifier: data$"
210 (looking-at "\\([^$\n]+\\)") 206 (looking-at "\\([^$\n]+\\)")
211 (match-end 1)) 207 (match-end 1))
212 (buffer-substring-no-properties (match-beginning 1) (match-end 1)) 208 (match-string-no-properties 1))))
213 nil)))
214 209
215(defun lm-header-multiline (header) 210(defun lm-header-multiline (header)
216 "Return the contents of the header named HEADER, with continuation lines. 211 "Return the contents of the header named HEADER, with continuation lines.
@@ -221,20 +216,14 @@ The returned value is a list of strings, one per line."
221 (when res 216 (when res
222 (setq res (list res)) 217 (setq res (list res))
223 (forward-line 1) 218 (forward-line 1)
224
225 (while (and (looking-at (concat lm-header-prefix "[\t ]+")) 219 (while (and (looking-at (concat lm-header-prefix "[\t ]+"))
226 (progn 220 (progn
227 (goto-char (match-end 0)) 221 (goto-char (match-end 0))
228 (looking-at "\\(.*\\)")) 222 (looking-at "\\(.*\\)"))
229 (match-end 1)) 223 (match-end 1))
230 (setq res (cons (buffer-substring-no-properties 224 (setq res (cons (match-string-no-properties 1) res))
231 (match-beginning 1) 225 (forward-line 1)))
232 (match-end 1)) 226 res)))
233 res))
234 (forward-line 1))
235 )
236 res
237 )))
238 227
239;; These give us smart access to the header fields and commentary 228;; These give us smart access to the header fields and commentary
240 229
@@ -253,12 +242,10 @@ The returned value is a list of strings, one per line."
253 "Return the one-line summary of file FILE, or current buffer if FILE is nil." 242 "Return the one-line summary of file FILE, or current buffer if FILE is nil."
254 (lm-with-file file 243 (lm-with-file file
255 (goto-char (point-min)) 244 (goto-char (point-min))
256 (if (and 245 (if (and (looking-at lm-header-prefix)
257 (looking-at lm-header-prefix) 246 (progn (goto-char (match-end 0))
258 (progn (goto-char (match-end 0)) 247 (looking-at "[^ ]+[ \t]+--+[ \t]+\\(.*\\)")))
259 (looking-at "[^ ]+[ \t]+--+[ \t]+\\(.*\\)"))) 248 (let ((summary (match-string-no-properties 1)))
260 (let ((summary (buffer-substring-no-properties (match-beginning 1)
261 (match-end 1))))
262 ;; Strip off -*- specifications. 249 ;; Strip off -*- specifications.
263 (if (string-match "[ \t]*-\\*-.*-\\*-" summary) 250 (if (string-match "[ \t]*-\\*-.*-\\*-" summary)
264 (substring summary 0 (match-beginning 0)) 251 (substring summary 0 (match-beginning 0))
@@ -268,11 +255,11 @@ The returned value is a list of strings, one per line."
268 "Split up an email address X into full name and real email address. 255 "Split up an email address X into full name and real email address.
269The value is a cons of the form (FULLNAME . ADDRESS)." 256The value is a cons of the form (FULLNAME . ADDRESS)."
270 (cond ((string-match "\\(.+\\) [(<]\\(\\S-+@\\S-+\\)[>)]" x) 257 (cond ((string-match "\\(.+\\) [(<]\\(\\S-+@\\S-+\\)[>)]" x)
271 (cons (substring x (match-beginning 1) (match-end 1)) 258 (cons (match-string 1 x)
272 (substring x (match-beginning 2) (match-end 2)))) 259 (match-string 2 x)))
273 ((string-match "\\(\\S-+@\\S-+\\) [(<]\\(.*\\)[>)]" x) 260 ((string-match "\\(\\S-+@\\S-+\\) [(<]\\(.*\\)[>)]" x)
274 (cons (substring x (match-beginning 2) (match-end 2)) 261 (cons (match-string 2 x)
275 (substring x (match-beginning 1) (match-end 1)))) 262 (match-string 1 x)))
276 ((string-match "\\S-+@\\S-+" x) 263 ((string-match "\\S-+@\\S-+" x)
277 (cons nil x)) 264 (cons nil x))
278 (t 265 (t
@@ -300,45 +287,43 @@ The return value has the form (NAME . ADDRESS)."
300 (lm-with-file file 287 (lm-with-file file
301 (lm-header "created"))) 288 (lm-header "created")))
302 289
303
304(defun lm-last-modified-date (&optional file) 290(defun lm-last-modified-date (&optional file)
305 "Return the modify-date given in file FILE, or current buffer if FILE is nil." 291 "Return the modify-date given in file FILE, or current buffer if FILE is nil."
306 (lm-with-file file 292 (lm-with-file file
307 (goto-char (point-min)) 293 (if (progn
308 (when (re-search-forward 294 (goto-char (point-min))
295 (re-search-forward
309 "\\$[I]d: [^ ]+ [^ ]+ \\([^/]+\\)/\\([^/]+\\)/\\([^ ]+\\) " 296 "\\$[I]d: [^ ]+ [^ ]+ \\([^/]+\\)/\\([^/]+\\)/\\([^ ]+\\) "
310 (lm-code-mark) t) 297 (lm-code-mark) t))
311 (format "%s %s %s" 298 (format "%s %s %s"
312 (buffer-substring (match-beginning 3) (match-end 3)) 299 (match-string 3)
313 (nth (string-to-int 300 (nth (string-to-int
314 (buffer-substring (match-beginning 2) (match-end 2))) 301 (match-string 2))
315 '("" "Jan" "Feb" "Mar" "Apr" "May" "Jun" 302 '("" "Jan" "Feb" "Mar" "Apr" "May" "Jun"
316 "Jul" "Aug" "Sep" "Oct" "Nov" "Dec")) 303 "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"))
317 (buffer-substring (match-beginning 1) (match-end 1)))))) 304 (match-string 1)))))
318 305
319(defun lm-version (&optional file) 306(defun lm-version (&optional file)
320 "Return the version listed in file FILE, or current buffer if FILE is nil. 307 "Return the version listed in file FILE, or current buffer if FILE is nil.
321This can befound in an RCS or SCCS header to crack it out of." 308This can be found in an RCS or SCCS header."
322 (lm-with-file file 309 (lm-with-file file
323 (or 310 (or (lm-header "version")
324 (lm-header "version") 311 (let ((header-max (lm-code-mark)))
325 (let ((header-max (lm-code-mark))) 312 (goto-char (point-min))
326 (goto-char (point-min)) 313 (cond
327 (cond 314 ;; Look for an RCS header
328 ;; Look for an RCS header 315 ((re-search-forward "\\$[I]d: [^ ]+ \\([^ ]+\\) " header-max t)
329 ((re-search-forward "\\$[I]d: [^ ]+ \\([^ ]+\\) " header-max t) 316 (match-string-no-properties 1))
330 (buffer-substring-no-properties (match-beginning 1) (match-end 1))) 317 ((re-search-forward "\\$Revision: +\\([^ ]+\\) " header-max t)
331 318 (match-string-no-properties 1))
332 ;; Look for an SCCS header 319 ;; Look for an SCCS header
333 ((re-search-forward 320 ((re-search-forward
334 (concat 321 (concat
335 (regexp-quote "@(#)") 322 (regexp-quote "@(#)")
336 (regexp-quote (file-name-nondirectory (buffer-file-name))) 323 (regexp-quote (file-name-nondirectory (buffer-file-name)))
337 "\t\\([012345679.]*\\)") 324 "\t\\([012345679.]*\\)")
338 header-max t) 325 header-max t)
339 (buffer-substring-no-properties (match-beginning 1) (match-end 1))) 326 (match-string-no-properties 1)))))))
340
341 (t nil))))))
342 327
343(defun lm-keywords (&optional file) 328(defun lm-keywords (&optional file)
344 "Return the keywords given in file FILE, or current buffer if FILE is nil." 329 "Return the keywords given in file FILE, or current buffer if FILE is nil."
@@ -359,12 +344,14 @@ The value is returned as a string. In the file, the commentary starts
359with the tag `Commentary' or `Documentation' and ends with one of the 344with the tag `Commentary' or `Documentation' and ends with one of the
360tags `Code', `Change Log' or `History'." 345tags `Code', `Change Log' or `History'."
361 (lm-with-file file 346 (lm-with-file file
362 (let ((commentary (lm-commentary-mark)) 347 (let ((commentary (lm-commentary-mark))
363 (change-log (lm-history-mark)) 348 (change-log (lm-history-mark))
364 (code (lm-code-mark))) 349 (code (lm-code-mark)))
365 (when (and commentary (or change-log code)) 350 (cond
366 (buffer-substring-no-properties 351 ((and commentary change-log)
367 commentary (min (or code (point-max)) (or change-log (point-max)))))))) 352 (buffer-substring-no-properties commentary change-log))
353 ((and commentary code)
354 (buffer-substring-no-properties commentary code))))))
368 355
369;;; Verification and synopses 356;;; Verification and synopses
370 357
@@ -379,79 +366,57 @@ tags `Code', `Change Log' or `History'."
379If FILE is a directory, recurse on its files and generate a report in 366If FILE is a directory, recurse on its files and generate a report in
380a temporary buffer." 367a temporary buffer."
381 (interactive) 368 (interactive)
382 (let* ((verb (or verb (interactive-p))) 369 (let* ((verb (or verb (interactive-p)))
383 ret 370 (ret (and verb "Ok."))
384 name 371 name)
385 )
386 (if verb
387 (setq ret "Ok.")) ;init value
388
389 (if (and file (file-directory-p file)) 372 (if (and file (file-directory-p file))
390 (setq 373 (setq ret
391 ret 374 (with-temp-buffer
392 (progn 375 (mapcar
393 (switch-to-buffer (get-buffer-create "*lm-verify*")) 376 (lambda (f)
394 (erase-buffer) 377 (if (string-match ".*\\.el\\'" f)
395 (mapcar 378 (let ((status (lm-verify f)))
396 '(lambda (f) 379 (insert f ":")
397 (if (string-match ".*\\.el$" f) 380 (if status
398 (let ((status (lm-verify f))) 381 (lm-insert-at-column lm-comment-column status
399 (if status 382 "\n")
400 (progn 383 (if showok
401 (insert f ":") 384 (lm-insert-at-column lm-comment-column
402 (lm-insert-at-column lm-comment-column status "\n")) 385 "OK\n"))))))
403 (and showok 386 (directory-files file))))
404 (progn
405 (insert f ":")
406 (lm-insert-at-column lm-comment-column "OK\n")))))))
407 (directory-files file))
408 ))
409 (lm-with-file file 387 (lm-with-file file
410 (setq name (lm-get-package-name)) 388 (setq name (lm-get-package-name))
411 389 (setq ret
412 (setq 390 (cond
413 ret 391 ((null name)
414 (cond 392 "Can't find a package NAME")
415 ((null name) 393 ((not (lm-authors))
416 "Can't find a package NAME") 394 "Author: tag missing.")
417 395 ((not (lm-maintainer))
418 ((not (lm-authors)) 396 "Maintainer: tag missing.")
419 "Author: tag missing.") 397 ((not (lm-summary))
420 398 "Can't find a one-line 'Summary' description")
421 ((not (lm-maintainer)) 399 ((not (lm-keywords))
422 "Maintainer: tag missing.") 400 "Keywords: tag missing.")
423 401 ((not (lm-commentary-mark))
424 ((not (lm-summary)) 402 "Can't find a 'Commentary' section marker.")
425 "Can't find a one-line 'Summary' description") 403 ((not (lm-history-mark))
426 404 "Can't find a 'History' section marker.")
427 ((not (lm-keywords)) 405 ((not (lm-code-mark))
428 "Keywords: tag missing.") 406 "Can't find a 'Code' section marker")
429 407 ((progn
430 ((not (lm-commentary-mark)) 408 (goto-char (point-max))
431 "Can't find a 'Commentary' section marker.") 409 (not
432 410 (re-search-backward
433 ((not (lm-history-mark)) 411 (concat "^;;;[ \t]+" name "[ \t]+ends here[ \t]*$"
434 "Can't find a 'History' section marker.") 412 "\\|^;;;[ \t]+ End of file[ \t]+" name)
435 413 nil t)))
436 ((not (lm-code-mark)) 414 (format "Can't find a footer line for [%s]" name))
437 "Can't find a 'Code' section marker") 415 (t
438 416 ret)))))
439 ((progn
440 (goto-char (point-max))
441 (not
442 (re-search-backward
443 (concat "^;;;[ \t]+" name "[ \t]+ends here[ \t]*$"
444 "\\|^;;;[ \t]+ End of file[ \t]+" name)
445 nil t
446 )))
447 (format "Can't find a footer line for [%s]" name))
448 (t
449 ret))
450 )))
451 (if verb 417 (if verb
452 (message ret)) 418 (message ret))
453 ret 419 ret))
454 ))
455 420
456(defun lm-synopsis (&optional file showall) 421(defun lm-synopsis (&optional file showall)
457 "Generate a synopsis listing for the buffer or the given FILE if given. 422 "Generate a synopsis listing for the buffer or the given FILE if given.
@@ -463,43 +428,46 @@ which do not include a recognizable synopsis."
463 (read-file-name "Synopsis for (file or dir): "))) 428 (read-file-name "Synopsis for (file or dir): ")))
464 429
465 (if (and file (file-directory-p file)) 430 (if (and file (file-directory-p file))
466 (progn 431 (with-temp-buffer
467 (switch-to-buffer (get-buffer-create "*lm-verify*"))
468 (erase-buffer)
469 (mapcar 432 (mapcar
470 '(lambda (f) 433 (lambda (f)
471 (if (string-match ".*\\.el$" f) 434 (if (string-match "\\.el\\'" f)
472 (let ((syn (lm-synopsis f))) 435 (let ((syn (lm-synopsis f)))
473 (if syn 436 (if syn
474 (progn 437 (progn
475 (insert f ":") 438 (insert f ":")
476 (lm-insert-at-column lm-comment-column syn "\n")) 439 (lm-insert-at-column lm-comment-column syn "\n"))
477 (and showall 440 (when showall
478 (progn 441 (insert f ":")
479 (insert f ":") 442 (lm-insert-at-column lm-comment-column "NA\n"))))))
480 (lm-insert-at-column lm-comment-column "NA\n"))))))) 443 (directory-files file)))
481 (directory-files file)) 444 (save-excursion
482 ) 445 (if file
483 (lm-with-file file 446 (find-file file))
484 (lm-summary)))) 447 (prog1
448 (lm-summary)
449 (if file
450 (kill-buffer (current-buffer)))))))
451
452(eval-when-compile (defvar report-emacs-bug-address))
485 453
486(defun lm-report-bug (topic) 454(defun lm-report-bug (topic)
487 "Report a bug in the package currently being visited to its maintainer. 455 "Report a bug in the package currently being visited to its maintainer.
488Prompts for bug subject TOPIC. Leaves you in a mail buffer." 456Prompts for bug subject TOPIC. Leaves you in a mail buffer."
489 (interactive "sBug Subject: ") 457 (interactive "sBug Subject: ")
490 (let ((package (lm-get-package-name)) 458 (require 'emacsbug)
491 (addr (lm-maintainer)) 459 (let ((package (lm-get-package-name))
492 (version (lm-version))) 460 (addr (lm-maintainer))
493 (mail nil 461 (version (lm-version)))
494 (if addr 462 (compose-mail (if addr
495 (concat (car addr) " <" (cdr addr) ">") 463 (concat (car addr) " <" (cdr addr) ">")
496 report-emacs-bug-address) 464 report-emacs-bug-address)
497 topic) 465 topic)
498 (goto-char (point-max)) 466 (goto-char (point-max))
499 (insert "\nIn " 467 (insert "\nIn " package)
500 package 468 (if version
501 (if version (concat " version " version) "") 469 (insert " version " version))
502 "\n\n") 470 (newline 2)
503 (message 471 (message
504 (substitute-command-keys "Type \\[mail-send] to send bug report.")))) 472 (substitute-command-keys "Type \\[mail-send] to send bug report."))))
505 473