879
+ 鐃緒申 1 ;;; lisp-mnt.el --- minor mode for Emacs Lisp maintainers
+ 鐃緒申 2
+ 鐃緒申 3 ;; Copyright (C) 1992 Free Software Foundation, Inc.
+ 鐃緒申 4
+ 鐃緒申 5 ;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
+ 鐃緒申 6 ;; Maintainer: Eric S. Raymond <esr@snark.thyrsus.com>
+ 鐃緒申 7 ;; Created: 14 Jul 1992
+ 鐃緒申 8 ;; Version: 1.2
+ 鐃緒申 9 ;; Keywords: docs
+ 鐃緒申 10 ;; Bogus-Bureaucratic-Cruft: Gruad will get you if you don't watch out!
+ 鐃緒申 11
+ 鐃緒申 12 ;; This file is part of GNU Emacs.
+ 鐃緒申 13
+ 鐃緒申 14 ;; GNU Emacs is free software; you can redistribute it and/or modify
+ 鐃緒申 15 ;; it under the terms of the GNU General Public License as published by
+ 鐃緒申 16 ;; the Free Software Foundation; either version 1, or (at your option)
+ 鐃緒申 17 ;; any later version.
+ 鐃緒申 18
+ 鐃緒申 19 ;; GNU Emacs is distributed in the hope that it will be useful,
+ 鐃緒申 20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+ 鐃緒申 21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 鐃緒申 22 ;; GNU General Public License for more details.
+ 鐃緒申 23
+ 鐃緒申 24 ;; You should have received a copy of the GNU General Public License
+ 鐃緒申 25 ;; along with GNU Emacs; see the file COPYING. If not, write to
+ 鐃緒申 26 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ 鐃緒申 27
+ 鐃緒申 28 ;;; Commentary:
+ 鐃緒申 29
+ 鐃緒申 30 ;; This minor mode adds some services to Emacs-Lisp editing mode.
+ 鐃緒申 31 ;;
+ 鐃緒申 32 ;; First, it knows about the header conventions for library packages.
+ 鐃緒申 33 ;; One entry point supports generating synopses from a library directory.
+ 鐃緒申 34 ;; Another can be used to check for missing headers in library files.
+ 鐃緒申 35 ;;
+ 鐃緒申 36 ;; Another entry point automatically addresses bug mail to a package's
+ 鐃緒申 37 ;; maintainer or author.
+ 鐃緒申 38
+ 鐃緒申 39 ;; This file can be loaded by your lisp-mode-hook. Have it (require 'lisp-mnt)
+ 鐃緒申 40
+ 鐃緒申 41 ;; This file is an example of the header conventions. Note the following
+ 鐃緒申 42 ;; features:
+ 鐃緒申 43 ;;
+ 鐃緒申 44 ;; * Header line --- makes it possible to extract a one-line summary of
+ 鐃緒申 45 ;; the package's uses automatically for use in library synopses, KWIC
+ 鐃緒申 46 ;; indexes and the like.
+ 鐃緒申 47 ;;
+ 鐃緒申 48 ;; Format is three semicolons, followed by the filename, followed by
+ 鐃緒申 49 ;; three dashes, followed by the summary. All fields space-separated.
+ 鐃緒申 50 ;;
+ 鐃緒申 51 ;; * Author line --- contains the name and net address of at least
+ 鐃緒申 52 ;; the principal author.
+ 鐃緒申 53 ;;
+ 鐃緒申 54 ;; If there are multible authors, they should be listed on continuation
+ 鐃緒申 55 ;; lines led by ;;<TAB>, like this:
+ 鐃緒申 56 ;;
+ 鐃緒申 57 ;; ;; Author: Ashwin Ram <Ram-Ashwin@cs.yale.edu>
+ 鐃緒申 58 ;; ;; Dave Sill <de5@ornl.gov>
+ 鐃緒申 59 ;; ;; David Lawrence <tale@pawl.rpi.edu>
+ 鐃緒申 60 ;; ;; Noah Friedman <friedman@ai.mit.edu>
+ 鐃緒申 61 ;; ;; Joe Wells <jbw@maverick.uswest.com>
+ 鐃緒申 62 ;; ;; Dave Brennan <brennan@hal.com>
+ 鐃緒申 63 ;; ;; Eric Raymond <esr@snark.thyrsus.com>
+ 鐃緒申 64 ;;
+ 鐃緒申 65 ;; This field may have some special values; notably "FSF", meaning
+ 鐃緒申 66 ;; "Free Software Foundation".
+ 鐃緒申 67 ;;
+ 鐃緒申 68 ;; * Maintainer line --- should be a single name/address as in the Author
+ 鐃緒申 69 ;; line, or an address only, or the string "FSF". If there is no maintainer
+ 鐃緒申 70 ;; line, the person(s) in the Author field are presumed to be it. The example
+ 鐃緒申 71 ;; in this file is mildly bogus because the maintainer line is redundant.
+ 鐃緒申 72 ;; The idea behind these two fields is to be able to write a lisp function
+ 鐃緒申 73 ;; that does "send mail to the author" without having to mine the name out by
+ 鐃緒申 74 ;; hand. Please be careful about surrounding the network address with <> if
+ 鐃緒申 75 ;; there's also a name in the field.
+ 鐃緒申 76 ;;
+ 鐃緒申 77 ;; * Created line --- optional, gives the original creation date of the
+ 鐃緒申 78 ;; file. For historical interest, basically.
+ 鐃緒申 79 ;;
+ 鐃緒申 80 ;; * Version line --- intended to give the reader a clue if they're looking
+ 鐃緒申 81 ;; at a different version of the file than the one they're accustomed to. Not
+ 鐃緒申 82 ;; needed if you have an RCS or SCCS header.
+ 鐃緒申 83 ;;
+ 鐃緒申 84 ;; * Adapted-By line --- this is for FSF's internal use. The person named
+ 鐃緒申 85 ;; in this field was the one responsible for installing and adapting the
+ 鐃緒申 86 ;; package for the distribution. (This file doesn't have one because the
+ 鐃緒申 87 ;; author *is* one of the maintainers.)
+ 鐃緒申 88 ;;
+ 鐃緒申 89 ;; * Keywords line --- used by the finder code (now under construction)
+ 鐃緒申 90 ;; for finding elisp code related to a topic.
+ 鐃緒申 91 ;;
+ 鐃緒申 92 ;; * Bogus-Bureaucratic-Cruft line --- this is a joke. I figured I should
+ 鐃緒申 93 ;; satirize this design before someone else did. Also, it illustrates the
+ 鐃緒申 94 ;; possibility that other headers may be added in the future for new purposes.
+ 鐃緒申 95 ;;
+ 鐃緒申 96 ;; * Commentary line --- enables lisp code to find the developer's and
+ 鐃緒申 97 ;; maintainers' explanations of the package internals.
+ 鐃緒申 98 ;;
+ 鐃緒申 99 ;; * Change log line --- optional, exists to terminate the commentary
+ 鐃緒申 100 ;; section and start a change-log part, if one exists.
+ 鐃緒申 101 ;;
+ 鐃緒申 102 ;; * Code line --- exists so elisp can know where commentary and/or
+ 鐃緒申 103 ;; change-log sections end.
+ 鐃緒申 104 ;;
+ 鐃緒申 105 ;; * Footer line --- marks end-of-file so it can be distinguished from
+ 鐃緒申 106 ;; an expanded formfeed or the results of truncation.
+ 鐃緒申 107
+ 鐃緒申 108 ;;; Change Log:
+ 鐃緒申 109
+ 鐃緒申 110 ;; Tue Jul 14 23:44:17 1992 ESR
+ 鐃緒申 111 ;; * Created.
+ 鐃緒申 112
+ 鐃緒申 113 ;;; Code:
+ 鐃緒申 114
+ 鐃緒申 115 (require 'picture) ; provides move-to-column-force
+ 鐃緒申 116
+ 鐃緒申 117 ;; These functions all parse the headers of the current buffer
+ 鐃緒申 118
+ 鐃緒申 119 (defun lm-section-mark (hd)
+ 鐃緒申 120 ;; Return the buffer location of a given section start marker
+ 鐃緒申 121 (save-excursion
+ 鐃緒申 122 (let ((case-fold-search t))
+ 鐃緒申 123 (goto-char (point-min))
+ 鐃緒申 124 (if (re-search-forward (concat "^;;; " hd ":$") nil t)
+ 鐃緒申 125 (progn
+ 鐃緒申 126 (beginning-of-line)
+ 鐃緒申 127 (point))
+ 鐃緒申 128 nil))))
+ 鐃緒申 129
+ 鐃緒申 130 (defun lm-code-mark ()
+ 鐃緒申 131 ;; Return the buffer location of the code start marker
+ 鐃緒申 132 (lm-section-mark "Code"))
+ 鐃緒申 133
+ 鐃緒申 134 (defun lm-header (hd)
+ 鐃緒申 135 ;; Return the contents of a named header
+ 鐃緒申 136 (goto-char (point-min))
+ 鐃緒申 137 (let ((case-fold-search t))
+ 鐃緒申 138 (if (re-search-forward
+ 鐃緒申 139 (concat "^;; " hd ": \\(.*\\)") (lm-code-mark) t)
+ 鐃緒申 140 (buffer-substring (match-beginning 1) (match-end 1))
+ 鐃緒申 141 nil)))
+ 鐃緒申 142
+ 鐃緒申 143 (defun lm-header-multiline (hd)
+ 鐃緒申 144 ;; Return the contents of a named header, with possible continuation lines.
+ 鐃緒申 145 ;; Note -- the returned value is a list of strings, one per line.
+ 鐃緒申 146 (save-excursion
+ 鐃緒申 147 (goto-char (point-min))
+ 鐃緒申 148 (let ((res (save-excursion (lm-header hd))))
+ 鐃緒申 149 (if res
+ 鐃緒申 150 (progn
+ 鐃緒申 151 (forward-line 1)
+ 鐃緒申 152 (setq res (list res))
+ 鐃緒申 153 (while (looking-at "^;;\t\\(.*\\)")
+ 鐃緒申 154 (setq res (cons (buffer-substring
+ 鐃緒申 155 (match-beginning 1)
+ 鐃緒申 156 (match-end 1))
+ 鐃緒申 157 res))
+ 鐃緒申 158 (forward-line 1))
+ 鐃緒申 159 ))
+ 鐃緒申 160 res)))
+ 鐃緒申 161
+ 鐃緒申 162 ;; These give us smart access to the header fields and commentary
+ 鐃緒申 163
+ 鐃緒申 164 (defun lm-summary (&optional file)
+ 鐃緒申 165 ;; Return the buffer's or FILE's one-line summary.
+ 鐃緒申 166 (save-excursion
+ 鐃緒申 167 (if file
+ 鐃緒申 168 (find-file file))
+ 鐃緒申 169 (goto-char (point-min))
+ 鐃緒申 170 (prog1
+ 鐃緒申 171 (if (looking-at "^;;; [^ ]+ --- \\(.*\\)")
+ 鐃緒申 172 (buffer-substring (match-beginning 1) (match-end 1)))
+ 鐃緒申 173 (if file
+ 鐃緒申 174 (kill-buffer (current-buffer)))
+ 鐃緒申 175 )))
+ 鐃緒申 176
+ 鐃緒申 177 (defun lm-authors (&optional file)
+ 鐃緒申 178 ;; Return the buffer's or FILE's author list.
+ 鐃緒申 179 (save-excursion
+ 鐃緒申 180 (if file
+ 鐃緒申 181 (find-file file))
+ 鐃緒申 182 (prog1
+ 鐃緒申 183 (lm-header-multiline "author")
+ 鐃緒申 184 (if file
+ 鐃緒申 185 (kill-buffer (current-buffer)))
+ 鐃緒申 186 )))
+ 鐃緒申 187
+ 鐃緒申 188 (defun lm-maintainer (&optional file)
+ 鐃緒申 189 ;; Get a package's bug-report & maintenance address. Parse it out of FILE,
+ 鐃緒申 190 ;; or the current buffer if FILE is nil.
+ 鐃緒申 191 ;; This may be a name-address pair, or an address by itself,
+ 鐃緒申 192 (save-excursion
+ 鐃緒申 193 (if file
+ 鐃緒申 194 (find-file file))
+ 鐃緒申 195 (prog1
+ 鐃緒申 196 (let ((raw-address
+ 鐃緒申 197 (or
+ 鐃緒申 198 (save-excursion (lm-header "maintainer"))
+ 鐃緒申 199 (car (lm-authors)))))
+ 鐃緒申 200 (cond ((string-match "[^<]<\\([^>]+\\)>" raw-address)
+ 鐃緒申 201 (substring raw-address (match-beginning 1) (match-end 1)))
+ 鐃緒申 202 (t raw-address))
+ 鐃緒申 203 )
+ 鐃緒申 204 (if file
+ 鐃緒申 205 (kill-buffer (current-buffer)))
+ 鐃緒申 206 )))
+ 鐃緒申 207
+ 鐃緒申 208 (defun lm-creation-date (&optional file)
+ 鐃緒申 209 ;; Return a package's creation date, if any. Parse it out of FILE,
+ 鐃緒申 210 ;; or the current buffer if FILE is nil.
+ 鐃緒申 211 (save-excursion
+ 鐃緒申 212 (if file
+ 鐃緒申 213 (find-file file))
+ 鐃緒申 214 (prog1
+ 鐃緒申 215 (lm-header "created")
+ 鐃緒申 216 (if file
+ 鐃緒申 217 (kill-buffer (current-buffer)))
+ 鐃緒申 218 )))
+ 鐃緒申 219
+ 鐃緒申 220
+ 鐃緒申 221 (defun lm-last-modified-date (&optional file)
+ 鐃緒申 222 ;; Return a package's last-modified date, if you can find one.
+ 鐃緒申 223 (save-excursion
+ 鐃緒申 224 (if file
+ 鐃緒申 225 (find-file file))
+ 鐃緒申 226 (prog1
+ 鐃緒申 227 (if (progn
+ 鐃緒申 228 (goto-char (point-min))
+ 鐃緒申 229 (re-search-forward
+ 鐃緒申 230 "\\$Id: [^ ]+ [^ ]+ \\([^/]+\\)/\\([^/]+\\)/\\([^ ]+\\) "
+ 鐃緒申 231 (lm-code-mark) t))
+ 鐃緒申 232 (format "%s %s %s"
+ 鐃緒申 233 (buffer-substring (match-beginning 3) (match-end 3))
+ 鐃緒申 234 (nth (string-to-int
+ 鐃緒申 235 (buffer-substring (match-beginning 2) (match-end 2)))
+ 鐃緒申 236 '("" "Jan" "Feb" "Mar" "Apr" "May" "Jun"
+ 鐃緒申 237 "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"))
+ 鐃緒申 238 (buffer-substring (match-beginning 1) (match-end 1))
+ 鐃緒申 239 )))
+ 鐃緒申 240 (if file
+ 鐃緒申 241 (kill-buffer (current-buffer)))
+ 鐃緒申 242 ))
+ 鐃緒申 243
+ 鐃緒申 244 (defun lm-version (&optional file)
+ 鐃緒申 245 ;; Return the package's version field.
+ 鐃緒申 246 ;; If none, look for an RCS or SCCS header to crack it out of.
+ 鐃緒申 247 (save-excursion
+ 鐃緒申 248 (if file
+ 鐃緒申 249 (find-file file))
+ 鐃緒申 250 (prog1
+ 鐃緒申 251 (or
+ 鐃緒申 252 (lm-header "version")
+ 鐃緒申 253 (let ((header-max (lm-code-mark)))
+ 鐃緒申 254 (goto-char (point-min))
+ 鐃緒申 255 (cond
+ 鐃緒申 256 ;; Look for an RCS header
+ 鐃緒申 257 ((re-search-forward "\\$Id: [^ ]+ \\([^ ]+\\) " header-max t)
+ 鐃緒申 258 (buffer-substring (match-beginning 1) (match-end 1)))
+ 鐃緒申 259
+ 鐃緒申 260 ;; Look for an SCCS header
+ 鐃緒申 261 ((re-search-forward
+ 鐃緒申 262 (concat
+ 鐃緒申 263 (regexp-quote "@(#)")
+ 鐃緒申 264 (regexp-quote (file-name-nondirectory (buffer-file-name)))
+ 鐃緒申 265 "\t\\([012345679.]*\\)")
+ 鐃緒申 266 header-max t)
+ 鐃緒申 267 (buffer-substring (match-beginning 1) (match-end 1)))
+ 鐃緒申 268
+ 鐃緒申 269 (t nil))))
+ 鐃緒申 270 (if file
+ 鐃緒申 271 (kill-buffer (current-buffer)))
+ 鐃緒申 272 )))
+ 鐃緒申 273
+ 鐃緒申 274 (defun lm-keywords (&optional file)
+ 鐃緒申 275 ;; Return the header containing the package's topic keywords.
+ 鐃緒申 276 ;; Parse them out of FILE, or the current buffer if FILE is nil.
+ 鐃緒申 277 (save-excursion
+ 鐃緒申 278 (if file
+ 鐃緒申 279 (find-file file))
+ 鐃緒申 280 (prog1
+ 鐃緒申 281 (let ((keywords (lm-header "keywords")))
+ 鐃緒申 282 (and keywords (downcase keywords)))
+ 鐃緒申 283 (if file
+ 鐃緒申 284 (kill-buffer (current-buffer)))
+ 鐃緒申 285 )))
+ 鐃緒申 286
+ 鐃緒申 287 (defun lm-adapted-by (&optional file)
+ 鐃緒申 288 ;; Return the name or code of the person who cleaned up this package
+ 鐃緒申 289 ;; for distribution. Parse it out of FILE, or the current buffer if
+ 鐃緒申 290 ;; FILE is nil.
+ 鐃緒申 291 (save-excursion
+ 鐃緒申 292 (if file
+ 鐃緒申 293 (find-file file))
+ 鐃緒申 294 (prog1
+ 鐃緒申 295 (lm-header "adapted-by")
+ 鐃緒申 296 (if file
+ 鐃緒申 297 (kill-buffer (current-buffer)))
+ 鐃緒申 298 )))
+ 鐃緒申 299
+ 鐃緒申 300 (defun lm-commentary-region (&optional file)
+ 鐃緒申 301 ;; Return a pair of character locations enclosing the commentary region.
+ 鐃緒申 302 (save-excursion
+ 鐃緒申 303 (if file
+ 鐃緒申 304 (find-file file))
+ 鐃緒申 305 (prog1
+ 鐃緒申 306 (let ((commentary (lm-section-mark "Commentary"))
+ 鐃緒申 307 (change-log (lm-section-mark "Change Log"))
+ 鐃緒申 308 (code (lm-section-mark "Code")))
+ 鐃緒申 309 (if commentary
+ 鐃緒申 310 (if change-log
+ 鐃緒申 311 (cons commentary change-log)
+ 鐃緒申 312 (cons commentary code)))
+ 鐃緒申 313 )
+ 鐃緒申 314 (if file
+ 鐃緒申 315 (kill-buffer (current-buffer)))
+ 鐃緒申 316 )))
+ 鐃緒申 317
+ 鐃緒申 318 ;;; Verification and synopses
+ 鐃緒申 319
+ 鐃緒申 320 (defun insert-at-column (col &rest pieces)
+ 鐃緒申 321 (if (> (current-column) col) (insert "\n"))
+ 鐃緒申 322 (move-to-column-force col)
+ 鐃緒申 323 (apply 'insert pieces))
+ 鐃緒申 324
+ 鐃緒申 325 (defconst lm-comment-column 16)
+ 鐃緒申 326
+ 鐃緒申 327 (defun lm-verify (&optional file showok)
+ 鐃緒申 328 "Check that the current buffer (or FILE if given) is in proper format.
+ 鐃緒申 329 If FILE is a directory, recurse on its files and generate a report into
+ 鐃緒申 330 a temporary buffer."
+ 鐃緒申 331 (if (and file (file-directory-p file))
+ 鐃緒申 332 (progn
+ 鐃緒申 333 (switch-to-buffer (get-buffer-create "*lm-verify*"))
+ 鐃緒申 334 (erase-buffer)
+ 鐃緒申 335 (mapcar
+ 鐃緒申 336 '(lambda (f)
+ 鐃緒申 337 (if (string-match ".*\\.el$" f)
+ 鐃緒申 338 (let ((status (lm-verify f)))
+ 鐃緒申 339 (if status
+ 鐃緒申 340 (progn
+ 鐃緒申 341 (insert f ":")
+ 鐃緒申 342 (insert-at-column lm-comment-column status "\n"))
+ 鐃緒申 343 (and showok
+ 鐃緒申 344 (progn
+ 鐃緒申 345 (insert f ":")
+ 鐃緒申 346 (insert-at-column lm-comment-column "OK\n")))))))
+ 鐃緒申 347 (directory-files file))
+ 鐃緒申 348 )
+ 鐃緒申 349 (save-excursion
+ 鐃緒申 350 (if file
+ 鐃緒申 351 (find-file file))
+ 鐃緒申 352 (prog1
+ 鐃緒申 353 (cond
+ 鐃緒申 354 ((not (lm-summary))
+ 鐃緒申 355 "Can't find a package summary")
+ 鐃緒申 356 ((not (lm-code-mark))
+ 鐃緒申 357 "Can't find a code section marker")
+ 鐃緒申 358 ((progn
+ 鐃緒申 359 (goto-char (point-max))
+ 鐃緒申 360 (forward-line -1)
+ 鐃緒申 361 (looking-at (concat ";;; " file "ends here")))
+ 鐃緒申 362 "Can't find a footer line")
+ 鐃緒申 363 )
+ 鐃緒申 364 (if file
+ 鐃緒申 365 (kill-buffer (current-buffer)))
+ 鐃緒申 366 ))))
+ 鐃緒申 367
+ 鐃緒申 368 (defun lm-synopsis (&optional file showall)
+ 鐃緒申 369 "Generate a synopsis listing for the buffer or the given FILE if given.
+ 鐃緒申 370 If FILE is a directory, recurse on its files and generate a report into
+ 鐃緒申 371 a temporary buffer. If SHOWALL is on, also generate a line for files
+ 鐃緒申 372 which do not include a recognizable synopsis."
+ 鐃緒申 373 (if (and file (file-directory-p file))
+ 鐃緒申 374 (progn
+ 鐃緒申 375 (switch-to-buffer (get-buffer-create "*lm-verify*"))
+ 鐃緒申 376 (erase-buffer)
+ 鐃緒申 377 (mapcar
+ 鐃緒申 378 '(lambda (f)
+ 鐃緒申 379 (if (string-match ".*\\.el$" f)
+ 鐃緒申 380 (let ((syn (lm-synopsis f)))
+ 鐃緒申 381 (if syn
+ 鐃緒申 382 (progn
+ 鐃緒申 383 (insert f ":")
+ 鐃緒申 384 (insert-at-column lm-comment-column syn "\n"))
+ 鐃緒申 385 (and showall
+ 鐃緒申 386 (progn
+ 鐃緒申 387 (insert f ":")
+ 鐃緒申 388 (insert-at-column lm-comment-column "NA\n")))))))
+ 鐃緒申 389 (directory-files file))
+ 鐃緒申 390 )
+ 鐃緒申 391 (save-excursion
+ 鐃緒申 392 (if file
+ 鐃緒申 393 (find-file file))
+ 鐃緒申 394 (prog1
+ 鐃緒申 395 (lm-summary)
+ 鐃緒申 396 (if file
+ 鐃緒申 397 (kill-buffer (current-buffer)))
+ 鐃緒申 398 ))))
+ 鐃緒申 399
+ 鐃緒申 400 (defun lm-report-bug (topic)
+ 鐃緒申 401 "Report a bug in the package currently being visited to its maintainer.
+ 鐃緒申 402 Prompts for bug subject. Leaves you in a mail buffer."
+ 鐃緒申 403 (let ((package (buffer-name))
+ 鐃緒申 404 (addr (lm-maintainer))
+ 鐃緒申 405 (version (lm-version)))
+ 鐃緒申 406 ;; We do this in order to avoid duplicating the general bug address here
+ 鐃緒申 407 (if (or (not addr) (string= "FSF"))
+ 鐃緒申 408 (progn
+ 鐃緒申 409 (load-library "emacsbug.el")
+ 鐃緒申 410 (emacsbug (format "%s --- %s" package topic))))
+ 鐃緒申 411 (interactive "sBug Subject: ")
+ 鐃緒申 412 (mail nil addr topic)
+ 鐃緒申 413 (goto-char (point-max))
+ 鐃緒申 414 (insert "\nIn "
+ 鐃緒申 415 package
+ 鐃緒申 416 (and version (concat " version " version))
+ 鐃緒申 417 "\n\n")
+ 鐃緒申 418 (message
+ 鐃緒申 419 (substitute-command-keys "Type \\[mail-send] to send bug report."))))
+ 鐃緒申 420
+ 鐃緒申 421 (provide 'lisp-mnt)
+ 鐃緒申 422
+ 鐃緒申 423 ;;; lisp-mnt.el ends here