Function: add-change-log-entry
add-change-log-entry is an autoloaded, interactive and byte-compiled
function defined in add-log.el.gz.
Signature
(add-change-log-entry &optional WHOAMI CHANGELOG-FILE-NAME OTHER-WINDOW NEW-ENTRY PUT-NEW-ENTRY-ON-NEW-LINE)
Documentation
Find ChangeLog buffer, add an entry for today and an item for this file.
Optional arg WHOAMI (interactive prefix) non-nil means prompt for
user name and email (stored in add-log-full-name
and add-log-mailing-address).
Second arg CHANGELOG-FILE-NAME is the file name of the change log.
If nil, use the value of change-log-default-name. If the file
thus named exists, it is used for the new entry. If it doesn't
exist, it is created, unless add-log-dont-create-changelog-file is t,
in which case a suitably named buffer that doesn't visit any file
is used for keeping entries pertaining to CHANGELOG-FILE-NAME's
directory.
Third arg OTHER-WINDOW non-nil means visit in other window.
Fourth arg NEW-ENTRY non-nil means always create a new entry at the front;
never append to an existing entry. Option add-log-keep-changes-together
otherwise affects whether a new entry is created.
Fifth arg PUT-NEW-ENTRY-ON-NEW-LINE non-nil means that if a new entry is created, put it on a new line by itself, do not put it after a comma on an existing line.
Option add-log-always-start-new-record non-nil means always create a
new record, even when the last record was made on the same date and by
the same person.
The change log file can start with a copyright notice and a copying permission notice. The first blank line indicates the end of these notices.
Today's date is calculated according to add-log-time-zone-rule if
non-nil, otherwise in local time.
Probably introduced at or before Emacs version 16.
Key Bindings
Source Code
;; Defined in /usr/src/emacs/lisp/vc/add-log.el.gz
;;;###autoload
(defun add-change-log-entry (&optional whoami
changelog-file-name
other-window new-entry
put-new-entry-on-new-line)
"Find ChangeLog buffer, add an entry for today and an item for this file.
Optional arg WHOAMI (interactive prefix) non-nil means prompt for
user name and email (stored in `add-log-full-name'
and `add-log-mailing-address').
Second arg CHANGELOG-FILE-NAME is the file name of the change log.
If nil, use the value of `change-log-default-name'. If the file
thus named exists, it is used for the new entry. If it doesn't
exist, it is created, unless `add-log-dont-create-changelog-file' is t,
in which case a suitably named buffer that doesn't visit any file
is used for keeping entries pertaining to CHANGELOG-FILE-NAME's
directory.
Third arg OTHER-WINDOW non-nil means visit in other window.
Fourth arg NEW-ENTRY non-nil means always create a new entry at the front;
never append to an existing entry. Option `add-log-keep-changes-together'
otherwise affects whether a new entry is created.
Fifth arg PUT-NEW-ENTRY-ON-NEW-LINE non-nil means that if a new
entry is created, put it on a new line by itself, do not put it
after a comma on an existing line.
Option `add-log-always-start-new-record' non-nil means always create a
new record, even when the last record was made on the same date and by
the same person.
The change log file can start with a copyright notice and a copying
permission notice. The first blank line indicates the end of these
notices.
Today's date is calculated according to `add-log-time-zone-rule' if
non-nil, otherwise in local time."
(interactive (list current-prefix-arg
(prompt-for-change-log-name)))
(let* ((defun (add-log-current-defun))
(version (and change-log-version-info-enabled
(change-log-version-number-search)))
(buf-file-name (funcall add-log-buffer-file-name-function))
(buffer-file (if buf-file-name (expand-file-name buf-file-name)))
(changelog-file-name (expand-file-name (find-change-log
changelog-file-name
buffer-file)))
;; Set ITEM to the file name to use in the new item.
(item (add-log-file-name buffer-file changelog-file-name)))
;; don't add entries from the ChangeLog file/buffer to itself.
(unless (equal changelog-file-name buffer-file-name)
(cond
((add-log--changelog-buffer-p
changelog-file-name
(window-buffer))
;; If the selected window already shows the desired buffer don't show
;; it again (particularly important if other-window is true).
;; This is important for diff-add-change-log-entries-other-window.
(set-buffer (window-buffer)))
((or other-window (window-dedicated-p))
(switch-to-buffer-other-window
(add-log-find-changelog-buffer changelog-file-name)))
(t
(switch-to-buffer
(add-log-find-changelog-buffer changelog-file-name)))))
(or (derived-mode-p 'change-log-mode)
(change-log-mode))
(undo-boundary)
(goto-char (point-min))
(let ((full-name (or add-log-full-name (user-full-name)))
(mailing-address (or add-log-mailing-address user-mail-address)))
(when whoami
(setq full-name (read-string "Full name: " full-name))
;; Note that some sites have room and phone number fields in
;; full name which look silly when inserted. Rather than do
;; anything about that here, let user give prefix argument so that
;; s/he can edit the full name field in prompter if s/he wants.
(setq mailing-address
(read-string "Mailing address: " mailing-address)))
;; If file starts with a copyright and permission notice, skip them.
;; Assume they end at first blank line.
(when (looking-at "Copyright")
(search-forward "\n\n")
(skip-chars-forward "\n"))
;; Advance into first entry if it is usable; else make new one.
(let ((new-entries
(mapcar (lambda (addr)
(concat
(funcall add-log-time-format
nil add-log-time-zone-rule)
" " full-name
" <" addr ">"))
(if (consp mailing-address)
mailing-address
(list mailing-address)))))
(if (and (not add-log-always-start-new-record)
(let ((hit nil))
(dolist (entry new-entries hit)
(and (looking-at (regexp-quote entry))
;; Reject multiple author entries. (Bug#8645)
(save-excursion
(forward-line 1)
(not (looking-at "[ \t]+.*<.*>$")))
(setq hit t)))))
(forward-line 1)
(insert (and new-entries (seq-random-elt new-entries))
(if use-hard-newlines hard-newline "\n")
(if use-hard-newlines hard-newline "\n"))
(forward-line -1))))
;; Determine where we should stop searching for a usable
;; item to add to, within this entry.
(let ((bound
(save-excursion
(if (looking-at "\n*[^\n* \t]")
(skip-chars-forward "\n")
(if add-log-keep-changes-together
(forward-page) ; page delimits entries for date
(forward-paragraph))) ; paragraph delimits entries for file
(point))))
;; Now insert the new line for this item.
(cond ((re-search-forward "^\\s *\\* *$" bound t)
;; Put this file name into the existing empty item.
(if item
(insert item)))
((and (not new-entry)
(let (case-fold-search)
(re-search-forward
(concat (regexp-quote (concat "* " item))
;; Don't accept `foo.bar' when
;; looking for `foo':
"\\(\\s \\|[(),:]\\)")
bound t)))
;; Add to the existing item for the same file.
(if (re-search-forward "^\\s *$\\|^\\s \\*" nil t)
(goto-char (match-beginning 0))
(goto-char (point-max))
(insert "\n"))
;; Delete excess empty lines; make just 2.
(while (and (not (eobp)) (looking-at "^\\s *$"))
(delete-region (point) (line-beginning-position 2)))
(insert (if use-hard-newlines hard-newline "\n")
(if use-hard-newlines hard-newline "\n"))
(forward-line -2)
(indent-relative-first-indent-point))
(t
;; Make a new item.
(while (looking-at "\\sW")
(forward-line 1))
(while (and (not (eobp)) (looking-at "^\\s *$"))
(delete-region (point) (line-beginning-position 2)))
(insert (if use-hard-newlines hard-newline "\n")
(if use-hard-newlines hard-newline "\n")
(if use-hard-newlines hard-newline "\n"))
(forward-line -2)
(indent-to left-margin)
(insert "* ")
(if item (insert item)))))
;; Now insert the function name, if we have one.
;; Point is at the item for this file,
;; either at the end of the line or at the first blank line.
(if (not defun)
;; No function name, so put in a colon unless we have just a star.
(unless (save-excursion
(beginning-of-line 1)
(looking-at "\\s *\\(\\* *\\)?$"))
(insert ": ")
(if version (insert version ?\s)))
;; Make it easy to get rid of the function name.
(undo-boundary)
(unless (save-excursion
(beginning-of-line 1)
(looking-at "\\s *$"))
(insert ?\s))
;; See if the prev function name has a message yet or not.
;; If not, merge the two items.
(let ((pos (point-marker)))
(skip-syntax-backward " ")
(skip-chars-backward "):")
(if (and (not put-new-entry-on-new-line)
(looking-at "):")
(let ((pos (save-excursion (backward-sexp 1) (point))))
(when (equal (buffer-substring pos (point)) defun)
(delete-region pos (point)))
(> fill-column (+ (current-column) (length defun) 4))))
(progn (skip-chars-backward ", ")
(delete-region (point) pos)
(unless (memq (char-before) '(?\()) (insert ", ")))
(when (and (not put-new-entry-on-new-line) (looking-at "):"))
(delete-region (+ 1 (point)) (line-end-position)))
(goto-char pos)
(insert "("))
(set-marker pos nil))
(insert defun "): ")
(if version (insert version ?\s)))))