diff options
Diffstat (limited to 'lisp/vc/log-edit.el')
-rw-r--r-- | lisp/vc/log-edit.el | 117 |
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 |