diff options
| -rw-r--r-- | lisp/add-log.el | 110 |
1 files changed, 86 insertions, 24 deletions
diff --git a/lisp/add-log.el b/lisp/add-log.el index 0b9e907f9af..62b2ef4885f 100644 --- a/lisp/add-log.el +++ b/lisp/add-log.el | |||
| @@ -76,6 +76,30 @@ and `current-time-string' are two valid values." | |||
| 76 | (function :tag "Other")) | 76 | (function :tag "Other")) |
| 77 | :group 'change-log) | 77 | :group 'change-log) |
| 78 | 78 | ||
| 79 | (defcustom add-log-keep-changes-together nil | ||
| 80 | "*If non-nil, then keep changes to the same file together. | ||
| 81 | If this variable is nil and you add log for (e.g.) two files, | ||
| 82 | the change log entries are added cumulatively to the beginning of log. | ||
| 83 | This is the old behaviour: | ||
| 84 | |||
| 85 | Wday Mon DD TIME YYYY | ||
| 86 | |||
| 87 | file A log2 << added this later | ||
| 88 | file B log1 | ||
| 89 | File A log1 | ||
| 90 | |||
| 91 | But if this variable is non-nil, then same file's changes are always kept | ||
| 92 | together. Notice that Log2 has been appended and it is the most recent | ||
| 93 | for file A. | ||
| 94 | |||
| 95 | Wday Mon DD TIME YYYY | ||
| 96 | |||
| 97 | file B log1 | ||
| 98 | File A log1 | ||
| 99 | file A log2 << Added this later" | ||
| 100 | :type 'boolean | ||
| 101 | :group 'change-log) | ||
| 102 | |||
| 79 | (defvar change-log-font-lock-keywords | 103 | (defvar change-log-font-lock-keywords |
| 80 | '(;; | 104 | '(;; |
| 81 | ;; Date lines, new and old styles. | 105 | ;; Date lines, new and old styles. |
| @@ -225,11 +249,25 @@ current buffer to the complete file name." | |||
| 225 | file-name) | 249 | file-name) |
| 226 | 250 | ||
| 227 | 251 | ||
| 252 | |||
| 253 | (defun change-log-add-make-room () | ||
| 254 | "Begin a new empty change log entry at point." | ||
| 255 | ;; Delete excess empty lines; make just 2. | ||
| 256 | ;; | ||
| 257 | (while (and (not (eobp)) (looking-at "^\\s *$")) | ||
| 258 | (delete-region (point) (save-excursion (forward-line 1) (point)))) | ||
| 259 | (insert "\n\n") | ||
| 260 | (forward-line -2) | ||
| 261 | (indent-relative-maybe) | ||
| 262 | ) | ||
| 263 | |||
| 228 | ;;;###autoload | 264 | ;;;###autoload |
| 229 | (defun add-change-log-entry (&optional whoami file-name other-window new-entry) | 265 | (defun add-change-log-entry (&optional whoami file-name other-window new-entry) |
| 230 | "Find change log file and add an entry for today. | 266 | "Find change log file and add an entry for today. |
| 231 | Optional arg (interactive prefix) non-nil means prompt for user name and site. | 267 | Optional arg WHOAMI (interactive prefix) non-nil means prompt for user |
| 232 | Second arg is file name of change log. If nil, uses `change-log-default-name'. | 268 | name and site. |
| 269 | |||
| 270 | Second arg is FILE-NAME of change log. If nil, uses `change-log-default-name'. | ||
| 233 | Third arg OTHER-WINDOW non-nil means visit in other window. | 271 | Third arg OTHER-WINDOW non-nil means visit in other window. |
| 234 | Fourth arg NEW-ENTRY non-nil means always create a new entry at the front; | 272 | Fourth arg NEW-ENTRY non-nil means always create a new entry at the front; |
| 235 | never append to an existing entry. Today's date is calculated according to | 273 | never append to an existing entry. Today's date is calculated according to |
| @@ -251,8 +289,11 @@ never append to an existing entry. Today's date is calculated according to | |||
| 251 | (read-input "Mailing address: " add-log-mailing-address)))) | 289 | (read-input "Mailing address: " add-log-mailing-address)))) |
| 252 | (let ((defun (funcall (or add-log-current-defun-function | 290 | (let ((defun (funcall (or add-log-current-defun-function |
| 253 | 'add-log-current-defun))) | 291 | 'add-log-current-defun))) |
| 254 | paragraph-end entry) | 292 | today-end |
| 293 | paragraph-end | ||
| 294 | entry | ||
| 255 | 295 | ||
| 296 | ) | ||
| 256 | (setq file-name (expand-file-name (find-change-log file-name))) | 297 | (setq file-name (expand-file-name (find-change-log file-name))) |
| 257 | 298 | ||
| 258 | ;; Set ENTRY to the file name to use in the new entry. | 299 | ;; Set ENTRY to the file name to use in the new entry. |
| @@ -287,11 +328,23 @@ never append to an existing entry. Today's date is calculated according to | |||
| 287 | (setq paragraph-end (point)) | 328 | (setq paragraph-end (point)) |
| 288 | (goto-char (point-min)) | 329 | (goto-char (point-min)) |
| 289 | 330 | ||
| 331 | ;; Today page's end point. Used in search boundary | ||
| 332 | |||
| 333 | (save-excursion | ||
| 334 | (goto-char (point-min)) ;Latest change log day | ||
| 335 | (forward-line 1) | ||
| 336 | (setq today-end | ||
| 337 | (if (re-search-forward "^[^ \t\n]" nil t) ;Seek to next day's hdr | ||
| 338 | (match-beginning 0) | ||
| 339 | (point-max)))) ;No next day, use point max | ||
| 340 | |||
| 290 | ;; Now insert the new line for this entry. | 341 | ;; Now insert the new line for this entry. |
| 291 | (cond ((re-search-forward "^\\s *\\*\\s *$" paragraph-end t) | 342 | (cond ((re-search-forward "^\\s *\\*\\s *$" paragraph-end t) |
| 292 | ;; Put this file name into the existing empty entry. | 343 | ;; Put this file name into the existing empty entry. |
| 293 | (if entry | 344 | (if entry |
| 294 | (insert entry))) | 345 | (insert entry)) |
| 346 | ) | ||
| 347 | |||
| 295 | ((and (not new-entry) | 348 | ((and (not new-entry) |
| 296 | (let (case-fold-search) | 349 | (let (case-fold-search) |
| 297 | (re-search-forward | 350 | (re-search-forward |
| @@ -303,12 +356,20 @@ never append to an existing entry. Today's date is calculated according to | |||
| 303 | ;; Add to the existing entry for the same file. | 356 | ;; Add to the existing entry for the same file. |
| 304 | (re-search-forward "^\\s *$\\|^\\s \\*") | 357 | (re-search-forward "^\\s *$\\|^\\s \\*") |
| 305 | (goto-char (match-beginning 0)) | 358 | (goto-char (match-beginning 0)) |
| 306 | ;; Delete excess empty lines; make just 2. | 359 | (change-log-add-make-room) |
| 307 | (while (and (not (eobp)) (looking-at "^\\s *$")) | 360 | ) |
| 308 | (delete-region (point) (save-excursion (forward-line 1) (point)))) | 361 | |
| 309 | (insert "\n\n") | 362 | ;; See if there is existing entry and append to it. |
| 310 | (forward-line -2) | 363 | ;; * file.txt: |
| 311 | (indent-relative-maybe)) | 364 | ;; |
| 365 | ((and add-log-keep-changes-together ;enabled ? | ||
| 366 | (re-search-forward (regexp-quote (concat "* " entry)) | ||
| 367 | today-end t)) | ||
| 368 | (re-search-forward "^\\s *$\\|^\\s \\*") | ||
| 369 | (goto-char (match-beginning 0)) | ||
| 370 | (change-log-add-make-room) | ||
| 371 | ) | ||
| 372 | |||
| 312 | (t | 373 | (t |
| 313 | ;; Make a new entry. | 374 | ;; Make a new entry. |
| 314 | (forward-line 1) | 375 | (forward-line 1) |
| @@ -342,7 +403,8 @@ never append to an existing entry. Today's date is calculated according to | |||
| 342 | ;;;###autoload | 403 | ;;;###autoload |
| 343 | (defun add-change-log-entry-other-window (&optional whoami file-name) | 404 | (defun add-change-log-entry-other-window (&optional whoami file-name) |
| 344 | "Find change log file in other window and add an entry for today. | 405 | "Find change log file in other window and add an entry for today. |
| 345 | Optional arg (interactive prefix) non-nil means prompt for user name and site. | 406 | Optional arg WHOAMI (interactive prefix) non-nil means prompt for user |
| 407 | name and site. | ||
| 346 | Second arg is file name of change log. \ | 408 | Second arg is file name of change log. \ |
| 347 | If nil, uses `change-log-default-name'." | 409 | If nil, uses `change-log-default-name'." |
| 348 | (interactive (if current-prefix-arg | 410 | (interactive (if current-prefix-arg |
| @@ -355,7 +417,7 @@ If nil, uses `change-log-default-name'." | |||
| 355 | (defun change-log-mode () | 417 | (defun change-log-mode () |
| 356 | "Major mode for editing change logs; like Indented Text Mode. | 418 | "Major mode for editing change logs; like Indented Text Mode. |
| 357 | Prevents numeric backups and sets `left-margin' to 8 and `fill-column' to 74. | 419 | Prevents numeric backups and sets `left-margin' to 8 and `fill-column' to 74. |
| 358 | New log entries are usually made with \\[add-change-log-entry] or \\[add-change-log-entry-other-window]. | 420 | New log entries are usually made with \\[add-change-log-entry] or \\[add-change-log-before-other-window]. |
| 359 | Each entry behaves as a paragraph, and the entries for one day as a page. | 421 | Each entry behaves as a paragraph, and the entries for one day as a page. |
| 360 | Runs `change-log-mode-hook'." | 422 | Runs `change-log-mode-hook'." |
| 361 | (interactive) | 423 | (interactive) |
| @@ -515,7 +577,7 @@ Has a preference of looking backwards." | |||
| 515 | (buffer-substring (point) | 577 | (buffer-substring (point) |
| 516 | (progn (forward-sexp 1) (point)))) | 578 | (progn (forward-sexp 1) (point)))) |
| 517 | (if (looking-at "^[+-]") | 579 | (if (looking-at "^[+-]") |
| 518 | (get-method-definition) | 580 | (change-log-get-method-definition) |
| 519 | ;; Ordinary C function syntax. | 581 | ;; Ordinary C function syntax. |
| 520 | (setq beg (point)) | 582 | (setq beg (point)) |
| 521 | (if (and (condition-case nil | 583 | (if (and (condition-case nil |
| @@ -614,33 +676,33 @@ Has a preference of looking backwards." | |||
| 614 | (match-end 1)))))))) | 676 | (match-end 1)))))))) |
| 615 | (error nil))) | 677 | (error nil))) |
| 616 | 678 | ||
| 617 | (defvar get-method-definition-md) | 679 | (defvar change-log-get-method-definition-md) |
| 618 | 680 | ||
| 619 | ;; Subroutine used within get-method-definition. | 681 | ;; Subroutine used within change-log-get-method-definition. |
| 620 | ;; Add the last match in the buffer to the end of `md', | 682 | ;; Add the last match in the buffer to the end of `md', |
| 621 | ;; followed by the string END; move to the end of that match. | 683 | ;; followed by the string END; move to the end of that match. |
| 622 | (defun get-method-definition-1 (end) | 684 | (defun change-log-get-method-definition-1 (end) |
| 623 | (setq get-method-definition-md | 685 | (setq change-log-get-method-definition-md |
| 624 | (concat get-method-definition-md | 686 | (concat change-log-get-method-definition-md |
| 625 | (buffer-substring (match-beginning 1) (match-end 1)) | 687 | (buffer-substring (match-beginning 1) (match-end 1)) |
| 626 | end)) | 688 | end)) |
| 627 | (goto-char (match-end 0))) | 689 | (goto-char (match-end 0))) |
| 628 | 690 | ||
| 629 | ;; For objective C, return the method name if we are in a method. | 691 | ;; For objective C, return the method name if we are in a method. |
| 630 | (defun get-method-definition () | 692 | (defun change-log-get-method-definition () |
| 631 | (let ((get-method-definition-md "[")) | 693 | (let ((change-log-get-method-definition-md "[")) |
| 632 | (save-excursion | 694 | (save-excursion |
| 633 | (if (re-search-backward "^@implementation\\s-*\\([A-Za-z_]*\\)" nil t) | 695 | (if (re-search-backward "^@implementation\\s-*\\([A-Za-z_]*\\)" nil t) |
| 634 | (get-method-definition-1 " "))) | 696 | (change-log-get-method-definition-1 " "))) |
| 635 | (save-excursion | 697 | (save-excursion |
| 636 | (cond | 698 | (cond |
| 637 | ((re-search-forward "^\\([-+]\\)[ \t\n\f\r]*\\(([^)]*)\\)?\\s-*" nil t) | 699 | ((re-search-forward "^\\([-+]\\)[ \t\n\f\r]*\\(([^)]*)\\)?\\s-*" nil t) |
| 638 | (get-method-definition-1 "") | 700 | (change-log-get-method-definition-1 "") |
| 639 | (while (not (looking-at "[{;]")) | 701 | (while (not (looking-at "[{;]")) |
| 640 | (looking-at | 702 | (looking-at |
| 641 | "\\([A-Za-z_]*:?\\)\\s-*\\(([^)]*)\\)?[A-Za-z_]*[ \t\n\f\r]*") | 703 | "\\([A-Za-z_]*:?\\)\\s-*\\(([^)]*)\\)?[A-Za-z_]*[ \t\n\f\r]*") |
| 642 | (get-method-definition-1 "")) | 704 | (change-log-get-method-definition-1 "")) |
| 643 | (concat get-method-definition-md "]")))))) | 705 | (concat change-log-get-method-definition-md "]")))))) |
| 644 | 706 | ||
| 645 | 707 | ||
| 646 | (provide 'add-log) | 708 | (provide 'add-log) |