commit f0bec20ac58ab84895b832fc545ea14c442d8332 (HEAD, refs/remotes/origin/master) Author: Dmitry Gutov Date: Thu May 29 22:26:59 2025 +0300 project-remember-project: Support calling it interactively * lisp/progmodes/project.el (project-remember-project): Support interactive invocation (bug#78099) and react with appropriate messages when called so, depending on the blacklist. diff --git a/etc/NEWS b/etc/NEWS index 6b6e5ca4c6d..01ed372a2da 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -429,6 +429,8 @@ This user option describes projects that should always be skipped by *** New command 'project-save-some-buffers' bound to 'C-x p C-x s'. This is like 'C-x s', but only for this project's buffers. +*** 'project-remember-project' can now be called interactively. + ** Registers *** New functions 'buffer-to-register' and 'file-to-register'. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 808d2890b8d..6e9c81ee581 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1936,12 +1936,18 @@ has changed, and NO-WRITE is nil." If project PR satisfies `project-list-exclude', then nothing is done. Save the result in `project-list-file' if the list of projects has changed, and NO-WRITE is nil." - (let ((root (project-root pr))) - (unless (seq-some (lambda (r) - (if (functionp r) - (funcall r pr) - (string-match-p r root))) - project-list-exclude) + (interactive (list (project-current t))) + (let ((root (project-root pr)) + (interact (called-interactively-p 'any))) + (if (seq-some (lambda (r) + (if (functionp r) + (funcall r pr) + (string-match-p r root))) + project-list-exclude) + (when interact + (message "Current project is blacklisted!")) + (when interact + (message "Current project remembered")) (project--remember-dir root no-write)))) (defun project--remove-from-project-list (project-root report-message) commit c9cb89edd500e8a142a7e7cc44a4f8335795d038 Author: Juri Linkov Date: Thu May 29 19:52:20 2025 +0300 Use 'outline-heading-end-regexp' consistently. * lisp/outline.el (outline-font-lock-keywords): For non-nil 'outline-search-function' also search for 'outline-heading-end-regexp' afterwards like there is 'outline-heading-end-regexp' at the end of the regexp counterpart. (outline-minor-mode-highlight-buffer): Use 'outline-heading-end-regexp' like in 'outline-font-lock-keywords' instead of "$". For non-nil 'outline-search-function' also use 'outline-heading-end-regexp' the same way. * lisp/help.el (describe-bindings): Remove unnecessary buffer-local 'outline-heading-end-regexp'. diff --git a/lisp/help.el b/lisp/help.el index 49394fea2cd..8b29a10e0cf 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -793,7 +793,6 @@ or a buffer name." (when describe-bindings-outline (setq-local outline-regexp ".*:$") - (setq-local outline-heading-end-regexp ":\n") (setq-local outline-level (lambda () 1)) (setq-local outline-minor-mode-cycle t outline-minor-mode-highlight t diff --git a/lisp/outline.el b/lisp/outline.el index 61e9b0f3289..9d453881b7e 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -259,14 +259,19 @@ non-nil and point is located on the heading line.") map)) (defvar outline-font-lock-keywords - '( + `( ;; Highlight headings according to the level. (eval . (list (or (when outline-search-function - (lambda (limit) - (when-let* ((ret (funcall outline-search-function limit))) - ;; This is equivalent to adding ".*" in the regexp below. - (set-match-data (list (match-beginning 0) (pos-eol))) - ret))) + ,(lambda (limit) + (when-let* ((ret (funcall outline-search-function limit))) + ;; This is equivalent to adding ".*" in the regexp below. + (set-match-data + (list (match-beginning 0) + (save-excursion + (save-match-data + (re-search-forward + (concat ".*" outline-heading-end-regexp) nil t))))) + ret))) (concat "^\\(?:" outline-regexp "\\).*" outline-heading-end-regexp)) 0 '(if outline-minor-mode (if outline-minor-mode-highlight @@ -520,11 +525,16 @@ outline font-lock faces to those of major mode." (save-excursion (goto-char (point-min)) (let ((regexp (unless outline-search-function - (concat "^\\(?:" outline-regexp "\\).*$")))) + (concat "^\\(?:" outline-regexp "\\).*" outline-heading-end-regexp)))) (while (if outline-search-function (when-let* ((ret (funcall outline-search-function))) ;; This is equivalent to adding ".*" in the regexp above. - (set-match-data (list (match-beginning 0) (pos-eol))) + (set-match-data + (list (match-beginning 0) + (save-excursion + (save-match-data + (re-search-forward + (concat ".*" outline-heading-end-regexp) nil t))))) ret) (re-search-forward regexp nil t)) (let ((overlay (make-overlay (match-beginning 0) (match-end 0)))) commit f9b311464db2e1cc34faaf2c86a9c46216337013 Author: Sean Whitton Date: Thu May 29 12:53:37 2025 +0100 New user option vc-dir-hide-up-to-date-on-revert * lisp/vc/vc-dir.el (vc-dir-hide-up-to-date-on-revert): New defcustom. (vc-dir-revert-buffer-function): Use it. * etc/NEWS: Document it. diff --git a/etc/NEWS b/etc/NEWS index 13479790407..6b6e5ca4c6d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1773,6 +1773,13 @@ were added, removed or edited, Emacs would refuse to proceed. Now Emacs prompts to first register the unregistered files, so that all files in the fileset are in a compatible state for a checkin. +--- +*** New user option 'vc-dir-hide-up-to-date-on-revert'. +If you customize this variable to non-nil, the 'g' command to refresh +the VC Directory buffer also has the effect of the 'x' command. +That is, typing 'g' refreshes the buffer and also hides items in the +'up-to-date' and 'ignored' states. + +++ *** New user option 'vc-async-checkin' to enable async checkin operations. Currently only supported by the Git and Mercurial backends. diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index b9d733d934b..278bafba022 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -158,6 +158,14 @@ option." :group 'vc :version "31.1") +(defcustom vc-dir-hide-up-to-date-on-revert nil + "If non-nil, \\\\[revert-buffer] in VC-Dir buffers also does \\[vc-dir-hide-up-to-date]. +That is, refreshing the VC-Dir buffer also hides `up-to-date' and +`ignored' items." + :type 'boolean + :group 'vc + :version "31.1") + (defun vc-dir-move-to-goal-column () ;; Used to keep the cursor on the file name column. (beginning-of-line) @@ -1347,7 +1355,9 @@ specific headers." (not (vc-dir-fileinfo->needs-update info)))))))))))) (defun vc-dir-revert-buffer-function (&optional _ignore-auto _noconfirm) - (vc-dir-refresh)) + (vc-dir-refresh) + (when vc-dir-hide-up-to-date-on-revert + (vc-dir-hide-state))) (defun vc-dir-refresh () "Refresh the contents of the *VC-dir* buffer. commit 6519fb5d2b22ec571de1d09095df4ad30345e988 Author: Sean Whitton Date: Thu May 29 12:41:36 2025 +0100 Factor out vc-async-checkin-backends This allows third party backends to indicate they support async checkins. * lisp/vc/vc.el (vc-async-checkin-backends): New variable. (vc-checkin): Use it. diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 60748d05ed8..c32cf9faae1 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -1020,6 +1020,9 @@ Not supported by all backends." :safe #'booleanp :version "31.1") +(defvar vc-async-checkin-backends '(Git Hg) + "Backends which support `vc-async-checkin'.") + ;; File property caching @@ -1889,9 +1892,7 @@ Runs the normal hooks `vc-before-checkin-hook' and `vc-checkin-hook'." (vc-call-backend backend 'checkin files comment rev)) (mapc #'vc-delete-automatic-version-backups files))) - (if (and vc-async-checkin - ;; Backends which support `vc-async-checkin'. - (memq backend '(Git Hg))) + (if (and vc-async-checkin (memq backend vc-async-checkin-backends)) ;; Rely on `vc-set-async-update' to update properties. (do-it) (message "Checking in %s..." (vc-delistify files)) commit 433a031d249a28a29bdc6c2c4cf880f26a262627 Author: Martin Rudalics Date: Thu May 29 11:33:28 2025 +0200 Have 'delete-frame' delete initial daemon frame only if FORCE is non-nil * src/frame.c (delete_frame): Delete initial daemon frame only if FORCE is non-nil (Bug#78583). (Fdelete_frame): Rewrite doc-string to mention that it can delete an initial daemon frame if and only if FORCE is non-nil. * etc/NEWS: * doc/lispref/frames.texi (Deleting Frames): Mention that 'delete-frame' can delete an initial daemon frame if and only if FORCE is non-nil. diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 0ad4f52bfc0..7f14e002892 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -2808,6 +2808,9 @@ Note that a frame cannot be deleted as long as its minibuffer serves as surrogate minibuffer for another frame (@pxref{Minibuffers and Frames}). Normally, you cannot delete a frame if all other frames are invisible, but if @var{force} is non-@code{nil}, then you are allowed to do so. +Also, the initial terminal frame of an Emacs process running as daemon +(@pxref{Initial Options, daemon,, emacs, The GNU Emacs Manual}) can be +deleted if and only if @var{force} is non-@code{nil}. @end deffn @defun frame-live-p frame diff --git a/etc/NEWS b/etc/NEWS index 33b042720b5..13479790407 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2195,6 +2195,11 @@ The unused variables 'block-comment-start' and 'block-comment-end', which never actually had any effect when set by major modes, have been removed. ++++ +** 'delete-frame' now needs non-nil FORCE argument to delete daemon frame. +The initial terminal frame of an Emacs process running as daemon can be +deleted via 'delete-frame' if and only if its optional FORCE argument is +non-nil. * Lisp Changes in Emacs 31.1 diff --git a/src/frame.c b/src/frame.c index f2acb19c77d..95fcb9ca7ff 100644 --- a/src/frame.c +++ b/src/frame.c @@ -2481,6 +2481,8 @@ delete_frame (Lisp_Object frame, Lisp_Object force) else error ("Attempt to delete the only frame"); } + else if (IS_DAEMON && FRAME_INITIAL_P (f) && NILP (force)) + error ("Attempt to delete daemon's initial frame"); #ifdef HAVE_X_WINDOWS else if ((x_dnd_in_progress && f == x_dnd_frame) || (x_dnd_waiting_for_finish && f == x_dnd_finish_frame)) @@ -2953,10 +2955,11 @@ FRAME must be a live frame and defaults to the selected one. When `undelete-frame-mode' is enabled, the 16 most recently deleted frames can be undeleted with `undelete-frame', which see. -A frame may not be deleted if its minibuffer serves as surrogate -minibuffer for another frame. Normally, you may not delete a frame if -all other frames are invisible, but if the second optional argument -FORCE is non-nil, you may do so. +Do not delete a frame whose minibuffer serves as surrogate minibuffer +for another frame. Do not delete a frame if all other frames are +invisible unless the second optional argument FORCE is non-nil. Do not +delete the initial terminal frame of an Emacs process running as daemon +unless FORCE is non-nil. This function runs `delete-frame-functions' before actually deleting the frame, unless the frame is a tooltip.