summaryrefslogtreecommitdiff
path: root/lisp/vc/log-edit.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/vc/log-edit.el')
-rw-r--r--lisp/vc/log-edit.el117
1 files changed, 101 insertions, 16 deletions
diff --git a/lisp/vc/log-edit.el b/lisp/vc/log-edit.el
index 963edb49dd3..8d47d66ac38 100644
--- a/lisp/vc/log-edit.el
+++ b/lisp/vc/log-edit.el
@@ -52,8 +52,9 @@
;; The main keymap
(easy-mmode-defmap log-edit-mode-map
- `(("\C-c\C-c" . log-edit-done)
+ '(("\C-c\C-c" . log-edit-done)
("\C-c\C-a" . log-edit-insert-changelog)
+ ("\C-c\C-w" . log-edit-generate-changelog-from-diff)
("\C-c\C-d" . log-edit-show-diff)
("\C-c\C-f" . log-edit-show-files)
("\C-c\C-k" . log-edit-kill-buffer)
@@ -203,10 +204,7 @@ when this variable is set to nil.")
(defconst log-edit-maximum-comment-ring-size 32
"Maximum number of saved comments in the comment ring.")
-(define-obsolete-variable-alias 'vc-comment-ring 'log-edit-comment-ring "22.1")
(defvar log-edit-comment-ring (make-ring log-edit-maximum-comment-ring-size))
-(define-obsolete-variable-alias 'vc-comment-ring-index
- 'log-edit-comment-ring-index "22.1")
(defvar log-edit-comment-ring-index nil)
(defvar log-edit-last-comment-match "")
@@ -311,13 +309,6 @@ automatically."
(or (eobp) (looking-at "\n\n")
(insert "\n"))))
-;; Compatibility with old names.
-(define-obsolete-function-alias 'vc-previous-comment 'log-edit-previous-comment "22.1")
-(define-obsolete-function-alias 'vc-next-comment 'log-edit-next-comment "22.1")
-(define-obsolete-function-alias 'vc-comment-search-reverse 'log-edit-comment-search-backward "22.1")
-(define-obsolete-function-alias 'vc-comment-search-forward 'log-edit-comment-search-forward "22.1")
-(define-obsolete-function-alias 'vc-comment-to-change-log 'log-edit-comment-to-change-log "22.1")
-
;;;
;;; Actual code
;;;
@@ -360,7 +351,7 @@ The first subexpression is the actual text of the field.")
(defun log-edit-goto-eoh () ;FIXME: Almost rfc822-goto-eoh!
(goto-char (point-min))
(when (re-search-forward
- "^\\([^[:alpha:]]\\|[[:alnum:]-]+[^[:alnum:]-:]\\)" nil 'move)
+ "^\\([^[:alpha:]]\\|[[:alnum:]-]+[^[:alnum:]-]\\)" nil 'move)
(goto-char (match-beginning 0))))
(defun log-edit--match-first-line (limit)
@@ -498,10 +489,63 @@ commands (under C-x v for VC, for example).
(set (make-local-variable 'font-lock-defaults)
'(log-edit-font-lock-keywords t))
(setq-local jit-lock-contextually t) ;For the "first line is summary".
+ (setq-local fill-paragraph-function #'log-edit-fill-entry)
(make-local-variable 'log-edit-comment-ring-index)
(add-hook 'kill-buffer-hook 'log-edit-remember-comment nil t)
(hack-dir-local-variables-non-file-buffer))
+(defun log-edit--insert-filled-defuns (func-names)
+ "Insert FUNC-NAMES, following ChangeLog formatting."
+ (if (not func-names)
+ (insert ":")
+ (unless (or (memq (char-before) '(?\n ?\s))
+ (> (current-column) fill-column))
+ (insert " "))
+ (cl-loop for first-fun = t then nil
+ for def in func-names do
+ (when (> (+ (current-column) (string-width def)) fill-column)
+ (unless first-fun
+ (insert ")"))
+ (insert "\n"))
+ (insert (if (memq (char-before) '(?\n ?\s))
+ "(" ", ")
+ def))
+ (insert "):")))
+
+(defun log-edit-fill-entry (&optional justify)
+ "Like \\[fill-paragraph], but handle ChangeLog entries.
+Consecutive function entries without prose (i.e., lines of the
+form \"(FUNCTION):\") will be combined into \"(FUNC1, FUNC2):\"
+according to `fill-column'."
+ (save-excursion
+ (pcase-let ((`(,beg ,end) (log-edit-changelog-paragraph)))
+ (if (= beg end)
+ ;; Not a ChangeLog entry, fill as normal.
+ nil
+ (cl-callf copy-marker end)
+ (goto-char beg)
+ (cl-loop
+ for defuns-beg =
+ (and (< beg end)
+ (re-search-forward
+ (concat "\\(?1:" change-log-unindented-file-names-re
+ "\\)\\|^\\(?1:\\)(")
+ end t)
+ (copy-marker (match-end 1)))
+ ;; Fill prose between log entries.
+ do (let ((fill-indent-according-to-mode t)
+ (end (if defuns-beg (match-beginning 0) end))
+ (beg (progn (goto-char beg) (line-beginning-position))))
+ (when (<= (line-end-position) end)
+ (fill-region beg end justify)))
+ while defuns-beg
+ for defuns = (progn (goto-char defuns-beg)
+ (change-log-read-defuns end))
+ do (progn (delete-region defuns-beg (point))
+ (log-edit--insert-filled-defuns defuns)
+ (setq beg (point))))
+ t))))
+
(defun log-edit-hide-buf (&optional buf where)
(when (setq buf (get-buffer (or buf log-edit-files-buf)))
;; FIXME: Should use something like `quit-windows-on' here, but
@@ -623,7 +667,7 @@ Also saves its contents in the comment history and hides
(setq buffer-read-only nil)
(erase-buffer)
(cvs-insert-strings files)
- (setq buffer-read-only t)
+ (special-mode)
(goto-char (point-min))
(save-selected-window
(cvs-pop-to-buffer-same-frame buf)
@@ -736,6 +780,27 @@ to build the Fixes: header.")
(replace-match (concat " " value) t t nil 1)
(insert field ": " value "\n" (if (looking-at "\n") "" "\n"))))
+(declare-function diff-add-log-current-defuns "diff-mode" ())
+
+(defun log-edit-generate-changelog-from-diff ()
+ "Insert a log message by looking at the current diff.
+This command will generate a ChangeLog entries listing the
+functions. You can then add a description where needed, and use
+\\[fill-paragraph] to join consecutive function names."
+ (interactive)
+ (let* ((diff-buf nil)
+ ;; Unfortunately, `log-edit-show-diff' doesn't have a NO-SHOW
+ ;; option, so we try to work around it via display-buffer
+ ;; machinery.
+ (display-buffer-overriding-action
+ `(,(lambda (buf alist)
+ (setq diff-buf buf)
+ (display-buffer-no-window buf alist))
+ . ((allow-no-window . t)))))
+ (change-log-insert-entries
+ (with-current-buffer (progn (log-edit-show-diff) diff-buf)
+ (diff-add-log-current-defuns)))))
+
(defun log-edit-insert-changelog (&optional use-first)
"Insert a log message by looking at the ChangeLog.
The idea is to write your ChangeLog entries first, and then use this
@@ -764,7 +829,9 @@ regardless of user name or time."
(log-edit-insert-changelog-entries (log-edit-files)))))
(log-edit-set-common-indentation)
;; Add an Author: field if appropriate.
- (when author (log-edit-add-field "Author" (car author)))
+ (when author
+ (log-edit-add-field "Author" (car author))
+ (log-edit-add-field "Summary" ""))
;; Add a Fixes: field if applicable.
(when (consp log-edit-rewrite-fixes)
(rfc822-goto-eoh)
@@ -923,8 +990,10 @@ where LOGBUFFER is the name of the ChangeLog buffer, and each
(setq change-log-default-name nil)
(find-change-log)))))
(when (or (find-buffer-visiting changelog-file-name)
- (file-exists-p changelog-file-name))
- (with-current-buffer (find-file-noselect changelog-file-name)
+ (file-exists-p changelog-file-name)
+ add-log-dont-create-changelog-file)
+ (with-current-buffer
+ (add-log-find-changelog-buffer changelog-file-name)
(unless (eq major-mode 'change-log-mode) (change-log-mode))
(goto-char (point-min))
(if (looking-at "\\s-*\n") (goto-char (match-end 0)))
@@ -1093,6 +1162,22 @@ line of MSG."
(if summary (insert summary "\n\n"))
(cons (buffer-string) res))))
+(defun log-edit--toggle-amend (last-msg-fn)
+ (when (log-edit-toggle-header "Amend" "yes")
+ (goto-char (point-max))
+ (unless (bolp) (insert "\n"))
+ (insert (funcall last-msg-fn))
+ (save-excursion
+ (rfc822-goto-eoh)
+ (forward-line 1)
+ (let ((pt (point)))
+ (and (zerop (forward-line 1))
+ (looking-at "\n\\|\\'")
+ (let ((summary (buffer-substring-no-properties pt (1- (point)))))
+ (skip-chars-forward " \n")
+ (delete-region pt (point))
+ (log-edit-set-header "Summary" summary)))))))
+
(provide 'log-edit)
;;; log-edit.el ends here