73 |
will be recognized as referring to the same user; when creating a new |
will be recognized as referring to the same user; when creating a new |
74 |
ChangeLog entry, one element will be chosen at random." |
ChangeLog entry, one element will be chosen at random." |
75 |
:type '(choice (const :tag "Default" nil) |
:type '(choice (const :tag "Default" nil) |
76 |
(repeat string)) |
(string :tag "String") |
77 |
|
(repeat :tag "List of Strings" string)) |
78 |
:group 'change-log) |
:group 'change-log) |
79 |
|
|
80 |
(defcustom add-log-time-format 'add-log-iso8601-time-string |
(defcustom add-log-time-format 'add-log-iso8601-time-string |
464 |
(item (add-log-file-name buffer-file file-name)) |
(item (add-log-file-name buffer-file file-name)) |
465 |
bound) |
bound) |
466 |
|
|
467 |
(if (or (and other-window (not (equal file-name buffer-file-name))) |
(unless (equal file-name buffer-file-name) |
468 |
(window-dedicated-p (selected-window))) |
(if (or other-window (window-dedicated-p (selected-window))) |
469 |
(find-file-other-window file-name) |
(find-file-other-window file-name) |
470 |
(find-file file-name)) |
(find-file file-name))) |
471 |
(or (eq major-mode 'change-log-mode) |
(or (eq major-mode 'change-log-mode) |
472 |
(change-log-mode)) |
(change-log-mode)) |
473 |
(undo-boundary) |
(undo-boundary) |
545 |
;; Now insert the function name, if we have one. |
;; Now insert the function name, if we have one. |
546 |
;; Point is at the item for this file, |
;; Point is at the item for this file, |
547 |
;; either at the end of the line or at the first blank line. |
;; either at the end of the line or at the first blank line. |
548 |
(if defun |
(if (not defun) |
549 |
(progn |
;; No function name, so put in a colon unless we have just a star. |
550 |
;; Make it easy to get rid of the function name. |
(unless (save-excursion |
551 |
(undo-boundary) |
(beginning-of-line 1) |
552 |
(unless (save-excursion |
(looking-at "\\s *\\(\\*\\s *\\)?$")) |
553 |
(beginning-of-line 1) |
(insert ": ") |
554 |
(looking-at "\\s *$")) |
(if version (insert version ?\ ))) |
555 |
(insert ?\ )) |
;; Make it easy to get rid of the function name. |
556 |
;; See if the prev function name has a message yet or not. |
(undo-boundary) |
|
;; If not, merge the two items. |
|
|
(let ((pos (point-marker))) |
|
|
(if (and (skip-syntax-backward " ") |
|
|
(skip-chars-backward "):") |
|
|
(looking-at "):") |
|
|
(progn (delete-region (+ 1 (point)) (+ 2 (point))) t) |
|
|
(> fill-column (+ (current-column) (length defun) 3))) |
|
|
(progn (delete-region (point) pos) |
|
|
(insert ", ")) |
|
|
(goto-char pos) |
|
|
(insert "(")) |
|
|
(set-marker pos nil)) |
|
|
(insert defun "): ") |
|
|
(if version |
|
|
(insert version ?\ ))) |
|
|
;; No function name, so put in a colon unless we have just a star. |
|
557 |
(unless (save-excursion |
(unless (save-excursion |
558 |
(beginning-of-line 1) |
(beginning-of-line 1) |
559 |
(looking-at "\\s *\\(\\*\\s *\\)?$")) |
(looking-at "\\s *$")) |
560 |
(insert ": ") |
(insert ?\ )) |
561 |
(if version (insert version ?\ )))))) |
;; See if the prev function name has a message yet or not. |
562 |
|
;; If not, merge the two items. |
563 |
|
(let ((pos (point-marker))) |
564 |
|
(skip-syntax-backward " ") |
565 |
|
(skip-chars-backward "):") |
566 |
|
(if (and (looking-at "):") |
567 |
|
(> fill-column (+ (current-column) (length defun) 4))) |
568 |
|
(progn (delete-region (point) pos) (insert ", ")) |
569 |
|
(if (looking-at "):") |
570 |
|
(delete-region (+ 1 (point)) (line-end-position))) |
571 |
|
(goto-char pos) |
572 |
|
(insert "(")) |
573 |
|
(set-marker pos nil)) |
574 |
|
(insert defun "): ") |
575 |
|
(if version (insert version ?\ ))))) |
576 |
|
|
577 |
;;;###autoload |
;;;###autoload |
578 |
(defun add-change-log-entry-other-window (&optional whoami file-name) |
(defun add-change-log-entry-other-window (&optional whoami file-name) |
586 |
;;;###autoload (define-key ctl-x-4-map "a" 'add-change-log-entry-other-window) |
;;;###autoload (define-key ctl-x-4-map "a" 'add-change-log-entry-other-window) |
587 |
|
|
588 |
;;;###autoload |
;;;###autoload |
589 |
(defun change-log-mode () |
(define-derived-mode change-log-mode text-mode "Change Log" |
590 |
"Major mode for editing change logs; like Indented Text Mode. |
"Major mode for editing change logs; like Indented Text Mode. |
591 |
Prevents numeric backups and sets `left-margin' to 8 and `fill-column' to 74. |
Prevents numeric backups and sets `left-margin' to 8 and `fill-column' to 74. |
592 |
New log entries are usually made with \\[add-change-log-entry] or \\[add-change-log-entry-other-window]. |
New log entries are usually made with \\[add-change-log-entry] or \\[add-change-log-entry-other-window]. |
593 |
Each entry behaves as a paragraph, and the entries for one day as a page. |
Each entry behaves as a paragraph, and the entries for one day as a page. |
594 |
Runs `change-log-mode-hook'." |
Runs `change-log-mode-hook'." |
595 |
(interactive) |
(setq left-margin 8 |
|
(kill-all-local-variables) |
|
|
(indented-text-mode) |
|
|
(setq major-mode 'change-log-mode |
|
|
mode-name "Change Log" |
|
|
left-margin 8 |
|
596 |
fill-column 74 |
fill-column 74 |
597 |
indent-tabs-mode t |
indent-tabs-mode t |
598 |
tab-width 8) |
tab-width 8) |
|
(use-local-map change-log-mode-map) |
|
599 |
(set (make-local-variable 'fill-paragraph-function) |
(set (make-local-variable 'fill-paragraph-function) |
600 |
'change-log-fill-paragraph) |
'change-log-fill-paragraph) |
601 |
|
(set (make-local-variable 'indent-line-function) 'indent-to-left-margin) |
602 |
;; We really do want "^" in paragraph-start below: it is only the |
;; We really do want "^" in paragraph-start below: it is only the |
603 |
;; lines that begin at column 0 (despite the left-margin of 8) that |
;; lines that begin at column 0 (despite the left-margin of 8) that |
604 |
;; we are looking for. Adding `* ' allows eliding the blank line |
;; we are looking for. Adding `* ' allows eliding the blank line |
609 |
;; is grouped with what follows. |
;; is grouped with what follows. |
610 |
(set (make-local-variable 'page-delimiter) "^\\<\\|^\f") |
(set (make-local-variable 'page-delimiter) "^\\<\\|^\f") |
611 |
(set (make-local-variable 'version-control) 'never) |
(set (make-local-variable 'version-control) 'never) |
612 |
|
(set (make-local-variable 'smerge-resolve-function) |
613 |
|
'change-log-resolve-conflict) |
614 |
(set (make-local-variable 'adaptive-fill-regexp) "\\s *") |
(set (make-local-variable 'adaptive-fill-regexp) "\\s *") |
615 |
(set (make-local-variable 'font-lock-defaults) |
(set (make-local-variable 'font-lock-defaults) |
616 |
'(change-log-font-lock-keywords t nil nil backward-paragraph)) |
'(change-log-font-lock-keywords t nil nil backward-paragraph))) |
|
(run-hooks 'change-log-mode-hook)) |
|
617 |
|
|
618 |
;; It might be nice to have a general feature to replace this. The idea I |
;; It might be nice to have a general feature to replace this. The idea I |
619 |
;; have is a variable giving a regexp matching text which should not be |
;; have is a variable giving a regexp matching text which should not be |
661 |
point for uppercase headings starting in the first column or |
point for uppercase headings starting in the first column or |
662 |
identifiers followed by `:' or `='. See variables |
identifiers followed by `:' or `='. See variables |
663 |
`add-log-current-defun-header-regexp' and |
`add-log-current-defun-header-regexp' and |
664 |
`add-log-current-defun-function' |
`add-log-current-defun-function'. |
665 |
|
|
666 |
Has a preference of looking backwards." |
Has a preference of looking backwards." |
667 |
(condition-case nil |
(condition-case nil |
827 |
(if (re-search-backward "^@node[ \t]+\\([^,\n]+\\)" nil t) |
(if (re-search-backward "^@node[ \t]+\\([^,\n]+\\)" nil t) |
828 |
(match-string-no-properties 1))) |
(match-string-no-properties 1))) |
829 |
((memq major-mode '(perl-mode cperl-mode)) |
((memq major-mode '(perl-mode cperl-mode)) |
830 |
(if (re-search-backward "^sub[ \t]+\\([^ \t\n]+\\)" nil t) |
(if (re-search-backward "^sub[ \t]+\\([^({ \t\n]+\\)" nil t) |
831 |
(match-string-no-properties 1))) |
(match-string-no-properties 1))) |
832 |
;; Emacs's autoconf-mode installs its own |
;; Emacs's autoconf-mode installs its own |
833 |
;; `add-log-current-defun-function'. This applies to |
;; `add-log-current-defun-function'. This applies to |
898 |
(error nil))))) |
(error nil))))) |
899 |
(error "Bad date"))) |
(error "Bad date"))) |
900 |
|
|
901 |
|
(defun change-log-resolve-conflict () |
902 |
|
"Function to be used in `smerge-resolve-function'." |
903 |
|
(let ((buf (current-buffer))) |
904 |
|
(with-temp-buffer |
905 |
|
(insert-buffer-substring buf (match-beginning 1) (match-end 1)) |
906 |
|
(save-match-data (change-log-mode)) |
907 |
|
(let ((other-buf (current-buffer))) |
908 |
|
(with-current-buffer buf |
909 |
|
(save-excursion |
910 |
|
(save-restriction |
911 |
|
(narrow-to-region (match-beginning 0) (match-end 0)) |
912 |
|
(replace-match (match-string 3) t t) |
913 |
|
(change-log-merge other-buf)))))))) |
914 |
|
|
915 |
;;;###autoload |
;;;###autoload |
916 |
(defun change-log-merge (other-log) |
(defun change-log-merge (other-log) |
917 |
"Merge the contents of ChangeLog file OTHER-LOG with this buffer. |
"Merge the contents of ChangeLog file OTHER-LOG with this buffer. |
918 |
Both must be found in Change Log mode (since the merging depends on |
Both must be found in Change Log mode (since the merging depends on |
919 |
the appropriate motion commands). |
the appropriate motion commands). OTHER-LOG can be either a file name |
920 |
|
or a buffer. |
921 |
|
|
922 |
Entries are inserted in chronological order. Both the current and |
Entries are inserted in chronological order. Both the current and |
923 |
old-style time formats for entries are supported." |
old-style time formats for entries are supported." |
924 |
(interactive "*fLog file name to merge: ") |
(interactive "*fLog file name to merge: ") |
925 |
(if (not (eq major-mode 'change-log-mode)) |
(if (not (eq major-mode 'change-log-mode)) |
926 |
(error "Not in Change Log mode")) |
(error "Not in Change Log mode")) |
927 |
(let ((other-buf (find-file-noselect other-log)) |
(let ((other-buf (if (bufferp other-log) other-log |
928 |
|
(find-file-noselect other-log))) |
929 |
(buf (current-buffer)) |
(buf (current-buffer)) |
930 |
date1 start end) |
date1 start end) |
931 |
(save-excursion |
(save-excursion |
948 |
(insert-buffer-substring other-buf start end) |
(insert-buffer-substring other-buf start end) |
949 |
;; At the end of the original buffer, insert a newline to |
;; At the end of the original buffer, insert a newline to |
950 |
;; separate entries and then the rest of the file being |
;; separate entries and then the rest of the file being |
951 |
;; merged. Move to the end of it to terminate outer loop. |
;; merged. |
952 |
(insert "\n") |
(unless (or (bobp) |
953 |
(insert-buffer-substring other-buf start |
(and (= ?\n (char-before)) |
954 |
(with-current-buffer other-buf |
(or (<= (1- (point)) (point-min)) |
955 |
(goto-char (point-max)) |
(= ?\n (char-before (1- (point))))))) |
956 |
(point))))))))) |
(insert "\n")) |
957 |
|
;; Move to the end of it to terminate outer loop. |
958 |
|
(with-current-buffer other-buf |
959 |
|
(goto-char (point-max))) |
960 |
|
(insert-buffer-substring other-buf start))))))) |
961 |
|
|
962 |
;;;###autoload |
;;;###autoload |
963 |
(defun change-log-redate () |
(defun change-log-redate () |