Function: tab-bar-close-tab

tab-bar-close-tab is an interactive and byte-compiled function defined in tab-bar.el.gz.

Signature

(tab-bar-close-tab &optional TAB-NUMBER TO-NUMBER)

Documentation

Close the tab specified by its absolute position TAB-NUMBER.

If no TAB-NUMBER is specified, then close the current tab and switch to the tab specified by tab-bar-close-tab-select. Interactively, TAB-NUMBER is the prefix numeric argument, and defaults to 1. TAB-NUMBER counts from 1. Optional TO-NUMBER could be specified to override the value of tab-bar-close-tab-select programmatically with a position of an existing tab to select after closing the current tab. TO-NUMBER counts from 1.

The functions in tab-bar-tab-prevent-close-functions will be run to determine whether or not to close the tab. Just before the tab is closed, the functions in tab-bar-tab-pre-close-functions will be run. The base behavior for the last tab on a frame is determined by tab-bar-close-last-tab-choice.

Key Bindings

Aliases

tab-close

Source Code

;; Defined in /usr/src/emacs/lisp/tab-bar.el.gz
(defun tab-bar-close-tab (&optional tab-number to-number)
  "Close the tab specified by its absolute position TAB-NUMBER.
If no TAB-NUMBER is specified, then close the current tab and switch
to the tab specified by `tab-bar-close-tab-select'.
Interactively, TAB-NUMBER is the prefix numeric argument, and defaults to 1.
TAB-NUMBER counts from 1.
Optional TO-NUMBER could be specified to override the value of
`tab-bar-close-tab-select' programmatically with a position
of an existing tab to select after closing the current tab.
TO-NUMBER counts from 1.

The functions in `tab-bar-tab-prevent-close-functions' will be
run to determine whether or not to close the tab.
Just before the tab is closed, the functions in
`tab-bar-tab-pre-close-functions' will be run.  The base behavior
for the last tab on a frame is determined by
`tab-bar-close-last-tab-choice'."
  (interactive "P")
  (let* ((tabs (funcall tab-bar-tabs-function))
         (current-index (tab-bar--current-tab-index tabs))
         (close-index (if (integerp tab-number) (1- tab-number) current-index))
         (last-tab-p (= 1 (length tabs)))
         (prevent-close (run-hook-with-args-until-success
                         'tab-bar-tab-prevent-close-functions
                         (nth close-index tabs)
                         last-tab-p)))

    (unless prevent-close
      (run-hook-with-args 'tab-bar-tab-pre-close-functions
                          (nth close-index tabs)
                          last-tab-p)

      (if last-tab-p
          (pcase tab-bar-close-last-tab-choice
            ('nil
             (user-error "Attempt to delete the sole tab in a frame"))
            ('delete-frame
             (delete-frame))
            ('tab-bar-mode-disable
             (tab-bar-mode -1))
            ((pred functionp)
             ;; Give the handler function the full extent of the tab's
             ;; data, not just it's name and explicit-name flag.
             (funcall tab-bar-close-last-tab-choice (tab-bar--tab))))

        ;; More than one tab still open
        (when (eq current-index close-index)
          ;; Select another tab before deleting the current tab
          (let ((to-index (or (if to-number (1- to-number))
                              (pcase tab-bar-close-tab-select
                                ('left (1- (if (< current-index 1) 2
                                             current-index)))
                                ('right (if (> (length tabs) (1+ current-index))
                                            (1+ current-index)
                                          (1- current-index)))
                                ('recent (tab-bar--tab-index-recent 1 tabs))))))
            (setq to-index (max 0 (min (or to-index 0) (1- (length tabs)))))
            (let ((inhibit-message t)) ; avoid message about selected tab
              (tab-bar-select-tab (1+ to-index)))
            ;; Re-read tabs after selecting another tab
            (setq tabs (funcall tab-bar-tabs-function))))

        (let ((close-tab (nth close-index tabs)))
          (push `((frame . ,(selected-frame))
                  (index . ,close-index)
                  (tab . ,(if (eq (car close-tab) 'current-tab)
                              (tab-bar--tab)
                            close-tab)))
                tab-bar-closed-tabs)
          (tab-bar-tabs-set (delq close-tab tabs)))

        ;; Recalculate `tab-bar-lines' and update frames
        (tab-bar--update-tab-bar-lines)

        (force-mode-line-update)
        (unless tab-bar-mode
          (message "Deleted tab and switched to %s"
                   tab-bar-close-tab-select))))))