comparison lisp/packages/add-log.el @ 151:59463afc5666 r20-3b2

Import from CVS: tag r20-3b2
author cvs
date Mon, 13 Aug 2007 09:37:19 +0200
parents cca96a509cfe
children 28f395d8dc7a
comparison
equal deleted inserted replaced
150:8ebb1c0f0f6f 151:59463afc5666
1 ;;; add-log.el --- change log maintenance commands for Emacs 1 ;;; add-log.el --- change log maintenance commands for Emacs
2 2
3 ;; Copyright (C) 1985, 1986, 1988, 1993, 1994 Free Software Foundation, Inc. 3 ;; Copyright (C) 1985, 86, 88, 93, 94, 1997 Free Software Foundation, Inc.
4 4
5 ;; Keywords: maint 5 ;; Keywords: maint
6 6
7 ;; This file is part of XEmacs. 7 ;; This file is part of XEmacs.
8 8
19 ;; You should have received a copy of the GNU General Public License 19 ;; You should have received a copy of the GNU General Public License
20 ;; along with XEmacs; see the file COPYING. If not, write to the 20 ;; along with XEmacs; see the file COPYING. If not, write to the
21 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 21 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA. 22 ;; Boston, MA 02111-1307, USA.
23 23
24 ;;; Synched up with: FSF 19.34. 24 ;;; Synched up with: Emacs 20.0.
25 25
26 ;;; Commentary: 26 ;;; Commentary:
27 27
28 ;; This facility is documented in the Emacs Manual. 28 ;; This facility is documented in the Emacs Manual.
29 29
58 This defaults to the value returned by the `user-full-name' function." 58 This defaults to the value returned by the `user-full-name' function."
59 :type '(choice (const :tag "Default" nil) 59 :type '(choice (const :tag "Default" nil)
60 string) 60 string)
61 :group 'change-log) 61 :group 'change-log)
62 62
63 ;; XEmacs;
63 ;; So that the dump-time value doesn't go into loaddefs.el with the autoload. 64 ;; So that the dump-time value doesn't go into loaddefs.el with the autoload.
64 (or add-log-full-name (setq add-log-full-name (user-full-name))) 65 (or add-log-full-name (setq add-log-full-name (user-full-name)))
65 66
66 ;;;###autoload 67 ;;;###autoload
67 (defcustom add-log-mailing-address nil 68 (defcustom add-log-mailing-address nil
69 This defaults to the value of `user-mail-address'." 70 This defaults to the value of `user-mail-address'."
70 :type '(choice (const :tag "Default" nil) 71 :type '(choice (const :tag "Default" nil)
71 string) 72 string)
72 :group 'change-log) 73 :group 'change-log)
73 74
75 ;; XEmacs:
74 ;; So that the dump-time value doesn't go into loaddefs.el with the autoload. 76 ;; So that the dump-time value doesn't go into loaddefs.el with the autoload.
75 (or add-log-mailing-address 77 (or add-log-mailing-address
76 (setq add-log-mailing-address (user-mail-address))) 78 (setq add-log-mailing-address (user-mail-address)))
77 79
78 (defvar change-log-font-lock-keywords 80 (defvar change-log-font-lock-keywords
79 '(("^[SMTWF].+" . font-lock-function-name-face) ; Date line. 81 '(;;
80 ("^\t\\* \\([^ :\n]+\\)" 1 font-lock-comment-face) ; File name. 82 ;; Date lines, new and old styles.
81 ("(\\([^)\n]+\\)):" 1 font-lock-keyword-face)) ; Function name. 83 ("^\\sw.........[0-9: ]*"
84 (0 font-lock-string-face)
85 ("\\([^<]+\\)<\\([A-Za-z0-9_.-]+@[A-Za-z0-9_.-]+\\)>" nil nil
86 (1 font-lock-reference-face)
87 (2 font-lock-variable-name-face)))
88 ;;
89 ;; File names.
90 ("^\t\\* \\([^ ,:([\n]+\\)"
91 (1 font-lock-function-name-face)
92 ("\\=, \\([^ ,:([\n]+\\)" nil nil (1 font-lock-function-name-face)))
93 ;;
94 ;; Function or variable names.
95 ("(\\([^ ,:\n]+\\)"
96 (1 font-lock-keyword-face)
97 ("\\=, \\([^ ,:\n]+\\)" nil nil (1 font-lock-keyword-face)))
98 ;;
99 ;; Conditionals.
100 ("\\[!?\\([^]\n]+\\)\\]\\(:\\| (\\)" (1 font-lock-variable-name-face))
101 ;;
102 ;; Acknowledgments.
103 ("^\t\\(From\\|Reported by\\)" 1 font-lock-comment-face)
104 )
82 "Additional expressions to highlight in Change Log mode.") 105 "Additional expressions to highlight in Change Log mode.")
83 (put 'change-log-mode 'font-lock-defaults 106 (put 'change-log-mode 'font-lock-defaults
84 '(change-log-font-lock-keywords t)) 107 '(change-log-font-lock-keywords t))
85 108
86 (defvar change-log-mode-map nil 109 (defvar change-log-mode-map nil
87 "Keymap for Change Log major mode.") 110 "Keymap for Change Log major mode.")
88 (if change-log-mode-map 111 (if change-log-mode-map
89 nil 112 nil
90 (setq change-log-mode-map (make-sparse-keymap)) 113 (setq change-log-mode-map (make-sparse-keymap)))
91 (define-key change-log-mode-map "\M-q" 'change-log-fill-paragraph)) 114
115 (defvar change-log-time-zone-rule nil
116 "Time zone used for calculating change log time stamps.
117 It takes the same format as the TZ argument of `set-time-zone-rule'.
118 If nil, use local time.")
119
120 (defun iso8601-time-zone (time)
121 (let* ((utc-offset (or (car (current-time-zone time)) 0))
122 (sign (if (< utc-offset 0) ?- ?+))
123 (sec (abs utc-offset))
124 (ss (% sec 60))
125 (min (/ sec 60))
126 (mm (% min 60))
127 (hh (/ min 60)))
128 (format (cond ((not (zerop ss)) "%c%02d:%02d:%02d")
129 ((not (zerop mm)) "%c%02d:%02d")
130 (t "%c%02d"))
131 sign hh mm ss)))
92 132
93 (defun change-log-name () 133 (defun change-log-name ()
94 (or change-log-default-name 134 (or change-log-default-name
95 (if (eq system-type 'vax-vms) 135 (if (eq system-type 'vax-vms)
96 "$CHANGE_LOG$.TXT" 136 "$CHANGE_LOG$.TXT"
97 (if (or (eq system-type 'ms-dos) (eq system-type 'windows-nt)) 137 "ChangeLog")))
98 "changelo"
99 "ChangeLog"))))
100 138
101 ;;;###autoload 139 ;;;###autoload
102 (defun prompt-for-change-log-name () 140 (defun prompt-for-change-log-name ()
103 "Prompt for a change log name." 141 "Prompt for a change log name."
104 (let* ((default (change-log-name)) 142 (let* ((default (change-log-name))
178 "Find change log file and add an entry for today. 216 "Find change log file and add an entry for today.
179 Optional arg (interactive prefix) non-nil means prompt for user name and site. 217 Optional arg (interactive prefix) non-nil means prompt for user name and site.
180 Second arg is file name of change log. If nil, uses `change-log-default-name'. 218 Second arg is file name of change log. If nil, uses `change-log-default-name'.
181 Third arg OTHER-WINDOW non-nil means visit in other window. 219 Third arg OTHER-WINDOW non-nil means visit in other window.
182 Fourth arg NEW-ENTRY non-nil means always create a new entry at the front; 220 Fourth arg NEW-ENTRY non-nil means always create a new entry at the front;
183 never append to an existing entry." 221 never append to an existing entry. Today's date is calculated according to
222 `change-log-time-zone-rule' if non-nil, otherwise in local time."
184 (interactive (list current-prefix-arg 223 (interactive (list current-prefix-arg
185 (prompt-for-change-log-name))) 224 (prompt-for-change-log-name)))
186 (or add-log-full-name 225 (or add-log-full-name
187 (setq add-log-full-name (user-full-name))) 226 (setq add-log-full-name (user-full-name)))
188 (or add-log-mailing-address 227 (or add-log-mailing-address
218 (find-file file-name)) 257 (find-file file-name))
219 (or (eq major-mode 'change-log-mode) 258 (or (eq major-mode 'change-log-mode)
220 (change-log-mode)) 259 (change-log-mode))
221 (undo-boundary) 260 (undo-boundary)
222 (goto-char (point-min)) 261 (goto-char (point-min))
223 (if (looking-at (concat (regexp-quote (substring (current-time-string) 262 (let ((new-entry (concat (if change-log-time-zone-rule
224 0 10)) 263 (let ((tz (getenv "TZ"))
225 ".* " (regexp-quote add-log-full-name) 264 (now (current-time)))
226 " <" (regexp-quote add-log-mailing-address))) 265 (unwind-protect
227 (forward-line 1) 266 (progn
228 (insert (current-time-string) 267 (set-time-zone-rule
229 " " add-log-full-name 268 change-log-time-zone-rule)
230 " <" add-log-mailing-address ">\n\n")) 269 (concat
270 (format-time-string "%Y-%m-%d " now)
271 (iso8601-time-zone now)))
272 (set-time-zone-rule tz)))
273 (format-time-string "%Y-%m-%d"))
274 " " add-log-full-name
275 " <" add-log-mailing-address ">")))
276 (if (looking-at (regexp-quote new-entry))
277 (forward-line 1)
278 (insert new-entry "\n\n")))
231 279
232 ;; Search only within the first paragraph. 280 ;; Search only within the first paragraph.
233 (if (looking-at "\n*[^\n* \t]") 281 (if (looking-at "\n*[^\n* \t]")
234 (skip-chars-forward "\n") 282 (skip-chars-forward "\n")
235 (forward-paragraph 1)) 283 (forward-paragraph 1))
298 (list current-prefix-arg 346 (list current-prefix-arg
299 (prompt-for-change-log-name)))) 347 (prompt-for-change-log-name))))
300 (add-change-log-entry whoami file-name t)) 348 (add-change-log-entry whoami file-name t))
301 ;;;###autoload (define-key ctl-x-4-map "a" 'add-change-log-entry-other-window) 349 ;;;###autoload (define-key ctl-x-4-map "a" 'add-change-log-entry-other-window)
302 350
303 (defvar change-log-mode-map nil
304 "Keymap for Change Log major mode.")
305 (if change-log-mode-map
306 nil
307 (setq change-log-mode-map (make-sparse-keymap))
308 (set-keymap-name change-log-mode-map 'change-log-mode-map)
309 (define-key change-log-mode-map "\M-q" 'change-log-fill-paragraph))
310
311 ;;;###autoload 351 ;;;###autoload
312 (defun change-log-mode () 352 (defun change-log-mode ()
313 "Major mode for editing change logs; like Indented Text Mode. 353 "Major mode for editing change logs; like Indented Text Mode.
314 Prevents numeric backups and sets `left-margin' to 8 and `fill-column' to 74. 354 Prevents numeric backups and sets `left-margin' to 8 and `fill-column' to 74.
315 New log entries are usually made with \\[add-change-log-entry] or \\[add-change-log-entry-other-window]. 355 New log entries are usually made with \\[add-change-log-entry] or \\[add-change-log-entry-other-window].
323 left-margin 8 363 left-margin 8
324 fill-column 74 364 fill-column 74
325 indent-tabs-mode t 365 indent-tabs-mode t
326 tab-width 8) 366 tab-width 8)
327 (use-local-map change-log-mode-map) 367 (use-local-map change-log-mode-map)
368 (set (make-local-variable 'fill-paragraph-function)
369 'change-log-fill-paragraph)
328 ;; Let each entry behave as one paragraph: 370 ;; Let each entry behave as one paragraph:
329 ;; We really do want "^" in paragraph-start below: it is only the lines that 371 ;; We really do want "^" in paragraph-start below: it is only the lines that
330 ;; begin at column 0 (despite the left-margin of 8) that we are looking for. 372 ;; begin at column 0 (despite the left-margin of 8) that we are looking for.
331 (set (make-local-variable 'paragraph-start) "\\s *$\\|\f\\|^\\sw") 373 (set (make-local-variable 'paragraph-start) "\\s *$\\|\f\\|^\\<")
332 (set (make-local-variable 'paragraph-separate) "\\s *$\\|\f\\|^\\sw") 374 (set (make-local-variable 'paragraph-separate) "\\s *$\\|\f\\|^\\<")
333 ;; Let all entries for one day behave as one page. 375 ;; Let all entries for one day behave as one page.
334 ;; Match null string on the date-line so that the date-line 376 ;; Match null string on the date-line so that the date-line
335 ;; is grouped with what follows. 377 ;; is grouped with what follows.
336 (set (make-local-variable 'page-delimiter) "^\\<\\|^\f") 378 (set (make-local-variable 'page-delimiter) "^\\<\\|^\f")
337 (set (make-local-variable 'version-control) 'never) 379 (set (make-local-variable 'version-control) 'never)
338 (set (make-local-variable 'adaptive-fill-regexp) "\\s *") 380 (set (make-local-variable 'adaptive-fill-regexp) "\\s *")
381 ;;(set (make-local-variable 'font-lock-defaults)
382 ;;'(change-log-font-lock-keywords t))
339 (run-hooks 'change-log-mode-hook)) 383 (run-hooks 'change-log-mode-hook))
340 384
341 ;; It might be nice to have a general feature to replace this. The idea I 385 ;; It might be nice to have a general feature to replace this. The idea I
342 ;; have is a variable giving a regexp matching text which should not be 386 ;; have is a variable giving a regexp matching text which should not be
343 ;; moved from bol by filling. change-log-mode would set this to "^\\s *\\s(". 387 ;; moved from bol by filling. change-log-mode would set this to "^\\s *\\s(".
344 ;; But I don't feel up to implementing that today. 388 ;; But I don't feel up to implementing that today.
345 (defun change-log-fill-paragraph (&optional justify) 389 (defun change-log-fill-paragraph (&optional justify)
346 "Fill the paragraph, but preserve open parentheses at beginning of lines. 390 "Fill the paragraph, but preserve open parentheses at beginning of lines.
347 Prefix arg means justify as well." 391 Prefix arg means justify as well."
348 (interactive "P") 392 (interactive "P")
349 (let ((end (save-excursion (forward-paragraph) (point))) 393 (let ((end (progn (forward-paragraph) (point)))
350 (beg (save-excursion (backward-paragraph)(point))) 394 (beg (progn (backward-paragraph) (point)))
351 (paragraph-start (concat paragraph-start "\\|\\s *\\s("))) 395 (paragraph-start (concat paragraph-start "\\|\\s *\\s(")))
352 (fill-region beg end justify))) 396 (fill-region beg end justify)
397 t))
353 398
354 (defcustom add-log-current-defun-header-regexp 399 (defcustom add-log-current-defun-header-regexp
355 "^\\([A-Z][A-Z_ ]*[A-Z_]\\|[-_a-zA-Z]+\\)[ \t]*[:=]" 400 "^\\([A-Z][A-Z_ ]*[A-Z_]\\|[-_a-zA-Z]+\\)[ \t]*[:=]"
356 "*Heuristic regexp used by `add-log-current-defun' for unknown major modes." 401 "*Heuristic regexp used by `add-log-current-defun' for unknown major modes."
357 :type 'regexp 402 :type 'regexp
358 :group 'change-log) 403 :group 'change-log)
359 404
360 ;;;###autoload 405 ;;;###autoload
406 (defvar add-log-lisp-like-modes
407 '(emacs-lisp-mode lisp-mode scheme-mode lisp-interaction-mode)
408 "*Modes that look like Lisp to `add-log-current-defun'.")
409
410 ;;;###autoload
411 (defvar add-log-c-like-modes
412 '(c-mode c++-mode c++-c-mode objc-mode)
413 "*Modes that look like C to `add-log-current-defun'.")
414
415 ;;;###autoload
416 (defvar add-log-tex-like-modes
417 '(TeX-mode plain-TeX-mode LaTeX-mode plain-tex-mode latex-mode)
418 "*Modes that look like TeX to `add-log-current-defun'.")
419
420 ;;;###autoload
361 (defun add-log-current-defun () 421 (defun add-log-current-defun ()
362 "Return name of function definition point is in, or nil. 422 "Return name of function definition point is in, or nil.
363 423
364 Understands C, Lisp, LaTeX (\"functions\" are chapters, sections, ...), 424 Understands C, Lisp, LaTeX (\"functions\" are chapters, sections, ...),
365 Texinfo (@node titles), Perl, and Fortran. 425 Texinfo (@node titles), Perl, and Fortran.
371 431
372 Has a preference of looking backwards." 432 Has a preference of looking backwards."
373 (condition-case nil 433 (condition-case nil
374 (save-excursion 434 (save-excursion
375 (let ((location (point))) 435 (let ((location (point)))
376 (cond ((memq major-mode '(emacs-lisp-mode lisp-mode scheme-mode 436 (cond ((memq major-mode add-log-lisp-like-modes)
377 lisp-interaction-mode))
378 ;; If we are now precisely at the beginning of a defun, 437 ;; If we are now precisely at the beginning of a defun,
379 ;; make sure beginning-of-defun finds that one 438 ;; make sure beginning-of-defun finds that one
380 ;; rather than the previous one. 439 ;; rather than the previous one.
381 (or (eobp) (forward-char 1)) 440 (or (eobp) (forward-char 1))
382 (beginning-of-defun) 441 (beginning-of-defun)
391 (forward-char 1)) 450 (forward-char 1))
392 (forward-sexp 1) 451 (forward-sexp 1)
393 (skip-chars-forward " '") 452 (skip-chars-forward " '")
394 (buffer-substring (point) 453 (buffer-substring (point)
395 (progn (forward-sexp 1) (point)))))) 454 (progn (forward-sexp 1) (point))))))
396 ((and (memq major-mode '(c-mode c++-mode c++-c-mode objc-mode)) 455 ((and (memq major-mode add-log-c-like-modes)
397 (save-excursion (beginning-of-line) 456 (save-excursion
398 ;; Use eq instead of = here to avoid 457 (beginning-of-line)
399 ;; error when at bob and char-after 458 ;; Use eq instead of = here to avoid
400 ;; returns nil. 459 ;; error when at bob and char-after
401 (while (eq (char-after (- (point) 2)) ?\\) 460 ;; returns nil.
402 (forward-line -1)) 461 (while (eq (char-after (- (point) 2)) ?\\)
403 (looking-at "[ \t]*#[ \t]*define[ \t]"))) 462 (forward-line -1))
463 (looking-at "[ \t]*#[ \t]*define[ \t]")))
404 ;; Handle a C macro definition. 464 ;; Handle a C macro definition.
405 (beginning-of-line) 465 (beginning-of-line)
406 (while (eq (char-after (- (point) 2)) ?\\) ;not =; note above 466 (while (eq (char-after (- (point) 2)) ?\\) ;not =; note above
407 (forward-line -1)) 467 (forward-line -1))
408 (search-forward "define") 468 (search-forward "define")
409 (skip-chars-forward " \t") 469 (skip-chars-forward " \t")
410 (buffer-substring (point) 470 (buffer-substring (point)
411 (progn (forward-sexp 1) (point)))) 471 (progn (forward-sexp 1) (point))))
412 ((memq major-mode '(c-mode c++-mode c++-c-mode objc-mode)) 472 ((memq major-mode add-log-c-like-modes)
413 (beginning-of-line) 473 (beginning-of-line)
414 ;; See if we are in the beginning part of a function, 474 ;; See if we are in the beginning part of a function,
415 ;; before the open brace. If so, advance forward. 475 ;; before the open brace. If so, advance forward.
416 (while (not (looking-at "{\\|\\(\\s *$\\)")) 476 (while (not (looking-at "{\\|\\(\\s *$\\)"))
417 (forward-line 1)) 477 (forward-line 1))
502 (forward-word -1)) 562 (forward-word -1))
503 (and (bolp) 563 (and (bolp)
504 (looking-at "struct \\|union \\|class ") 564 (looking-at "struct \\|union \\|class ")
505 (setq middle (point))) 565 (setq middle (point)))
506 (buffer-substring middle end))))))))) 566 (buffer-substring middle end)))))))))
507 ((memq major-mode 567 ((memq major-mode add-log-tex-like-modes)
508 '(TeX-mode plain-TeX-mode LaTeX-mode;; tex-mode.el
509 plain-tex-mode latex-mode;; cmutex.el
510 ))
511 (if (re-search-backward 568 (if (re-search-backward
512 "\\\\\\(sub\\)*\\(section\\|paragraph\\|chapter\\)" nil t) 569 "\\\\\\(sub\\)*\\(section\\|paragraph\\|chapter\\)" nil t)
513 (progn 570 (progn
514 (goto-char (match-beginning 0)) 571 (goto-char (match-beginning 0))
515 (buffer-substring (1+ (point));; without initial backslash 572 (buffer-substring (1+ (point));; without initial backslash