Mercurial > hg > xemacs-beta
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 |