diff options
Diffstat (limited to 'lisp/vc/log-edit.el')
-rw-r--r-- | lisp/vc/log-edit.el | 169 |
1 files changed, 137 insertions, 32 deletions
diff --git a/lisp/vc/log-edit.el b/lisp/vc/log-edit.el index 72867f14d2f..1f766eea455 100644 --- a/lisp/vc/log-edit.el +++ b/lisp/vc/log-edit.el @@ -575,19 +575,82 @@ the \\[vc-prefix-map] prefix for VC commands, for example). "Insert FUNC-NAMES, following ChangeLog formatting." (if (not func-names) (insert ":") + ;; Insert a space unless this list of defun names is being + ;; inserted at the start of a line or after a space character. (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 "):"))) + (let ((inside-paren-pair nil) + (first-line t) + name) + ;; Now insert the functions names one by one, inserting newlines + ;; as appropriate. + (while func-names + (setq name (car func-names)) + (setq func-names (cdr func-names)) + ;; If inserting `name' after preexisting text in the first + ;; line would overflow the fill column, place it on its own + ;; line. + (if (and first-line + (> (current-column) 0) + (> (+ (current-column) + (string-width name) + ;; If this be the last name, the column must be + ;; followed by an extra colon character. + (if func-names 1 2)) + fill-column)) + (progn + (insert "\n") + ;; Iterate over this function name again. + (setq func-names (cons name func-names))) + (if inside-paren-pair + ;; If `name' is not the first item in a list of defuns + ;; and inserting it would overflow the fill column, + ;; start a new list of defuns on the next line. + (if (> (+ (current-column) + (string-width name) + ;; If this be the last name, the column must + ;; be followed by an extra colon character; + ;; however, there are two separator characters + ;; that will be deleted, so the number of + ;; columns to add to this in the case of + ;; `name' being final and in other cases are 0 + ;; and 1 respectively. + (if func-names 0 1)) + fill-column) + (progn + (delete-char -2) + (insert ")\n") + (setq inside-paren-pair nil + ;; Iterate over this function name again. + func-names (cons name func-names))) + ;; Insert this defun name with a separator attached. + (insert name ", ")) + ;; Otherwise, decide whether to start a list of defuns or + ;; to insert `name' on its own line. + (if (> (+ (current-column) + (string-width name) + (if func-names 1 2)) ; The column number of + ; line after inserting + ; `name'... + fill-column) + ;; ...would leave insufficient space for any + ;; subsequent defun names so insert it on its own + ;; line. + (insert (if func-names + (format "(%s)\n" name) + (format "(%s):" name))) + ;; Insert a new defun list, unless `name' is the last + ;; function name. + (insert (if (not func-names) + (format "(%s):" name) + (setq inside-paren-pair t) + (format "(%s, " name)))))) + (setq first-line nil)) + ;; Close any open list of defuns. + (when inside-paren-pair + (delete-char -2) + (insert "):"))))) (defun log-edit-fill-entry (&optional justify) "Like \\[fill-paragraph], but for filling ChangeLog-formatted entries. @@ -595,32 +658,70 @@ 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))) + (let* ((range (log-edit-changelog-paragraph)) + (beg (car range)) + (end (cadr range))) (if (= beg end) ;; Not a ChangeLog entry, fill as normal. nil - (cl-callf copy-marker end) + (setq end (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:\\)[[:blank:]]*(") - 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)))) + (let* ((defuns-beg nil) + (defuns nil)) + (while + (progn + ;; Match a regexp against the next ChangeLog entry. + ;; `defuns-beg' will be the end of the file name, + ;; which marks the beginning of the list of defuns. + (setq defuns-beg + (and (< beg end) + (re-search-forward + (concat "\\(?1:" + change-log-unindented-file-names-re + "\\)\\|^\\(?1:\\)[[:blank:]]*(") + end t) + (copy-marker (match-end 1)))) + ;; Fill the intervening prose between the end of the + ;; last match and the beginning of the current match. + (let ((fill-indent-according-to-mode t) + (end (if defuns-beg + (match-beginning 0) end)) + (beg (progn (goto-char beg) + (line-beginning-position))) + space-beg space-end) + (when (<= (line-end-position) end) + ;; Replace space characters within parentheses + ;; that resemble ChangeLog defun names between BEG + ;; and END with non-breaking spaces to prevent + ;; them from being considered break points by + ;; `fill-region'. + (save-excursion + (goto-char beg) + (when (re-search-forward + "^[[:blank:]]*(.*\\([[:space:]]\\).*):" + end t) + (replace-regexp-in-region "[[:space:]]" " " + (setq space-beg + (copy-marker + (match-beginning 0))) + (setq space-end + (copy-marker + (match-end 0)))))) + (fill-region beg end justify)) + ;; Restore the spaces replaced by NBSPs. + (when space-beg + (replace-string-in-region " " " " + space-beg space-end) + (set-marker space-beg nil) + (set-marker space-end nil))) + defuns-beg) + (goto-char defuns-beg) + (setq defuns (change-log-read-defuns end)) + (progn + (delete-region defuns-beg (point)) + (log-edit--insert-filled-defuns defuns) + (setq beg (point)))) + nil) t)))) (defun log-edit-hide-buf (&optional buf where) @@ -1288,3 +1389,7 @@ line of MSG." (provide 'log-edit) ;;; log-edit.el ends here + +;; Local Variables: +;; coding: utf-8-unix +;; End: |