1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-04 02:51:31 -08:00

Improve customization.

* lisp/tab-bar.el (tab-bar-new-tab-choice)
(tab-bar-close-button-show): New defcustoms.
(tab-bar-tab-name-function): New defvar.

* lisp/tab-line.el (tab-line-new-tab-choice)
(tab-line-close-button-show): New defcustoms.
This commit is contained in:
Juri Linkov 2019-09-25 23:21:37 +03:00
parent 848e21b049
commit e47c389cfd
2 changed files with 178 additions and 72 deletions

View file

@ -121,7 +121,7 @@ on a console which has no window system but does have a mouse."
(setq column (+ column (length (nth 1 binding)))))) (setq column (+ column (length (nth 1 binding))))))
keymap)) keymap))
;; Clicking anywhere outside existing tabs will add a new tab ;; Clicking anywhere outside existing tabs will add a new tab
(tab-bar-add-tab))))) (tab-bar-new-tab)))))
;; Used in the Show/Hide menu, to have the toggle reflect the current frame. ;; Used in the Show/Hide menu, to have the toggle reflect the current frame.
(defun toggle-tab-bar-mode-from-frame (&optional arg) (defun toggle-tab-bar-mode-from-frame (&optional arg)
@ -152,9 +152,27 @@ Its main job is to show tabs in the tab bar."
(puthash key tab-bar-map tab-bar-keymap-cache))))) (puthash key tab-bar-map tab-bar-keymap-cache)))))
(defvar tab-bar-separator nil) (defcustom tab-bar-new-tab-choice t
"Defines what to show in a new tab.
If t, start a new tab with the current buffer, i.e. the buffer
that was current before calling the command that adds a new tab
(this is the same what `make-frame' does by default).
If the value is a string, switch to a buffer if it exists, or switch
to a buffer visiting the file or directory that the string specifies.
If the value is a function, call it with no arguments and switch to
the buffer that it returns.
If nil, duplicate the contents of the tab that was active
before calling the command that adds a new tab."
:type '(choice (const :tag "Current buffer" t)
(directory :tag "Directory" :value "~/")
(file :tag "File" :value "~/.emacs")
(string :tag "Buffer" "*scratch*")
(function :tag "Function")
(const :tag "Duplicate tab" nil))
:group 'tab-bar
:version "27.1")
(defvar tab-bar-button-new (defvar tab-bar-new-button
(propertize " + " (propertize " + "
'display `(image :type xpm 'display `(image :type xpm
:file ,(expand-file-name :file ,(expand-file-name
@ -164,7 +182,23 @@ Its main job is to show tabs in the tab bar."
:ascent center)) :ascent center))
"Button for creating a new tab.") "Button for creating a new tab.")
(defvar tab-bar-button-close (defcustom tab-bar-close-button-show t
"Defines where to show the close tab button.
If t, show the close tab button on all tabs.
If `selected', show it only on the selected tab.
If `non-selected', show it only on non-selected tab.
If nil, don't show it at all."
:type '(choice (const :tag "On all tabs" t)
(const :tag "On selected tab" selected)
(const :tag "On non-selected tabs" non-selected)
(const :tag "None" nil))
:set (lambda (sym val)
(set sym val)
(force-mode-line-update))
:group 'tab-bar
:version "27.1")
(defvar tab-bar-close-button
(propertize " x" (propertize " x"
'display `(image :type xpm 'display `(image :type xpm
:file ,(expand-file-name :file ,(expand-file-name
@ -176,12 +210,21 @@ Its main job is to show tabs in the tab bar."
:help "Click to close tab") :help "Click to close tab")
"Button for closing the clicked tab.") "Button for closing the clicked tab.")
(defvar tab-bar-separator nil)
(defvar tab-bar-tab-name-function #'tab-bar-tab-name
"Function to get a tab name.
Function gets no arguments.
By default, use function `tab-bar-tab-name'.")
(defun tab-bar-tab-name () (defun tab-bar-tab-name ()
"Generate tab name in the context of the selected frame." "Generate tab name in the context of the selected frame."
(mapconcat (mapconcat #'buffer-name
(lambda (w) (buffer-name (window-buffer w))) (delete-dups (mapcar #'window-buffer
(window-list-1 (frame-first-window) 'nomini) (window-list-1 (frame-first-window)
", ")) 'nomini)))
", "))
(defvar tab-bar-tabs-function #'tab-bar-tabs (defvar tab-bar-tabs-function #'tab-bar-tabs
"Function to get a list of tabs to display in the tab bar. "Function to get a list of tabs to display in the tab bar.
@ -195,8 +238,12 @@ By default, use function `tab-bar-tabs'.")
Ensure the frame parameter `tabs' is pre-populated. Ensure the frame parameter `tabs' is pre-populated.
Return its existing value or a new value." Return its existing value or a new value."
(let ((tabs (frame-parameter nil 'tabs))) (let ((tabs (frame-parameter nil 'tabs)))
(unless tabs (if tabs
(setq tabs `((current-tab (name . ,(tab-bar-tab-name))))) ;; Update current tab name
(let ((name (assq 'name (assq 'current-tab tabs))))
(when name (setcdr name (funcall tab-bar-tab-name-function))))
;; Create default tabs
(setq tabs `((current-tab (name . ,(funcall tab-bar-tab-name-function)))))
(set-frame-parameter nil 'tabs tabs)) (set-frame-parameter nil 'tabs tabs))
tabs)) tabs))
@ -216,7 +263,10 @@ Return its existing value or a new value."
`((current-tab `((current-tab
menu-item menu-item
,(propertize (concat (cdr (assq 'name tab)) ,(propertize (concat (cdr (assq 'name tab))
(or tab-bar-button-close "")) (or (and tab-bar-close-button-show
(not (eq tab-bar-close-button-show
'non-selected))
tab-bar-close-button) ""))
'face 'tab-bar-tab) 'face 'tab-bar-tab)
ignore ignore
:help "Current tab"))) :help "Current tab")))
@ -224,21 +274,28 @@ Return its existing value or a new value."
`((,(intern (format "tab-%i" i)) `((,(intern (format "tab-%i" i))
menu-item menu-item
,(propertize (concat (cdr (assq 'name tab)) ,(propertize (concat (cdr (assq 'name tab))
(or tab-bar-button-close "")) (or (and tab-bar-close-button-show
(not (eq tab-bar-close-button-show
'selected))
tab-bar-close-button) ""))
'face 'tab-bar-tab-inactive) 'face 'tab-bar-tab-inactive)
,(lambda () ,(or
(interactive) (cdr (assq 'binding tab))
(tab-bar-select-tab tab)) (lambda ()
(interactive)
(tab-bar-select-tab tab)))
:help "Click to visit tab")))) :help "Click to visit tab"))))
`((,(if (eq (car tab) 'current-tab) 'C-current-tab (intern (format "C-tab-%i" i))) `((,(if (eq (car tab) 'current-tab) 'C-current-tab (intern (format "C-tab-%i" i)))
menu-item "" menu-item ""
,(lambda () ,(or
(interactive) (cdr (assq 'close-binding tab))
(tab-bar-close-tab tab)))))) (lambda ()
(interactive)
(tab-bar-close-tab tab)))))))
(funcall tab-bar-tabs-function)) (funcall tab-bar-tabs-function))
(when tab-bar-button-new (when tab-bar-new-button
`((sep-add-tab menu-item ,separator ignore) `((sep-add-tab menu-item ,separator ignore)
(add-tab menu-item ,tab-bar-button-new tab-bar-add-tab (add-tab menu-item ,tab-bar-new-button tab-bar-new-tab
:help "New tab")))))) :help "New tab"))))))
@ -255,9 +312,9 @@ Return its existing value or a new value."
(when (equal (cdr (assq 'name tab)) tab-name) (when (equal (cdr (assq 'name tab)) tab-name)
(throw 'done tab)))))) (throw 'done tab))))))
(defun tab-bar-new-tab () (defun tab-bar-tab-default ()
(let ((tab `(tab (let ((tab `(tab
(name . ,(tab-bar-tab-name)) (name . ,(funcall tab-bar-tab-name-function))
(time . ,(time-convert nil 'integer)) (time . ,(time-convert nil 'integer))
(wc . ,(current-window-configuration)) (wc . ,(current-window-configuration))
(ws . ,(window-state-get (ws . ,(window-state-get
@ -278,7 +335,7 @@ Return its existing value or a new value."
(interactive (list (tab-bar-read-tab-name "Select tab by name: "))) (interactive (list (tab-bar-read-tab-name "Select tab by name: ")))
(when (and tab (not (eq (car tab) 'current-tab))) (when (and tab (not (eq (car tab) 'current-tab)))
(let* ((tabs (tab-bar-tabs)) (let* ((tabs (tab-bar-tabs))
(new-tab (tab-bar-new-tab)) (new-tab (tab-bar-tab-default))
(wc (cdr (assq 'wc tab)))) (wc (cdr (assq 'wc tab))))
;; During the same session, use window-configuration to switch ;; During the same session, use window-configuration to switch
;; tabs, because window-configurations are more reliable ;; tabs, because window-configurations are more reliable
@ -293,11 +350,11 @@ Return its existing value or a new value."
(while tabs (while tabs
(cond (cond
((eq (car tabs) tab) ((eq (car tabs) tab)
(setcar tabs `(current-tab (name . ,(tab-bar-tab-name))))) (setcar tabs `(current-tab (name . ,(funcall tab-bar-tab-name-function)))))
((eq (car (car tabs)) 'current-tab) ((eq (car (car tabs)) 'current-tab)
(setcar tabs new-tab))) (setcar tabs new-tab)))
(setq tabs (cdr tabs))) (setq tabs (cdr tabs)))
(force-window-update)))) (force-mode-line-update))))
(defun tab-bar-switch-to-prev-tab (&optional _arg) (defun tab-bar-switch-to-prev-tab (&optional _arg)
"Switch to ARGth previous tab." "Switch to ARGth previous tab."
@ -316,7 +373,7 @@ Return its existing value or a new value."
(tab-bar-select-tab (car (cdr tabs)))))) (tab-bar-select-tab (car (cdr tabs))))))
(defcustom tab-bar-add-tab-to 'right (defcustom tab-bar-new-tab-to 'right
"Defines where to create a new tab. "Defines where to create a new tab.
If `leftmost', create as the first tab. If `leftmost', create as the first tab.
If `left', create to the left from the current tab. If `left', create to the left from the current tab.
@ -326,35 +383,46 @@ If `rightmost', create as the last tab."
(const :tag "To the left" left) (const :tag "To the left" left)
(const :tag "To the right" right) (const :tag "To the right" right)
(const :tag "Last tab" rightmost)) (const :tag "Last tab" rightmost))
:group 'tab-bar
:version "27.1") :version "27.1")
(defun tab-bar-add-tab () (defun tab-bar-new-tab ()
"Clone the current tab to the position specified by `tab-bar-add-tab-to'." "Clone the current tab to the position specified by `tab-bar-new-tab-to'."
(interactive) (interactive)
(unless tab-bar-mode (unless tab-bar-mode
(tab-bar-mode 1)) (tab-bar-mode 1))
(let* ((tabs (tab-bar-tabs)) (let* ((tabs (tab-bar-tabs))
;; (i-tab (- (length tabs) (length (memq tab tabs)))) ;; (i-tab (- (length tabs) (length (memq tab tabs))))
(new-tab (tab-bar-new-tab))) (new-tab (tab-bar-tab-default)))
(cond (cond
((eq tab-bar-add-tab-to 'leftmost) ((eq tab-bar-new-tab-to 'leftmost)
(setq tabs (cons new-tab tabs))) (setq tabs (cons new-tab tabs)))
((eq tab-bar-add-tab-to 'rightmost) ((eq tab-bar-new-tab-to 'rightmost)
(setq tabs (append tabs (list new-tab)))) (setq tabs (append tabs (list new-tab))))
(t (t
(let ((prev-tab (tab-bar-find-prev-tab tabs))) (let ((prev-tab (tab-bar-find-prev-tab tabs)))
(cond (cond
((eq tab-bar-add-tab-to 'left) ((eq tab-bar-new-tab-to 'left)
(if prev-tab (if prev-tab
(setcdr prev-tab (cons new-tab (cdr prev-tab))) (setcdr prev-tab (cons new-tab (cdr prev-tab)))
(setq tabs (cons new-tab tabs)))) (setq tabs (cons new-tab tabs))))
((eq tab-bar-add-tab-to 'right) ((eq tab-bar-new-tab-to 'right)
(if prev-tab (if prev-tab
(setq prev-tab (cdr prev-tab)) (setq prev-tab (cdr prev-tab))
(setq prev-tab tabs)) (setq prev-tab tabs))
(setcdr prev-tab (cons new-tab (cdr prev-tab)))))))) (setcdr prev-tab (cons new-tab (cdr prev-tab))))))))
(set-frame-parameter nil 'tabs tabs) (set-frame-parameter nil 'tabs tabs)
(tab-bar-select-tab new-tab) (tab-bar-select-tab new-tab)
(when tab-bar-new-tab-choice
(delete-other-windows)
(let ((buffer
(if (functionp tab-bar-new-tab-choice)
(funcall tab-bar-new-tab-choice)
(if (stringp tab-bar-new-tab-choice)
(or (get-buffer tab-bar-new-tab-choice)
(find-file-noselect tab-bar-new-tab-choice))))))
(when (buffer-live-p buffer)
(switch-to-buffer buffer))))
(unless tab-bar-mode (unless tab-bar-mode
(message "Added new tab with the current window configuration")))) (message "Added new tab with the current window configuration"))))
@ -365,6 +433,7 @@ If `left', select the adjacent left tab.
If `right', select the adjacent right tab." If `right', select the adjacent right tab."
:type '(choice (const :tag "Select left tab" left) :type '(choice (const :tag "Select left tab" left)
(const :tag "Select right tab" right)) (const :tag "Select right tab" right))
:group 'tab-bar
:version "27.1") :version "27.1")
(defun tab-bar-close-current-tab (&optional tab select-tab) (defun tab-bar-close-current-tab (&optional tab select-tab)
@ -407,29 +476,30 @@ specified by `tab-bar-close-tab-select'."
(tab-bar-close-current-tab tab) (tab-bar-close-current-tab tab)
;; Close non-current tab, no need to switch to another tab ;; Close non-current tab, no need to switch to another tab
(set-frame-parameter nil 'tabs (delq tab (tab-bar-tabs))) (set-frame-parameter nil 'tabs (delq tab (tab-bar-tabs)))
(force-window-update)))) (force-mode-line-update))))
;;; Non-graphical access to frame-local tabs (named window configurations) ;;; Non-graphical access to frame-local tabs (named window configurations)
(defun make-tab () (defun tab-make ()
"Create a new named window configuration without having to click a tab." "Create a new named window configuration without having to click a tab."
(interactive) (interactive)
(tab-bar-add-tab) (tab-bar-new-tab)
(unless tab-bar-mode (unless tab-bar-mode
(message "Added new tab with the current window configuration"))) (message "Added new tab with the current window configuration")))
(defun delete-tab () (defun tab-delete ()
"Delete the current window configuration without clicking a close button." "Delete the current window configuration without clicking a close button."
(interactive) (interactive)
(tab-bar-close-current-tab) (tab-bar-close-current-tab)
(unless tab-bar-mode (unless tab-bar-mode
(message "Deleted the current tab"))) (message "Deleted the current tab")))
(defalias 'list-tabs 'tab-bar-list) ;; Short aliases
(defalias 'switch-to-tab 'tab-bar-select-tab) ;; (defalias 'tab-switch 'tab-bar-switch-to-next-tab)
(defalias 'previous-tab 'tab-bar-switch-to-prev-tab) (defalias 'tab-select 'tab-bar-select-tab)
(defalias 'next-tab 'tab-bar-switch-to-next-tab) (defalias 'tab-previous 'tab-bar-switch-to-prev-tab)
(defalias 'tab-next 'tab-bar-switch-to-next-tab)
(defun tab-bar-list () (defun tab-bar-list ()
"Display a list of named window configurations. "Display a list of named window configurations.
@ -445,7 +515,7 @@ marked for deletion."
(let ((dir default-directory) (let ((dir default-directory)
(minibuf (minibuffer-selected-window))) (minibuf (minibuffer-selected-window)))
(let ((tab-bar-mode t)) ; don't enable tab-bar-mode if it's disabled (let ((tab-bar-mode t)) ; don't enable tab-bar-mode if it's disabled
(tab-bar-add-tab)) (tab-bar-new-tab))
;; Handle the case when it's called in the active minibuffer. ;; Handle the case when it's called in the active minibuffer.
(when minibuf (select-window (minibuffer-selected-window))) (when minibuf (select-window (minibuffer-selected-window)))
(delete-other-windows) (delete-other-windows)
@ -541,9 +611,9 @@ Letters do not insert themselves; instead, they are commands.
(defun tab-bar-list-current-tab (error-if-non-existent-p) (defun tab-bar-list-current-tab (error-if-non-existent-p)
"Return window configuration described by this line of the list." "Return window configuration described by this line of the list."
(let* ((where (save-excursion (let* ((where (save-excursion
(beginning-of-line) (beginning-of-line)
(+ 2 (point) tab-bar-list-column))) (+ 2 (point) tab-bar-list-column)))
(tab (and (not (eobp)) (get-text-property where 'tab)))) (tab (and (not (eobp)) (get-text-property where 'tab))))
(or tab (or tab
(if error-if-non-existent-p (if error-if-non-existent-p
(user-error "No window configuration on this line") (user-error "No window configuration on this line")
@ -621,16 +691,16 @@ Then move up one line. Prefix arg means move that many lines."
(while (re-search-forward (while (re-search-forward
(format "^%sD" (make-string tab-bar-list-column ?\040)) (format "^%sD" (make-string tab-bar-list-column ?\040))
nil t) nil t)
(forward-char -1) (forward-char -1)
(let ((tab (tab-bar-list-current-tab nil))) (let ((tab (tab-bar-list-current-tab nil)))
(when tab (when tab
(tab-bar-list-delete-from-list tab) (tab-bar-list-delete-from-list tab)
(beginning-of-line) (beginning-of-line)
(delete-region (point) (progn (forward-line 1) (point)))))))) (delete-region (point) (progn (forward-line 1) (point))))))))
(beginning-of-line) (beginning-of-line)
(move-to-column tab-bar-list-column) (move-to-column tab-bar-list-column)
(when tab-bar-mode (when tab-bar-mode
(force-window-update))) (force-mode-line-update)))
(defun tab-bar-list-select () (defun tab-bar-list-select ()
"Select this line's window configuration. "Select this line's window configuration.
@ -662,7 +732,7 @@ in the selected frame."
Like \\[switch-to-buffer-other-frame] (which see), but creates a new tab." Like \\[switch-to-buffer-other-frame] (which see), but creates a new tab."
(interactive (interactive
(list (read-buffer-to-switch "Switch to buffer in other tab: "))) (list (read-buffer-to-switch "Switch to buffer in other tab: ")))
(tab-bar-add-tab) (tab-bar-new-tab)
(delete-other-windows) (delete-other-windows)
(switch-to-buffer buffer-or-name norecord)) (switch-to-buffer buffer-or-name norecord))
@ -674,14 +744,14 @@ Like \\[find-file-other-frame] (which see), but creates a new tab."
(confirm-nonexistent-file-or-buffer))) (confirm-nonexistent-file-or-buffer)))
(let ((value (find-file-noselect filename nil nil wildcards))) (let ((value (find-file-noselect filename nil nil wildcards)))
(if (listp value) (if (listp value)
(progn (progn
(setq value (nreverse value)) (setq value (nreverse value))
(switch-to-buffer-other-tab (car value)) (switch-to-buffer-other-tab (car value))
(mapc 'switch-to-buffer (cdr value)) (mapc 'switch-to-buffer (cdr value))
value) value)
(switch-to-buffer-other-tab value)))) (switch-to-buffer-other-tab value))))
(define-key ctl-x-6-map "2" 'tab-bar-add-tab) (define-key ctl-x-6-map "2" 'tab-bar-new-tab)
(define-key ctl-x-6-map "0" 'tab-bar-close-current-tab) (define-key ctl-x-6-map "0" 'tab-bar-close-current-tab)
(define-key ctl-x-6-map "b" 'switch-to-buffer-other-tab) (define-key ctl-x-6-map "b" 'switch-to-buffer-other-tab)
(define-key ctl-x-6-map "f" 'find-file-other-tab) (define-key ctl-x-6-map "f" 'find-file-other-tab)

View file

@ -99,9 +99,9 @@
(defvar tab-line-add-map (defvar tab-line-add-map
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(define-key map [tab-line mouse-1] 'tab-line-add-tab) (define-key map [tab-line mouse-1] 'tab-line-new-tab)
(define-key map [tab-line mouse-2] 'tab-line-add-tab) (define-key map [tab-line mouse-2] 'tab-line-new-tab)
(define-key map "\C-m" 'tab-line-add-tab) (define-key map "\C-m" 'tab-line-new-tab)
map) map)
"Local keymap to add `tab-line-mode' window tabs.") "Local keymap to add `tab-line-mode' window tabs.")
@ -113,12 +113,18 @@
"Local keymap to close `tab-line-mode' window tabs.") "Local keymap to close `tab-line-mode' window tabs.")
(defvar tab-line-separator nil) (defcustom tab-line-new-tab-choice t
"Defines what to show in a new tab.
If t, display a selection menu with all available buffers.
If the value is a function, call it with no arguments.
If nil, don't show the new tab button."
:type '(choice (const :tag "Buffer menu" t)
(function :tag "Function")
(const :tag "No button" nil))
:group 'tab-line
:version "27.1")
(defvar tab-line-tab-name-ellipsis (defvar tab-line-new-button
(if (char-displayable-p ?…) "" "..."))
(defvar tab-line-button-new
(propertize " + " (propertize " + "
'display `(image :type xpm 'display `(image :type xpm
:file ,(expand-file-name :file ,(expand-file-name
@ -131,7 +137,23 @@
'help-echo "Click to add tab") 'help-echo "Click to add tab")
"Button for creating a new tab.") "Button for creating a new tab.")
(defvar tab-line-button-close (defcustom tab-line-close-button-show t
"Defines where to show the close tab button.
If t, show the close tab button on all tabs.
If `selected', show it only on the selected tab.
If `non-selected', show it only on non-selected tab.
If nil, don't show it at all."
:type '(choice (const :tag "On all tabs" t)
(const :tag "On selected tab" selected)
(const :tag "On non-selected tabs" non-selected)
(const :tag "None" nil))
:set (lambda (sym val)
(set sym val)
(force-mode-line-update))
:group 'tab-line
:version "27.1")
(defvar tab-line-close-button
(propertize " x" (propertize " x"
'display `(image :type xpm 'display `(image :type xpm
:file ,(expand-file-name :file ,(expand-file-name
@ -144,6 +166,11 @@
'help-echo "Click to close tab") 'help-echo "Click to close tab")
"Button for closing the clicked tab.") "Button for closing the clicked tab.")
(defvar tab-line-separator nil)
(defvar tab-line-tab-name-ellipsis
(if (char-displayable-p ?…) "" "..."))
(defvar tab-line-tab-name-function #'tab-line-tab-name (defvar tab-line-tab-name-function #'tab-line-tab-name
"Function to get a tab name. "Function to get a tab name.
@ -218,7 +245,12 @@ variable `tab-line-tabs-function'."
(apply 'propertize (concat (propertize (apply 'propertize (concat (propertize
(funcall tab-line-tab-name-function tab tabs) (funcall tab-line-tab-name-function tab tabs)
'keymap tab-line-tab-map) 'keymap tab-line-tab-map)
tab-line-button-close) (or (and tab-line-close-button-show
(not (eq tab-line-close-button-show
(if (eq tab selected-buffer)
'non-selected
'selected)))
tab-line-close-button) ""))
`( `(
tab ,tab tab ,tab
face ,(if (eq tab selected-buffer) face ,(if (eq tab selected-buffer)
@ -226,15 +258,19 @@ variable `tab-line-tabs-function'."
'tab-line-tab-inactive) 'tab-line-tab-inactive)
mouse-face tab-line-highlight)))) mouse-face tab-line-highlight))))
tabs) tabs)
(list (concat separator tab-line-button-new))))) (list (concat separator (when tab-line-new-tab-choice
tab-line-new-button))))))
(defun tab-line-add-tab (&optional e) (defun tab-line-new-tab (&optional e)
"Add a new tab."
(interactive "e") (interactive "e")
(if window-system ; (display-popup-menus-p) (if (functionp tab-line-new-tab-choice)
(mouse-buffer-menu e) ; like (buffer-menu-open) (funcall tab-line-new-tab-choice)
;; tty menu doesn't support mouse clicks, so use tmm (if window-system ; (display-popup-menus-p)
(tmm-prompt (mouse-buffer-menu-keymap)))) (mouse-buffer-menu e) ; like (buffer-menu-open)
;; tty menu doesn't support mouse clicks, so use tmm
(tmm-prompt (mouse-buffer-menu-keymap)))))
(defun tab-line-select-tab (&optional e) (defun tab-line-select-tab (&optional e)
"Switch to the selected tab. "Switch to the selected tab.