]> git.eshelyaron.com Git - emacs.git/commitdiff
* lisp/tab-bar.el (tab-bar-close-group-tabs): New command.
authorJuri Linkov <juri@linkov.net>
Wed, 10 Mar 2021 18:09:23 +0000 (20:09 +0200)
committerJuri Linkov <juri@linkov.net>
Wed, 10 Mar 2021 18:09:23 +0000 (20:09 +0200)
(tab-close-group): New alias.
(tab-bar-close-other-tabs): Rewrite to fix old bug where regardless of
the returned value from tab-bar-tab-prevent-close-functions,
only one tab was retained.

etc/NEWS
lisp/tab-bar.el

index b5ee78893ce644214ccd12d9639721794ac48cf8..b48f7c361676ae61b17276912380d346940ca8c6 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -542,6 +542,7 @@ It also supports a negative argument.
 
 ---
 *** 'C-x t G' assigns a group name to the tab.
+'tab-close-group' can close all tabs that belong to the selected group.
 
 ---
 *** New user option 'tab-bar-tab-name-format-function'.
index bc89a114228004ed1365b437000aa0f97b63da5a..66f8ccae472b4c9f2f98820e20d66f6be80fc051 100644 (file)
@@ -1148,22 +1148,25 @@ for the last tab on a frame is determined by
   "Close all tabs on the selected frame, except the selected one."
   (interactive)
   (let* ((tabs (funcall tab-bar-tabs-function))
-         (current-index (tab-bar--current-tab-index tabs)))
-    (when current-index
-      (dotimes (index (length tabs))
-        (unless (or (eq index current-index)
+         (current-index (tab-bar--current-tab-index tabs))
+         (current-tab (and current-index (nth current-index tabs)))
+         (index 0))
+    (when current-tab
+      (dolist (tab tabs)
+        (unless (or (eq tab current-tab)
                     (run-hook-with-args-until-success
-                     'tab-bar-tab-prevent-close-functions
-                     (nth index tabs)
+                     'tab-bar-tab-prevent-close-functions tab
                      ;; `last-tab-p' logically can't ever be true
                      ;; if we make it this far
                      nil))
           (push `((frame . ,(selected-frame))
                   (index . ,index)
-                  (tab . ,(nth index tabs)))
+                  (tab . ,tab))
                 tab-bar-closed-tabs)
-          (run-hook-with-args 'tab-bar-tab-pre-close-functions (nth index tabs) nil)))
-      (set-frame-parameter nil 'tabs (list (nth current-index tabs)))
+          (run-hook-with-args 'tab-bar-tab-pre-close-functions tab nil)
+          (setq tabs (delq tab tabs)))
+        (setq index (1+ index)))
+      (set-frame-parameter nil 'tabs tabs)
 
       ;; Recalculate tab-bar-lines and update frames
       (tab-bar--update-tab-bar-lines)
@@ -1277,6 +1280,32 @@ If GROUP-NAME is the empty string, then remove the tab from any group."
     (unless tab-bar-mode
       (message "Set tab group to '%s'" group-new-name))))
 
+(defun tab-bar-close-group-tabs (group-name)
+  "Close all tabs that belong to GROUP-NAME on the selected frame."
+  (interactive
+   (let* ((tabs (funcall tab-bar-tabs-function))
+          (tab-index (1+ (tab-bar--current-tab-index tabs)))
+          (group-name (alist-get 'group (nth (1- tab-index) tabs))))
+     (list (completing-read
+            "Close all tabs with group name: "
+            (delete-dups (delq nil (cons group-name
+                                         (mapcar (lambda (tab)
+                                                   (alist-get 'group tab))
+                                                 (funcall tab-bar-tabs-function)))))))))
+  (let* ((close-group (and (> (length group-name) 0) group-name))
+         (tab-bar-tab-prevent-close-functions
+          (cons (lambda (tab _last-tab-p)
+                  (not (equal (alist-get 'group tab) close-group)))
+                tab-bar-tab-prevent-close-functions)))
+    (tab-bar-close-other-tabs)
+
+    (let* ((tabs (funcall tab-bar-tabs-function))
+           (current-index (tab-bar--current-tab-index tabs))
+           (current-tab (and current-index (nth current-index tabs))))
+      (when (and current-tab (equal (alist-get 'group current-tab)
+                                    close-group))
+        (tab-bar-close-tab)))))
+
 \f
 ;;; Tab history mode
 
@@ -1807,6 +1836,7 @@ When `switch-to-buffer-obey-display-actions' is non-nil,
 (defalias 'tab-duplicate   'tab-bar-duplicate-tab)
 (defalias 'tab-close       'tab-bar-close-tab)
 (defalias 'tab-close-other 'tab-bar-close-other-tabs)
+(defalias 'tab-close-group 'tab-bar-close-group-tabs)
 (defalias 'tab-undo        'tab-bar-undo-close-tab)
 (defalias 'tab-select      'tab-bar-select-tab)
 (defalias 'tab-switch      'tab-bar-switch-to-tab)