update packages
This commit is contained in:
@@ -1,23 +1,12 @@
|
||||
;;; git-commit.el --- Edit Git commit messages -*- lexical-binding:t; coding:utf-8 -*-
|
||||
|
||||
;; Copyright (C) 2008-2023 The Magit Project Contributors
|
||||
;; Copyright (C) 2008-2025 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <jonas@bernoul.li>
|
||||
;; Author: Jonas Bernoulli <emacs.magit@jonas.bernoulli.dev>
|
||||
;; Sebastian Wiesner <lunaryorn@gmail.com>
|
||||
;; Florian Ragwitz <rafl@debian.org>
|
||||
;; Marius Vollmer <marius.vollmer@gmail.com>
|
||||
;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
|
||||
|
||||
;; Homepage: https://github.com/magit/magit
|
||||
;; Keywords: git tools vc
|
||||
|
||||
;; Package-Version: 3.3.0.50-git
|
||||
;; Package-Requires: (
|
||||
;; (emacs "25.1")
|
||||
;; (compat "29.1.3.4")
|
||||
;; (seq "2.24")
|
||||
;; (transient "0.3.6")
|
||||
;; (with-editor "3.0.5"))
|
||||
;; Maintainer: Jonas Bernoulli <emacs.magit@jonas.bernoulli.dev>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
@@ -111,13 +100,9 @@
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'compat)
|
||||
(require 'subr-x)
|
||||
|
||||
(when (and (featurep' seq)
|
||||
(not (fboundp 'seq-keep)))
|
||||
(unload-feature 'seq 'force))
|
||||
(require 'seq)
|
||||
(require 'magit-git)
|
||||
(require 'magit-mode)
|
||||
(require 'magit-process)
|
||||
|
||||
(require 'log-edit)
|
||||
(require 'ring)
|
||||
@@ -125,23 +110,19 @@
|
||||
(require 'transient)
|
||||
(require 'with-editor)
|
||||
|
||||
;; For historic reasons Magit isn't a hard dependency.
|
||||
(require 'magit-base nil t)
|
||||
(require 'magit-git nil t)
|
||||
(declare-function magit-completing-read "magit-base"
|
||||
( prompt collection &optional predicate require-match
|
||||
initial-input hist def fallback))
|
||||
(declare-function magit-expand-git-file-name "magit-git" (filename))
|
||||
(declare-function magit-git-lines "magit-git" (&rest args))
|
||||
(declare-function magit-hook-custom-get "magit-base" (symbol))
|
||||
(declare-function magit-list-local-branch-names "magit-git" ())
|
||||
|
||||
(defvar diff-default-read-only)
|
||||
(defvar flyspell-generic-check-word-predicate)
|
||||
(defvar font-lock-beg)
|
||||
(defvar font-lock-end)
|
||||
(defvar recentf-exclude)
|
||||
|
||||
(defvar git-commit-need-summary-line)
|
||||
|
||||
(define-obsolete-variable-alias
|
||||
'git-commit-known-pseudo-headers
|
||||
'git-commit-trailers
|
||||
"git-commit 4.0.0")
|
||||
|
||||
;;; Options
|
||||
;;;; Variables
|
||||
|
||||
@@ -170,13 +151,22 @@ full loading."
|
||||
:type 'boolean
|
||||
:global t
|
||||
:init-value t
|
||||
:initialize (lambda (symbol exp)
|
||||
(custom-initialize-default symbol exp)
|
||||
(when global-git-commit-mode
|
||||
(add-hook 'find-file-hook #'git-commit-setup-check-buffer)))
|
||||
(if global-git-commit-mode
|
||||
(add-hook 'find-file-hook #'git-commit-setup-check-buffer)
|
||||
(remove-hook 'find-file-hook #'git-commit-setup-check-buffer)))
|
||||
:initialize
|
||||
(lambda (symbol exp)
|
||||
(custom-initialize-default symbol exp)
|
||||
(when global-git-commit-mode
|
||||
(add-hook 'find-file-hook #'git-commit-setup-check-buffer)
|
||||
(remove-hook 'after-change-major-mode-hook
|
||||
#'git-commit-setup-font-lock-in-buffer)))
|
||||
(cond
|
||||
(global-git-commit-mode
|
||||
(add-hook 'find-file-hook #'git-commit-setup-check-buffer)
|
||||
(add-hook 'after-change-major-mode-hook
|
||||
#'git-commit-setup-font-lock-in-buffer))
|
||||
(t
|
||||
(remove-hook 'find-file-hook #'git-commit-setup-check-buffer)
|
||||
(remove-hook 'after-change-major-mode-hook
|
||||
#'git-commit-setup-font-lock-in-buffer))))
|
||||
|
||||
(defcustom git-commit-major-mode #'text-mode
|
||||
"Major mode used to edit Git commit messages.
|
||||
@@ -199,17 +189,23 @@ The major mode configured here is turned on by the minor mode
|
||||
;;;###autoload fundamental-mode
|
||||
;;;###autoload git-commit-elisp-text-mode))))
|
||||
|
||||
(defvaralias 'git-commit-mode-hook 'git-commit-setup-hook
|
||||
"This variable is an alias for `git-commit-setup-hook' (which see).
|
||||
Also note that `git-commit-mode' (which see) is not a major-mode.")
|
||||
|
||||
(defcustom git-commit-setup-hook
|
||||
'(git-commit-save-message
|
||||
git-commit-setup-changelog-support
|
||||
git-commit-turn-on-auto-fill
|
||||
git-commit-propertize-diff
|
||||
bug-reference-mode)
|
||||
(list #'git-commit-ensure-comment-gap
|
||||
#'git-commit-save-message
|
||||
#'git-commit-setup-changelog-support
|
||||
#'git-commit-turn-on-auto-fill
|
||||
#'git-commit-propertize-diff
|
||||
#'bug-reference-mode)
|
||||
"Hook run at the end of `git-commit-setup'."
|
||||
:group 'git-commit
|
||||
:type 'hook
|
||||
:get (and (featurep 'magit-base) #'magit-hook-custom-get)
|
||||
:options '(git-commit-save-message
|
||||
:get #'magit-hook-custom-get
|
||||
:options '(git-commit-ensure-comment-gap
|
||||
git-commit-save-message
|
||||
git-commit-setup-changelog-support
|
||||
magit-generate-changelog
|
||||
git-commit-turn-on-auto-fill
|
||||
@@ -232,12 +228,10 @@ seconds, then this hook isn't run at all. For certain commands
|
||||
such as `magit-rebase-continue' this hook is never run because
|
||||
doing so would lead to a race condition.
|
||||
|
||||
This hook is only run if `magit' is available.
|
||||
|
||||
Also see `magit-post-commit-hook'."
|
||||
:group 'git-commit
|
||||
:type 'hook
|
||||
:get (and (featurep 'magit-base) #'magit-hook-custom-get))
|
||||
:get #'magit-hook-custom-get)
|
||||
|
||||
(defcustom git-commit-post-finish-hook-timeout 1
|
||||
"Time in seconds to wait for git to create a commit.
|
||||
@@ -251,7 +245,7 @@ commit, then the hook is not run at all."
|
||||
:type 'number)
|
||||
|
||||
(defcustom git-commit-finish-query-functions
|
||||
'(git-commit-check-style-conventions)
|
||||
(list #'git-commit-check-style-conventions)
|
||||
"List of functions called to query before performing commit.
|
||||
|
||||
The commit message buffer is current while the functions are
|
||||
@@ -313,13 +307,31 @@ serves as a good introduction."
|
||||
"Whether to use a local message ring instead of the global one.
|
||||
|
||||
This can be set globally, in which case every repository gets its
|
||||
own commit message ring, or locally for a single repository. If
|
||||
Magit isn't available, then setting this to a non-nil value has
|
||||
no effect."
|
||||
own commit message ring, or locally for a single repository."
|
||||
:group 'git-commit
|
||||
:safe 'booleanp
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom git-commit-cd-to-toplevel nil
|
||||
"Whether to set `default-directory' to the worktree in message buffer.
|
||||
|
||||
Editing a commit message is done by visiting a file located in the git
|
||||
directory, usually \"COMMIT_EDITMSG\". As is done when visiting any
|
||||
file, the local value of `default-directory' is set to the directory
|
||||
that contains the file.
|
||||
|
||||
If this option is non-nil, then the local `default-directory' is changed
|
||||
to the working tree from which the commit command was invoked. You may
|
||||
wish to do that, to make it easier to open a file that is located in the
|
||||
working tree, directly from the commit message buffer.
|
||||
|
||||
If the git variable `safe.bareRepository' is set to \"explicit\", then
|
||||
you have to enable this, to be able to commit at all. See issue #5100.
|
||||
|
||||
This option only has an effect if the commit was initiated from Magit."
|
||||
:group 'git-commit
|
||||
:type 'boolean)
|
||||
|
||||
;;;; Faces
|
||||
|
||||
(defgroup git-commit-faces nil
|
||||
@@ -360,18 +372,13 @@ In this context a \"keyword\" is text surrounded by brackets."
|
||||
:group 'git-commit-faces)
|
||||
|
||||
(defface git-commit-comment-branch-local
|
||||
(if (featurep 'magit)
|
||||
'((t :inherit magit-branch-local))
|
||||
'((t :inherit font-lock-variable-name-face)))
|
||||
'((t :inherit magit-branch-local))
|
||||
"Face used for names of local branches in commit message comments."
|
||||
:group 'git-commit-faces)
|
||||
|
||||
(defface git-commit-comment-branch-remote
|
||||
(if (featurep 'magit)
|
||||
'((t :inherit magit-branch-remote))
|
||||
'((t :inherit font-lock-variable-name-face)))
|
||||
"Face used for names of remote branches in commit message comments.
|
||||
This is only used if Magit is available."
|
||||
'((t :inherit magit-branch-remote))
|
||||
"Face used for names of remote branches in commit message comments."
|
||||
:group 'git-commit-faces)
|
||||
|
||||
(defface git-commit-comment-detached
|
||||
@@ -419,13 +426,15 @@ the redundant bindings, then set this to nil, before loading
|
||||
"C-c M-p" #'git-commit-search-message-backward
|
||||
"C-c M-n" #'git-commit-search-message-forward
|
||||
"C-c C-i" #'git-commit-insert-trailer
|
||||
"C-c M-s" #'git-commit-save-message)
|
||||
"C-c M-s" #'git-commit-save-message
|
||||
"C-c C-d" 'magit-diff-while-committing
|
||||
"C-c C-w" 'magit-pop-revision-stack)
|
||||
|
||||
;;; Menu
|
||||
|
||||
(require 'easymenu)
|
||||
(easy-menu-define git-commit-mode-menu git-commit-mode-map
|
||||
"Git Commit Mode Menu"
|
||||
"Git Commit Mode Menu."
|
||||
'("Commit"
|
||||
["Previous" git-commit-prev-message t]
|
||||
["Next" git-commit-next-message t]
|
||||
@@ -472,8 +481,6 @@ the redundant bindings, then set this to nil, before loading
|
||||
(string-match-p git-commit-filename-regexp buffer-file-name))
|
||||
(git-commit-setup-font-lock)))
|
||||
|
||||
(add-hook 'after-change-major-mode-hook #'git-commit-setup-font-lock-in-buffer)
|
||||
|
||||
(defun git-commit-setup-check-buffer ()
|
||||
(when (and buffer-file-name
|
||||
(string-match-p git-commit-filename-regexp buffer-file-name))
|
||||
@@ -484,7 +491,7 @@ the redundant bindings, then set this to nil, before loading
|
||||
(defun git-commit-file-not-found ()
|
||||
;; cygwin git will pass a cygwin path (/cygdrive/c/foo/.git/...),
|
||||
;; try to handle this in window-nt Emacs.
|
||||
(when-let
|
||||
(when-let*
|
||||
((file (and (or (string-match-p git-commit-filename-regexp
|
||||
buffer-file-name)
|
||||
(and (boundp 'git-rebase-filename-regexp)
|
||||
@@ -492,20 +499,11 @@ the redundant bindings, then set this to nil, before loading
|
||||
buffer-file-name)))
|
||||
(not (file-accessible-directory-p
|
||||
(file-name-directory buffer-file-name)))
|
||||
(if (require 'magit-git nil t)
|
||||
;; Emacs prepends a "c:".
|
||||
(magit-expand-git-file-name
|
||||
(substring buffer-file-name 2))
|
||||
;; Fallback if we can't load `magit-git'.
|
||||
(and (string-match
|
||||
"\\`[a-z]:/\\(cygdrive/\\)?\\([a-z]\\)/\\(.*\\)"
|
||||
buffer-file-name)
|
||||
(concat (match-string 2 buffer-file-name) ":/"
|
||||
(match-string 3 buffer-file-name)))))))
|
||||
(when (file-accessible-directory-p (file-name-directory file))
|
||||
(let ((inhibit-read-only t))
|
||||
(insert-file-contents file t)
|
||||
t))))
|
||||
(magit-expand-git-file-name (substring buffer-file-name 2))))
|
||||
((file-accessible-directory-p (file-name-directory file)))
|
||||
(inhibit-read-only t))
|
||||
(insert-file-contents file t)
|
||||
t))
|
||||
|
||||
(when (eq system-type 'windows-nt)
|
||||
(add-hook 'find-file-not-found-functions #'git-commit-file-not-found))
|
||||
@@ -534,27 +532,28 @@ Used as the local value of `header-line-format', in buffer using
|
||||
(setq git-commit-usage-message nil) ; show a shorter message")
|
||||
|
||||
(defun git-commit-setup ()
|
||||
(when (fboundp 'magit-toplevel)
|
||||
;; `magit-toplevel' is autoloaded and defined in magit-git.el,
|
||||
;; That library declares this functions without loading
|
||||
;; magit-process.el, which defines it.
|
||||
(require 'magit-process nil t))
|
||||
;; Pretend that git-commit-mode is a major-mode,
|
||||
;; so that directory-local settings can be used.
|
||||
(let ((default-directory
|
||||
(or (and (not (file-exists-p ".dir-locals.el"))
|
||||
;; When $GIT_DIR/.dir-locals.el doesn't exist,
|
||||
;; fallback to $GIT_WORK_TREE/.dir-locals.el,
|
||||
;; because the maintainer can use the latter
|
||||
;; to enforce conventions, while s/he has no
|
||||
;; control over the former.
|
||||
(fboundp 'magit-toplevel) ; silence byte-compiler
|
||||
(magit-toplevel))
|
||||
default-directory)))
|
||||
(let ((buffer-file-name nil) ; trick hack-dir-local-variables
|
||||
(major-mode 'git-commit-mode)) ; trick dir-locals-collect-variables
|
||||
(hack-dir-local-variables)
|
||||
(hack-local-variables-apply)))
|
||||
(let ((gitdir default-directory)
|
||||
(cd (and git-commit-cd-to-toplevel
|
||||
(or (car (rassoc default-directory magit--separated-gitdirs))
|
||||
(magit-toplevel)))))
|
||||
;; Pretend that git-commit-mode is a major-mode,
|
||||
;; so that directory-local settings can be used.
|
||||
(let ((default-directory
|
||||
(or (and (not (file-exists-p
|
||||
(expand-file-name ".dir-locals.el" gitdir)))
|
||||
;; When $GIT_DIR/.dir-locals.el doesn't exist,
|
||||
;; fallback to $GIT_WORK_TREE/.dir-locals.el,
|
||||
;; because the maintainer can use the latter
|
||||
;; to enforce conventions, while s/he has no
|
||||
;; control over the former.
|
||||
(or cd (magit-toplevel)))
|
||||
gitdir)))
|
||||
(let ((buffer-file-name nil) ; trick hack-dir-local-variables
|
||||
(major-mode 'git-commit-mode)) ; trick dir-locals-collect-variables
|
||||
(hack-dir-local-variables)
|
||||
(hack-local-variables-apply)))
|
||||
(when cd
|
||||
(setq default-directory cd)))
|
||||
(when git-commit-major-mode
|
||||
(let ((auto-mode-alist
|
||||
;; `set-auto-mode--apply-alist' removes the remote part from
|
||||
@@ -580,21 +579,18 @@ Used as the local value of `header-line-format', in buffer using
|
||||
(with-editor-mode 1))
|
||||
(add-hook 'with-editor-finish-query-functions
|
||||
#'git-commit-finish-query-functions nil t)
|
||||
(add-hook 'with-editor-pre-finish-hook
|
||||
#'git-commit-save-message nil t)
|
||||
(add-hook 'with-editor-pre-cancel-hook
|
||||
#'git-commit-save-message nil t)
|
||||
(add-hook 'with-editor-pre-finish-hook #'git-commit-save-message nil t)
|
||||
(add-hook 'with-editor-pre-cancel-hook #'git-commit-save-message nil t)
|
||||
(when (fboundp 'magit-commit--reset-command)
|
||||
(add-hook 'with-editor-post-finish-hook #'magit-commit--reset-command)
|
||||
(add-hook 'with-editor-post-cancel-hook #'magit-commit--reset-command))
|
||||
(when (and (fboundp 'magit-rev-parse)
|
||||
(not (memq last-command
|
||||
'(magit-sequencer-continue
|
||||
magit-sequencer-skip
|
||||
magit-am-continue
|
||||
magit-am-skip
|
||||
magit-rebase-continue
|
||||
magit-rebase-skip))))
|
||||
(unless (memq last-command
|
||||
'(magit-sequencer-continue
|
||||
magit-sequencer-skip
|
||||
magit-am-continue
|
||||
magit-am-skip
|
||||
magit-rebase-continue
|
||||
magit-rebase-skip))
|
||||
(add-hook 'with-editor-post-finish-hook
|
||||
(apply-partially #'git-commit-run-post-finish-hook
|
||||
(magit-rev-parse "HEAD"))
|
||||
@@ -603,29 +599,24 @@ Used as the local value of `header-line-format', in buffer using
|
||||
(magit-wip-maybe-add-commit-hook)))
|
||||
(setq with-editor-cancel-message
|
||||
#'git-commit-cancel-message)
|
||||
(git-commit-mode 1)
|
||||
(git-commit-setup-font-lock)
|
||||
(git-commit-prepare-message-ring)
|
||||
(when (boundp 'save-place)
|
||||
(setq save-place nil))
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(when (looking-at "\\`\\(\\'\\|\n[^\n]\\)")
|
||||
(open-line 1)))
|
||||
(let ((git-commit-mode-hook nil))
|
||||
(git-commit-mode 1))
|
||||
(with-demoted-errors "Error running git-commit-setup-hook: %S"
|
||||
(run-hooks 'git-commit-setup-hook))
|
||||
(when git-commit-usage-message
|
||||
(setq with-editor-usage-message git-commit-usage-message))
|
||||
(with-editor-usage-message)
|
||||
(set-buffer-modified-p nil)
|
||||
(when-let ((format git-commit-header-line-format))
|
||||
(setq header-line-format
|
||||
(if (stringp format) (substitute-command-keys format) format)))
|
||||
(set-buffer-modified-p nil))
|
||||
(when git-commit-usage-message
|
||||
(setq with-editor-usage-message git-commit-usage-message))
|
||||
(with-editor-usage-message))
|
||||
|
||||
(defun git-commit-run-post-finish-hook (previous)
|
||||
(when (and git-commit-post-finish-hook
|
||||
(require 'magit nil t)
|
||||
(fboundp 'magit-rev-parse))
|
||||
(when git-commit-post-finish-hook
|
||||
(cl-block nil
|
||||
(let ((break (time-add (current-time)
|
||||
(seconds-to-time
|
||||
@@ -641,22 +632,40 @@ Used as the local value of `header-line-format', in buffer using
|
||||
(define-minor-mode git-commit-mode
|
||||
"Auxiliary minor mode used when editing Git commit messages.
|
||||
This mode is only responsible for setting up some key bindings.
|
||||
Don't use it directly, instead enable `global-git-commit-mode'."
|
||||
Don't use it directly; instead enable `global-git-commit-mode'.
|
||||
Variable `git-commit-major-mode' controls which major-mode is
|
||||
used."
|
||||
:lighter "")
|
||||
|
||||
(put 'git-commit-mode 'permanent-local t)
|
||||
|
||||
(defun git-commit-ensure-comment-gap ()
|
||||
"Separate initial empty line from initial comment.
|
||||
If the buffer begins with an empty line followed by a comment, insert
|
||||
an additional newline in between, so that once the users start typing,
|
||||
the input isn't tacked to the comment."
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(when (looking-at (format "\\`\n%s" comment-start))
|
||||
(open-line 1))))
|
||||
|
||||
(defun git-commit-setup-changelog-support ()
|
||||
"Treat ChangeLog entries as unindented paragraphs."
|
||||
(when (fboundp 'log-indent-fill-entry) ; New in Emacs 27.
|
||||
(setq-local fill-paragraph-function #'log-indent-fill-entry))
|
||||
(setq-local fill-paragraph-function #'log-edit-fill-entry)
|
||||
(setq-local fill-indent-according-to-mode t)
|
||||
(setq-local paragraph-start (concat paragraph-start "\\|\\*\\|(")))
|
||||
|
||||
(defun git-commit-turn-on-auto-fill ()
|
||||
"Unconditionally turn on Auto Fill mode."
|
||||
"Unconditionally turn on Auto Fill mode.
|
||||
Ensure auto filling happens everywhere, except in the summary line."
|
||||
(turn-on-auto-fill)
|
||||
(setq-local comment-auto-fill-only-comments nil)
|
||||
(turn-on-auto-fill))
|
||||
(when git-commit-need-summary-line
|
||||
(setq-local auto-fill-function #'git-commit-auto-fill-except-summary)))
|
||||
|
||||
(defun git-commit-auto-fill-except-summary ()
|
||||
(unless (eq (line-beginning-position) 1)
|
||||
(do-auto-fill)))
|
||||
|
||||
(defun git-commit-turn-on-orglink ()
|
||||
"Turn on Orglink mode if it is available.
|
||||
@@ -670,16 +679,21 @@ turning on `orglink-mode'."
|
||||
|
||||
(defun git-commit-turn-on-flyspell ()
|
||||
"Unconditionally turn on Flyspell mode.
|
||||
Also prevent comments from being checked and
|
||||
finally check current non-comment text."
|
||||
Also check text that is already in the buffer, while avoiding to check
|
||||
most text that Git will strip from the final message, such as the last
|
||||
comment and anything below the cut line (\"--- >8 ---\")."
|
||||
(require 'flyspell)
|
||||
(turn-on-flyspell)
|
||||
(setq flyspell-generic-check-word-predicate
|
||||
#'git-commit-flyspell-verify)
|
||||
(let ((end)
|
||||
(let ((end nil)
|
||||
;; The "cut line" is defined in "git/wt-status.c". It appears
|
||||
;; in the commit message when `commit.verbose' is set to true.
|
||||
(cut-line-regex (format "^%s -\\{8,\\} >8 -\\{8,\\}$" comment-start))
|
||||
(comment-start-regex (format "^\\(%s\\|$\\)" comment-start)))
|
||||
(save-excursion
|
||||
(goto-char (point-max))
|
||||
(goto-char (or (re-search-forward cut-line-regex nil t)
|
||||
(point-max)))
|
||||
(while (and (not (bobp)) (looking-at comment-start-regex))
|
||||
(forward-line -1))
|
||||
(unless (looking-at comment-start-regex)
|
||||
@@ -726,7 +740,7 @@ conventions are checked."
|
||||
|
||||
(defun git-commit-prev-message (arg)
|
||||
"Cycle backward through message history, after saving current message.
|
||||
With a numeric prefix ARG, go back ARG comments."
|
||||
With a numeric prefix ARG, go back ARG messages."
|
||||
(interactive "*p")
|
||||
(let ((len (ring-length log-edit-comment-ring)))
|
||||
(if (<= len 0)
|
||||
@@ -734,11 +748,11 @@ With a numeric prefix ARG, go back ARG comments."
|
||||
;; Unlike `log-edit-previous-comment' we save the current
|
||||
;; non-empty and newly written comment, because otherwise
|
||||
;; it would be irreversibly lost.
|
||||
(when-let ((message (git-commit-buffer-message)))
|
||||
(unless (ring-member log-edit-comment-ring message)
|
||||
(ring-insert log-edit-comment-ring message)
|
||||
(cl-incf arg)
|
||||
(setq len (ring-length log-edit-comment-ring))))
|
||||
(when-let* ((message (git-commit-buffer-message))
|
||||
((not (ring-member log-edit-comment-ring message))))
|
||||
(ring-insert log-edit-comment-ring message)
|
||||
(cl-incf arg)
|
||||
(setq len (ring-length log-edit-comment-ring)))
|
||||
;; Delete the message but not the instructions at the end.
|
||||
(save-restriction
|
||||
(goto-char (point-min))
|
||||
@@ -754,7 +768,7 @@ With a numeric prefix ARG, go back ARG comments."
|
||||
|
||||
(defun git-commit-next-message (arg)
|
||||
"Cycle forward through message history, after saving current message.
|
||||
With a numeric prefix ARG, go forward ARG comments."
|
||||
With a numeric prefix ARG, go forward ARG messages."
|
||||
(interactive "*p")
|
||||
(git-commit-prev-message (- arg)))
|
||||
|
||||
@@ -762,9 +776,8 @@ With a numeric prefix ARG, go forward ARG comments."
|
||||
"Search backward through message history for a match for STRING.
|
||||
Save current message first."
|
||||
(interactive
|
||||
;; Avoid `format-prompt' because it isn't available until Emacs 28.
|
||||
(list (read-string (format "Comment substring (default %s): "
|
||||
log-edit-last-comment-match)
|
||||
(list (read-string (format-prompt "Comment substring"
|
||||
log-edit-last-comment-match)
|
||||
nil nil log-edit-last-comment-match)))
|
||||
(cl-letf (((symbol-function #'log-edit-previous-comment)
|
||||
(symbol-function #'git-commit-prev-message)))
|
||||
@@ -774,9 +787,8 @@ Save current message first."
|
||||
"Search forward through message history for a match for STRING.
|
||||
Save current message first."
|
||||
(interactive
|
||||
;; Avoid `format-prompt' because it isn't available until Emacs 28.
|
||||
(list (read-string (format "Comment substring (default %s): "
|
||||
log-edit-last-comment-match)
|
||||
(list (read-string (format-prompt "Comment substring"
|
||||
log-edit-last-comment-match)
|
||||
nil nil log-edit-last-comment-match)))
|
||||
(cl-letf (((symbol-function #'log-edit-previous-comment)
|
||||
(symbol-function #'git-commit-prev-message)))
|
||||
@@ -790,8 +802,7 @@ Save current message first."
|
||||
(when-let ((index (ring-member log-edit-comment-ring message)))
|
||||
(ring-remove log-edit-comment-ring index))
|
||||
(ring-insert log-edit-comment-ring message)
|
||||
(when (and git-commit-use-local-message-ring
|
||||
(fboundp 'magit-repository-local-set))
|
||||
(when git-commit-use-local-message-ring
|
||||
(magit-repository-local-set 'log-edit-comment-ring
|
||||
log-edit-comment-ring))
|
||||
(message "Message saved"))
|
||||
@@ -799,8 +810,7 @@ Save current message first."
|
||||
|
||||
(defun git-commit-prepare-message-ring ()
|
||||
(make-local-variable 'log-edit-comment-ring-index)
|
||||
(when (and git-commit-use-local-message-ring
|
||||
(fboundp 'magit-repository-local-get))
|
||||
(when git-commit-use-local-message-ring
|
||||
(setq-local log-edit-comment-ring
|
||||
(magit-repository-local-get
|
||||
'log-edit-comment-ring
|
||||
@@ -828,13 +838,6 @@ Save current message first."
|
||||
(setq str (replace-match "\n" t t str)))
|
||||
str))))
|
||||
|
||||
;;; Utilities
|
||||
|
||||
(defsubst git-commit-executable ()
|
||||
(if (fboundp 'magit-git-executable)
|
||||
(magit-git-executable)
|
||||
"git"))
|
||||
|
||||
;;; Trailers
|
||||
|
||||
(transient-define-prefix git-commit-insert-trailer ()
|
||||
@@ -923,16 +926,14 @@ return name and email of the current user (you)."
|
||||
(list (or (getenv "GIT_AUTHOR_NAME")
|
||||
(getenv "GIT_COMMITTER_NAME")
|
||||
(with-demoted-errors "Error running 'git config user.name': %S"
|
||||
(car (process-lines
|
||||
(git-commit-executable) "config" "user.name")))
|
||||
(magit-get "user.name"))
|
||||
user-full-name
|
||||
(read-string "Name: "))
|
||||
(or (getenv "GIT_AUTHOR_EMAIL")
|
||||
(getenv "GIT_COMMITTER_EMAIL")
|
||||
(getenv "EMAIL")
|
||||
(with-demoted-errors "Error running 'git config user.email': %S"
|
||||
(car (process-lines
|
||||
(git-commit-executable) "config" "user.email")))
|
||||
(magit-get "user.email"))
|
||||
(read-string "Email: ")))))
|
||||
|
||||
(defalias 'git-commit-self-ident #'git-commit-get-ident)
|
||||
@@ -941,23 +942,19 @@ return name and email of the current user (you)."
|
||||
|
||||
(defun git-commit-read-ident (prompt)
|
||||
"Read a name and email, prompting with PROMPT, and return them.
|
||||
If Magit is available, read them using a single prompt, offering
|
||||
past commit authors as completion candidates. The input must
|
||||
have the form \"NAME <EMAIL>\"."
|
||||
(if (require 'magit-git nil t)
|
||||
(let ((str (magit-completing-read
|
||||
prompt
|
||||
(sort (delete-dups
|
||||
(magit-git-lines "log" "-n9999" "--format=%aN <%ae>"))
|
||||
#'string<)
|
||||
nil nil nil 'git-commit-read-ident-history)))
|
||||
(save-match-data
|
||||
(if (string-match "\\`\\([^<]+\\) *<\\([^>]+\\)>\\'" str)
|
||||
(list (save-match-data (string-trim (match-string 1 str)))
|
||||
(string-trim (match-string 2 str)))
|
||||
(user-error "Invalid input"))))
|
||||
(list (read-string "Name: ")
|
||||
(read-string "Email: "))))
|
||||
Read them using a single prompt, offering past commit authors as
|
||||
completion candidates. The input must have the form \"NAME <EMAIL>\"."
|
||||
(let ((str (magit-completing-read
|
||||
prompt
|
||||
(sort (delete-dups
|
||||
(magit-git-lines "log" "-n9999" "--format=%aN <%ae>"))
|
||||
#'string<)
|
||||
nil nil nil 'git-commit-read-ident-history)))
|
||||
(save-match-data
|
||||
(if (string-match "\\`\\([^<]+\\) *<\\([^>]+\\)>\\'" str)
|
||||
(list (save-match-data (string-trim (match-string 1 str)))
|
||||
(string-trim (match-string 2 str)))
|
||||
(user-error "Invalid input")))))
|
||||
|
||||
(defun git-commit--insert-ident-trailer (trailer name email)
|
||||
(git-commit--insert-trailer trailer (format "%s <%s>" name email)))
|
||||
@@ -1051,10 +1048,10 @@ Added to `font-lock-extend-region-functions'."
|
||||
(defconst git-commit-font-lock-keywords-1
|
||||
'(;; Trailers
|
||||
(eval . `(,(git-commit--trailer-regexp)
|
||||
(1 'git-commit-trailer-token)
|
||||
(2 'git-commit-trailer-value)
|
||||
(3 'git-commit-trailer-token)
|
||||
(4 'git-commit-trailer-value)))
|
||||
(1 'git-commit-trailer-token nil t)
|
||||
(2 'git-commit-trailer-value nil t)
|
||||
(3 'git-commit-trailer-token nil t)
|
||||
(4 'git-commit-trailer-value nil t)))
|
||||
;; Summary
|
||||
(eval . `(,(git-commit-summary-regexp)
|
||||
(1 'git-commit-summary)))
|
||||
@@ -1130,17 +1127,7 @@ Added to `font-lock-extend-region-functions'."
|
||||
(modify-syntax-entry ?\' "." table)
|
||||
(modify-syntax-entry ?` "." table)
|
||||
(set-syntax-table table))
|
||||
(setq-local comment-start
|
||||
(or (with-temp-buffer
|
||||
(and (zerop
|
||||
(call-process
|
||||
(git-commit-executable) nil (list t nil) nil
|
||||
"config" "core.commentchar"))
|
||||
(not (bobp))
|
||||
(progn
|
||||
(goto-char (point-min))
|
||||
(buffer-substring (point) (line-end-position)))))
|
||||
"#"))
|
||||
(setq-local comment-start (or (magit-get "core.commentchar") "#"))
|
||||
(setq-local comment-start-skip (format "^%s+[\s\t]*" comment-start))
|
||||
(setq-local comment-end "")
|
||||
(setq-local comment-end-skip "\n")
|
||||
@@ -1153,23 +1140,17 @@ Added to `font-lock-extend-region-functions'."
|
||||
(aref comment-start 0)))
|
||||
(markdown-fill-paragraph justify)))))
|
||||
(setq-local git-commit--branch-name-regexp
|
||||
(if (and (featurep 'magit-git)
|
||||
;; When using cygwin git, we may end up in a
|
||||
;; non-existing directory, which would cause
|
||||
;; any git calls to signal an error.
|
||||
(file-accessible-directory-p default-directory))
|
||||
(progn
|
||||
;; Make sure the below functions are available.
|
||||
(require 'magit)
|
||||
;; Font-Lock wants every submatch to succeed, so
|
||||
;; also match the empty string. Avoid listing
|
||||
;; remote branches and using `regexp-quote',
|
||||
;; because in repositories have thousands of
|
||||
;; branches that would be very slow. See #4353.
|
||||
(format "\\(\\(?:%s\\)\\|\\)\\([^']+\\)"
|
||||
(mapconcat #'identity
|
||||
(magit-list-local-branch-names)
|
||||
"\\|")))
|
||||
;; When using cygwin git, we may end up in a
|
||||
;; non-existing directory, which would cause
|
||||
;; any git calls to signal an error.
|
||||
(if (file-accessible-directory-p default-directory)
|
||||
;; Font-Lock wants every submatch to succeed, so
|
||||
;; also match the empty string. Avoid listing
|
||||
;; remote branches and using `regexp-quote',
|
||||
;; because in repositories that have thousands of
|
||||
;; branches that would be very slow. See #4353.
|
||||
(format "\\(\\(?:%s\\)\\|\\)\\([^']+\\)"
|
||||
(string-join (magit-list-local-branch-names) "\\|"))
|
||||
"\\([^']*\\)"))
|
||||
(setq-local font-lock-multiline t)
|
||||
(add-hook 'font-lock-extend-region-functions
|
||||
@@ -1192,13 +1173,11 @@ Added to `font-lock-extend-region-functions'."
|
||||
(delete-region (point) (point-max)))))
|
||||
(let ((diff-default-read-only nil))
|
||||
(diff-mode))
|
||||
(let (font-lock-verbose font-lock-support-mode)
|
||||
(if (fboundp 'font-lock-ensure)
|
||||
(font-lock-ensure)
|
||||
(with-no-warnings
|
||||
(font-lock-fontify-buffer))))
|
||||
(let (next (pos (point-min)))
|
||||
(while (setq next (next-single-property-change pos 'face))
|
||||
(let ((font-lock-verbose nil)
|
||||
(font-lock-support-mode nil))
|
||||
(font-lock-ensure))
|
||||
(let ((pos (point-min)))
|
||||
(while-let ((next (next-single-property-change pos 'face)))
|
||||
(put-text-property pos next 'font-lock-face
|
||||
(get-text-property pos 'face))
|
||||
(setq pos next))
|
||||
@@ -1231,10 +1210,6 @@ Elisp doc-strings, including this one. Unlike in doc-strings,
|
||||
'git-commit-insert-header
|
||||
'git-commit--insert-ident-trailer
|
||||
"git-commit 4.0.0")
|
||||
(define-obsolete-variable-alias
|
||||
'git-commit-known-pseudo-headers
|
||||
'git-commit-trailer
|
||||
"git-commit 4.0.0")
|
||||
(define-obsolete-face-alias
|
||||
'git-commit-pseudo-header
|
||||
'git-commit-trailer-value
|
||||
|
||||
Reference in New Issue
Block a user