aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Cochran2019-10-23 17:34:24 -0700
committerJuri Linkov2019-10-27 00:41:45 +0300
commit6d2ea60ca874f04c37527b21355f81a2b140d405 (patch)
tree1100ad4a2e5f76f28ada4ce1e55e8bf5609f1e7e
parentf247599e167d34be93badd693a8b4de15daa0a8e (diff)
downloademacs-6d2ea60ca874f04c37527b21355f81a2b140d405.tar.gz
emacs-6d2ea60ca874f04c37527b21355f81a2b140d405.zip
Add customization option for what do when the last tab is closed
* lisp/tab-bar.el (tab-bar-close-last-tab-choice): New custom variable. (tab-bar-close-tab): Handle closing the last tab specially, referring to tab-bar-close-last-tab-choice.
-rw-r--r--lisp/tab-bar.el84
1 files changed, 54 insertions, 30 deletions
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index 617057cf460..d664774b6c0 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -634,6 +634,19 @@ If `right', select the adjacent right tab."
634 :group 'tab-bar 634 :group 'tab-bar
635 :version "27.1") 635 :version "27.1")
636 636
637(defcustom tab-bar-close-last-tab-choice nil
638 "Defines what to do when the last tab is closed.
639If nil, do nothing and show a message, like closing the last window or frame.
640If `close-frame', delete the containing frame, as a web browser would do.
641If `disable-tab-bar', disable tab-bar-mode so that tabs no longer show in the frame.
642If the value is a function, call that function with the tab to be closed as an argument."
643 :type '(choice (const :tag "Do nothing and show message" nil)
644 (const :tag "Delete the containing frame" close-frame)
645 (const :tag "Disable tab-bar-mode" disable-tab-bar)
646 (function :tag "Function"))
647 :group 'tab-bar
648 :version "27.1")
649
637(defun tab-bar-close-tab (&optional arg to-index) 650(defun tab-bar-close-tab (&optional arg to-index)
638 "Close the tab specified by its absolute position ARG. 651 "Close the tab specified by its absolute position ARG.
639If no ARG is specified, then close the current tab and switch 652If no ARG is specified, then close the current tab and switch
@@ -647,38 +660,49 @@ TO-INDEX counts from 1."
647 (let* ((tabs (funcall tab-bar-tabs-function)) 660 (let* ((tabs (funcall tab-bar-tabs-function))
648 (current-index (tab-bar--current-tab-index tabs)) 661 (current-index (tab-bar--current-tab-index tabs))
649 (close-index (if (integerp arg) (1- arg) current-index))) 662 (close-index (if (integerp arg) (1- arg) current-index)))
663 (if (= 1 (length tabs))
664 (pcase tab-bar-close-last-tab-choice
665 ('nil
666 (signal 'user-error '("Attempt to delete the sole tab in a frame")))
667 ('close-frame
668 (delete-frame))
669 ('disable-tab-bar
670 (tab-bar-mode -1))
671 ((pred functionp)
672 ;; Give the handler function the full extent of the tab's
673 ;; data, not just it's name and explicit-name flag.
674 (funcall tab-bar-close-last-tab-choice (tab-bar--tab))))
675
676 ;;; More than one tab still open
677 (when (eq current-index close-index)
678 (let ((to-index (or (if to-index (1- to-index))
679 (pcase tab-bar-close-tab-select
680 ('left (1- current-index))
681 ('right (if (> (length tabs) (1+ current-index))
682 (1+ current-index)
683 (1- current-index)))))))
684 (setq to-index (max 0 (min (or to-index 0) (1- (length tabs)))))
685 (tab-bar-select-tab (1+ to-index))
686 ;; Re-read tabs after selecting another tab
687 (setq tabs (funcall tab-bar-tabs-function))))
688
689 (let ((close-tab (nth close-index tabs)))
690 (push `((frame . ,(selected-frame))
691 (index . ,close-index)
692 (tab . ,(if (eq (car close-tab) 'current-tab)
693 (tab-bar--tab)
694 close-tab)))
695 tab-bar-closed-tabs)
696 (set-frame-parameter nil 'tabs (delq close-tab tabs)))
650 697
651 ;; Select another tab before deleting the current tab 698 (when (and tab-bar-mode
652 (when (eq current-index close-index) 699 (and (natnump tab-bar-show)
653 (let ((to-index (or (if to-index (1- to-index)) 700 (<= (length tabs) tab-bar-show)))
654 (pcase tab-bar-close-tab-select 701 (tab-bar-mode -1))
655 ('left (1- current-index))
656 ('right (if (> (length tabs) (1+ current-index))
657 (1+ current-index)
658 (1- current-index)))))))
659 (setq to-index (max 0 (min (or to-index 0) (1- (length tabs)))))
660 (tab-bar-select-tab (1+ to-index))
661 ;; Re-read tabs after selecting another tab
662 (setq tabs (funcall tab-bar-tabs-function))))
663
664 (let ((close-tab (nth close-index tabs)))
665 (push `((frame . ,(selected-frame))
666 (index . ,close-index)
667 (tab . ,(if (eq (car close-tab) 'current-tab)
668 (tab-bar--tab)
669 close-tab)))
670 tab-bar-closed-tabs)
671 (set-frame-parameter nil 'tabs (delq close-tab tabs)))
672
673 (when (and tab-bar-mode
674 (or (<= (length tabs) 1) ; closed the last tab
675 (and (natnump tab-bar-show)
676 (<= (length tabs) tab-bar-show))))
677 (tab-bar-mode -1))
678 702
679 (force-mode-line-update) 703 (force-mode-line-update)
680 (unless tab-bar-mode 704 (unless tab-bar-mode
681 (message "Deleted tab and switched to %s" tab-bar-close-tab-select)))) 705 (message "Deleted tab and switched to %s" tab-bar-close-tab-select)))))
682 706
683(defun tab-bar-close-tab-by-name (name) 707(defun tab-bar-close-tab-by-name (name)
684 "Close the tab by NAME." 708 "Close the tab by NAME."