aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/tab-bar.el404
1 files changed, 217 insertions, 187 deletions
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index 6d2c915aa67..d8d9bdac26d 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -34,6 +34,8 @@
34 34
35;;; Code: 35;;; Code:
36 36
37(eval-when-compile (require 'cl-lib))
38
37 39
38(defgroup tab-bar nil 40(defgroup tab-bar nil
39 "Frame-local tabs." 41 "Frame-local tabs."
@@ -179,16 +181,16 @@ keyboard commands `tab-list', `tab-new', `tab-close', `tab-next', etc."
179If t, start a new tab with the current buffer, i.e. the buffer 181If t, start a new tab with the current buffer, i.e. the buffer
180that was current before calling the command that adds a new tab 182that was current before calling the command that adds a new tab
181(this is the same what `make-frame' does by default). 183(this is the same what `make-frame' does by default).
182If the value is a string, switch to a buffer if it exists, or switch 184If the value is a string, use it as a buffer name switch to a buffer
183to a buffer visiting the file or directory that the string specifies. 185if such buffer exists, or switch to a buffer visiting the file or
184If the value is a function, call it with no arguments and switch to 186directory that the string specifies. If the value is a function,
185the buffer that it returns. 187call it with no arguments and switch to the buffer that it returns.
186If nil, duplicate the contents of the tab that was active 188If nil, duplicate the contents of the tab that was active
187before calling the command that adds a new tab." 189before calling the command that adds a new tab."
188 :type '(choice (const :tag "Current buffer" t) 190 :type '(choice (const :tag "Current buffer" t)
191 (string :tag "Buffer" "*scratch*")
189 (directory :tag "Directory" :value "~/") 192 (directory :tag "Directory" :value "~/")
190 (file :tag "File" :value "~/.emacs") 193 (file :tag "File" :value "~/.emacs")
191 (string :tag "Buffer" "*scratch*")
192 (function :tag "Function") 194 (function :tag "Function")
193 (const :tag "Duplicate tab" nil)) 195 (const :tag "Duplicate tab" nil))
194 :group 'tab-bar 196 :group 'tab-bar
@@ -233,6 +235,17 @@ If nil, don't show it at all."
233 :help "Click to close tab") 235 :help "Click to close tab")
234 "Button for closing the clicked tab.") 236 "Button for closing the clicked tab.")
235 237
238(defcustom tab-bar-tab-hints nil
239 "Show absolute numbers on tabs in the tab bar before the tab name.
240This helps to select the tab by its number using `tab-bar-select-tab'."
241 :type 'boolean
242 :initialize 'custom-initialize-default
243 :set (lambda (sym val)
244 (set-default sym val)
245 (force-mode-line-update))
246 :group 'tab-bar
247 :version "27.1")
248
236(defvar tab-bar-separator nil) 249(defvar tab-bar-separator nil)
237 250
238 251
@@ -261,19 +274,20 @@ By default, use function `tab-bar-tabs'.")
261Ensure the frame parameter `tabs' is pre-populated. 274Ensure the frame parameter `tabs' is pre-populated.
262Return its existing value or a new value." 275Return its existing value or a new value."
263 (let ((tabs (frame-parameter nil 'tabs))) 276 (let ((tabs (frame-parameter nil 'tabs)))
264 (if tabs 277 (unless tabs
265 ;; Update current tab name
266 (let ((name (assq 'name (assq 'current-tab tabs))))
267 (when name (setcdr name (funcall tab-bar-tab-name-function))))
268 ;; Create default tabs 278 ;; Create default tabs
269 (setq tabs `((current-tab (name . ,(funcall tab-bar-tab-name-function))))) 279 (setq tabs (list (tab-bar--current-tab)))
270 (set-frame-parameter nil 'tabs tabs)) 280 (set-frame-parameter nil 'tabs tabs))
271 tabs)) 281 tabs))
272 282
273(defun tab-bar-make-keymap-1 () 283(defun tab-bar-make-keymap-1 ()
274 "Generate an actual keymap from `tab-bar-map', without caching." 284 "Generate an actual keymap from `tab-bar-map', without caching."
275 (let ((separator (or tab-bar-separator (if window-system " " "|"))) 285 (let* ((separator (or tab-bar-separator (if window-system " " "|")))
276 (i 0)) 286 (i 0)
287 (tabs (funcall tab-bar-tabs-function))
288 (current-tab-name (assq 'name (assq 'current-tab tabs))))
289 (when current-tab-name
290 (setf (cdr current-tab-name) (funcall tab-bar-tab-name-function)))
277 (append 291 (append
278 '(keymap (mouse-1 . tab-bar-handle-mouse)) 292 '(keymap (mouse-1 . tab-bar-handle-mouse))
279 (mapcan 293 (mapcan
@@ -285,7 +299,8 @@ Return its existing value or a new value."
285 ((eq (car tab) 'current-tab) 299 ((eq (car tab) 'current-tab)
286 `((current-tab 300 `((current-tab
287 menu-item 301 menu-item
288 ,(propertize (concat (cdr (assq 'name tab)) 302 ,(propertize (concat (if tab-bar-tab-hints (format "%d " i) "")
303 (cdr (assq 'name tab))
289 (or (and tab-bar-close-button-show 304 (or (and tab-bar-close-button-show
290 (not (eq tab-bar-close-button-show 305 (not (eq tab-bar-close-button-show
291 'non-selected)) 306 'non-selected))
@@ -296,7 +311,8 @@ Return its existing value or a new value."
296 (t 311 (t
297 `((,(intern (format "tab-%i" i)) 312 `((,(intern (format "tab-%i" i))
298 menu-item 313 menu-item
299 ,(propertize (concat (cdr (assq 'name tab)) 314 ,(propertize (concat (if tab-bar-tab-hints (format "%d " i) "")
315 (cdr (assq 'name tab))
300 (or (and tab-bar-close-button-show 316 (or (and tab-bar-close-button-show
301 (not (eq tab-bar-close-button-show 317 (not (eq tab-bar-close-button-show
302 'selected)) 318 'selected))
@@ -304,97 +320,132 @@ Return its existing value or a new value."
304 'face 'tab-bar-tab-inactive) 320 'face 'tab-bar-tab-inactive)
305 ,(or 321 ,(or
306 (cdr (assq 'binding tab)) 322 (cdr (assq 'binding tab))
307 (lambda () 323 `(lambda ()
308 (interactive) 324 (interactive)
309 (tab-bar-select-tab tab))) 325 (tab-bar-select-tab ,i)))
310 :help "Click to visit tab")))) 326 :help "Click to visit tab"))))
311 `((,(if (eq (car tab) 'current-tab) 'C-current-tab (intern (format "C-tab-%i" i))) 327 `((,(if (eq (car tab) 'current-tab) 'C-current-tab (intern (format "C-tab-%i" i)))
312 menu-item "" 328 menu-item ""
313 ,(or 329 ,(or
314 (cdr (assq 'close-binding tab)) 330 (cdr (assq 'close-binding tab))
315 (lambda () 331 `(lambda ()
316 (interactive) 332 (interactive)
317 (tab-bar-close-tab tab))))))) 333 (tab-bar-close-tab ,i)))))))
318 (funcall tab-bar-tabs-function)) 334 tabs)
319 (when tab-bar-new-button 335 (when tab-bar-new-button
320 `((sep-add-tab menu-item ,separator ignore) 336 `((sep-add-tab menu-item ,separator ignore)
321 (add-tab menu-item ,tab-bar-new-button tab-bar-new-tab 337 (add-tab menu-item ,tab-bar-new-button tab-bar-new-tab
322 :help "New tab")))))) 338 :help "New tab"))))))
323 339
324 340
325(defun tab-bar-read-tab-name (prompt) 341(defun tab-bar--tab ()
326 (let* ((tabs (tab-bar-tabs)) 342 `(tab
327 (tab-name 343 (name . ,(funcall tab-bar-tab-name-function))
328 (completing-read prompt 344 (time . ,(time-convert nil 'integer))
329 (or (delq nil (mapcar (lambda (tab) 345 (wc . ,(current-window-configuration))
330 (cdr (assq 'name tab))) 346 (ws . ,(window-state-get
331 tabs)) 347 (frame-root-window (selected-frame)) 'writable))))
332 '(""))))) 348
349(defun tab-bar--current-tab ()
350 `(current-tab
351 (name . ,(funcall tab-bar-tab-name-function))))
352
353(defun tab-bar--current-tab-index (&optional tabs)
354 ;; FIXME: could be replaced with 1-liner using seq-position
355 (let ((tabs (or tabs (tab-bar-tabs)))
356 (i 0))
333 (catch 'done 357 (catch 'done
334 (dolist (tab tabs) 358 (while tabs
335 (when (equal (cdr (assq 'name tab)) tab-name) 359 (when (eq (car (car tabs)) 'current-tab)
336 (throw 'done tab)))))) 360 (throw 'done i))
337 361 (setq i (1+ i) tabs (cdr tabs))))))
338(defun tab-bar-tab-default ()
339 (let ((tab `(tab
340 (name . ,(funcall tab-bar-tab-name-function))
341 (time . ,(time-convert nil 'integer))
342 (wc . ,(current-window-configuration))
343 (ws . ,(window-state-get
344 (frame-root-window (selected-frame)) 'writable)))))
345 tab))
346
347(defun tab-bar-find-prev-tab (&optional tabs)
348 (unless tabs
349 (setq tabs (tab-bar-tabs)))
350 (unless (eq (car (car tabs)) 'current-tab)
351 (while (and tabs (not (eq (car (car (cdr tabs))) 'current-tab)))
352 (setq tabs (cdr tabs)))
353 tabs))
354 362
355 363(defun tab-bar--tab-index (tab &optional tabs)
356(defun tab-bar-select-tab (tab) 364 ;; FIXME: could be replaced with 1-liner using seq-position
357 "Switch to the specified TAB." 365 (let ((tabs (or tabs (tab-bar-tabs)))
358 (interactive (list (tab-bar-read-tab-name "Select tab by name: "))) 366 (i 0))
359 (when (and tab (not (eq (car tab) 'current-tab))) 367 (catch 'done
360 (let* ((tabs (tab-bar-tabs))
361 (new-tab (tab-bar-tab-default))
362 (wc (cdr (assq 'wc tab))))
363 ;; During the same session, use window-configuration to switch
364 ;; tabs, because window-configurations are more reliable
365 ;; (they keep references to live buffers) than window-states.
366 ;; But after restoring tabs from a previously saved session,
367 ;; its value of window-configuration is unreadable,
368 ;; so restore its saved window-state.
369 (if (window-configuration-p wc)
370 (set-window-configuration wc)
371 (window-state-put (cdr (assq 'ws tab))
372 (frame-root-window (selected-frame)) 'safe))
373 (while tabs 368 (while tabs
374 (cond 369 (when (eq (car tabs) tab)
375 ((eq (car tabs) tab) 370 (throw 'done i))
376 (setcar tabs `(current-tab (name . ,(funcall tab-bar-tab-name-function))))) 371 (setq i (1+ i) tabs (cdr tabs))))
377 ((eq (car (car tabs)) 'current-tab) 372 i))
378 (setcar tabs new-tab))) 373
379 (setq tabs (cdr tabs))) 374(defun tab-bar--tab-index-by-name (name &optional tabs)
375 ;; FIXME: could be replaced with 1-liner using seq-position
376 (let ((tabs (or tabs (tab-bar-tabs)))
377 (i 0))
378 (catch 'done
379 (while tabs
380 (when (equal (cdr (assq 'name (car tabs))) name)
381 (throw 'done i))
382 (setq i (1+ i) tabs (cdr tabs))))
383 i))
384
385
386(defun tab-bar-select-tab (&optional arg)
387 "Switch to the tab by its absolute position ARG in the tab bar.
388When this command is bound to a numeric key (with a prefix or modifier),
389calling it without an argument will translate its bound numeric key
390to the numeric argument. ARG counts from 1."
391 (interactive "P")
392 (unless (integerp arg)
393 (let ((key (event-basic-type last-command-event)))
394 (setq arg (if (and (characterp key) (>= key ?1) (<= key ?9))
395 (- key ?0)
396 1))))
397
398 (let* ((tabs (tab-bar-tabs))
399 (from-index (tab-bar--current-tab-index tabs))
400 (to-index (1- (max 1 (min arg (length tabs))))))
401 (unless (eq from-index to-index)
402 (let* ((from-tab (tab-bar--tab))
403 (to-tab (nth to-index tabs))
404 (wc (cdr (assq 'wc to-tab)))
405 (ws (cdr (assq 'ws to-tab))))
406
407 ;; During the same session, use window-configuration to switch
408 ;; tabs, because window-configurations are more reliable
409 ;; (they keep references to live buffers) than window-states.
410 ;; But after restoring tabs from a previously saved session,
411 ;; its value of window-configuration is unreadable,
412 ;; so restore its saved window-state.
413 (if (window-configuration-p wc)
414 (set-window-configuration wc)
415 (if ws (window-state-put ws (frame-root-window (selected-frame))
416 'safe)))
417
418 (when from-index
419 (setf (nth from-index tabs) from-tab))
420 (setf (nth to-index tabs) (tab-bar--current-tab)))
421
380 (when tab-bar-mode 422 (when tab-bar-mode
381 (force-mode-line-update))))) 423 (force-mode-line-update)))))
382 424
383(defun tab-bar-switch-to-prev-tab (&optional _arg) 425(defun tab-bar-switch-to-next-tab (&optional arg)
384 "Switch to ARGth previous tab."
385 (interactive "p")
386 (let ((prev-tab (tab-bar-find-prev-tab)))
387 (when prev-tab
388 (tab-bar-select-tab (car prev-tab)))))
389
390(defun tab-bar-switch-to-next-tab (&optional _arg)
391 "Switch to ARGth next tab." 426 "Switch to ARGth next tab."
392 (interactive "p") 427 (interactive "p")
428 (unless (integerp arg)
429 (setq arg 1))
393 (let* ((tabs (tab-bar-tabs)) 430 (let* ((tabs (tab-bar-tabs))
394 (prev-tab (tab-bar-find-prev-tab tabs))) 431 (from-index (or (tab-bar--current-tab-index tabs) 0))
395 (if prev-tab 432 (to-index (mod (+ from-index arg) (length tabs))))
396 (tab-bar-select-tab (car (cdr (cdr prev-tab)))) 433 (tab-bar-select-tab (1+ to-index))))
397 (tab-bar-select-tab (car (cdr tabs)))))) 434
435(defun tab-bar-switch-to-prev-tab (&optional arg)
436 "Switch to ARGth previous tab."
437 (interactive "p")
438 (unless (integerp arg)
439 (setq arg 1))
440 (tab-bar-switch-to-next-tab (- arg)))
441
442(defun tab-bar-switch-to-tab (name)
443 "Switch to the tab by NAME."
444 (interactive (list (completing-read "Switch to tab by name: "
445 (mapcar (lambda (tab)
446 (cdr (assq 'name tab)))
447 (tab-bar-tabs)))))
448 (tab-bar-select-tab (1+ (tab-bar--tab-index-by-name name))))
398 449
399 450
400(defcustom tab-bar-new-tab-to 'right 451(defcustom tab-bar-new-tab-to 'right
@@ -411,35 +462,12 @@ If `rightmost', create as the last tab."
411 :version "27.1") 462 :version "27.1")
412 463
413(defun tab-bar-new-tab () 464(defun tab-bar-new-tab ()
414 "Clone the current tab to the position specified by `tab-bar-new-tab-to'." 465 "Add a new tab at the position specified by `tab-bar-new-tab-to'."
415 (interactive) 466 (interactive)
416 (let* ((tabs (tab-bar-tabs)) 467 (let* ((tabs (tab-bar-tabs))
417 ;; (i-tab (- (length tabs) (length (memq tab tabs)))) 468 (from-index (tab-bar--current-tab-index tabs))
418 (new-tab (tab-bar-tab-default))) 469 (from-tab (tab-bar--tab)))
419 (when (and (not tab-bar-mode) 470
420 (or (eq tab-bar-show t)
421 (and (natnump tab-bar-show)
422 (>= (length tabs) tab-bar-show))))
423 (tab-bar-mode 1))
424 (cond
425 ((eq tab-bar-new-tab-to 'leftmost)
426 (setq tabs (cons new-tab tabs)))
427 ((eq tab-bar-new-tab-to 'rightmost)
428 (setq tabs (append tabs (list new-tab))))
429 (t
430 (let ((prev-tab (tab-bar-find-prev-tab tabs)))
431 (cond
432 ((eq tab-bar-new-tab-to 'left)
433 (if prev-tab
434 (setcdr prev-tab (cons new-tab (cdr prev-tab)))
435 (setq tabs (cons new-tab tabs))))
436 ((eq tab-bar-new-tab-to 'right)
437 (if prev-tab
438 (setq prev-tab (cdr prev-tab))
439 (setq prev-tab tabs))
440 (setcdr prev-tab (cons new-tab (cdr prev-tab))))))))
441 (set-frame-parameter nil 'tabs tabs)
442 (tab-bar-select-tab new-tab)
443 (when tab-bar-new-tab-choice 471 (when tab-bar-new-tab-choice
444 (delete-other-windows) 472 (delete-other-windows)
445 ;; Create a new window to get rid of old window parameters 473 ;; Create a new window to get rid of old window parameters
@@ -453,8 +481,29 @@ If `rightmost', create as the last tab."
453 (find-file-noselect tab-bar-new-tab-choice)))))) 481 (find-file-noselect tab-bar-new-tab-choice))))))
454 (when (buffer-live-p buffer) 482 (when (buffer-live-p buffer)
455 (switch-to-buffer buffer)))) 483 (switch-to-buffer buffer))))
456 (unless tab-bar-mode 484
457 (message "Added new tab with the current window configuration")))) 485 (when from-index
486 (setf (nth from-index tabs) from-tab))
487 (let ((to-tab (tab-bar--current-tab))
488 (to-index (pcase tab-bar-new-tab-to
489 ('leftmost 0)
490 ('rightmost (length tabs))
491 ('left (1- (or from-index 1)))
492 ('right (1+ (or from-index 0))))))
493 (setq to-index (max 0 (min (or to-index 0) (length tabs))))
494 (cl-pushnew to-tab (nthcdr to-index tabs))
495 (when (eq to-index 0)
496 ;; pushnew handles the head of tabs but not frame-parameter
497 (set-frame-parameter nil 'tabs tabs)))
498
499 (when (and (not tab-bar-mode)
500 (or (eq tab-bar-show t)
501 (and (natnump tab-bar-show)
502 (> (length tabs) tab-bar-show))))
503 (tab-bar-mode 1))
504 (if tab-bar-mode
505 (force-mode-line-update)
506 (message "Added new tab at %s" tab-bar-new-tab-to))))
458 507
459 508
460(defcustom tab-bar-close-tab-select 'right 509(defcustom tab-bar-close-tab-select 'right
@@ -466,85 +515,69 @@ If `right', select the adjacent right tab."
466 :group 'tab-bar 515 :group 'tab-bar
467 :version "27.1") 516 :version "27.1")
468 517
469(defun tab-bar-close-current-tab (&optional tab select-tab) 518(defun tab-bar-close-tab (&optional arg to-index)
470 "Close the current TAB. 519 "Close the tab specified by its absolute position ARG.
471After closing the current tab switch to the tab 520If no ARG is specified, then close the current tab and switch
472specified by `tab-bar-close-tab-select', or to `select-tab' 521to the tab specified by `tab-bar-close-tab-select'.
473if its value is provided." 522ARG counts from 1.
474 (interactive) 523Optional TO-INDEX could be specified to override the value of
475 (let ((tabs (tab-bar-tabs))) 524`tab-bar-close-tab-select' programmatically with a position
476 (unless tab 525of an existing tab to select after closing the current tab.
477 (let ((prev-tab (tab-bar-find-prev-tab tabs))) 526TO-INDEX counts from 1."
478 (setq tab (if prev-tab 527 (interactive "P")
479 (car (cdr prev-tab)) 528 (let* ((tabs (tab-bar-tabs))
480 (car tabs))))) 529 (current-index (tab-bar--current-tab-index tabs))
481 (if select-tab 530 (close-index (if (integerp arg) (1- arg) current-index)))
482 (setq tabs (delq tab tabs)) 531
483 (let* ((i-tab (- (length tabs) (length (memq tab tabs)))) 532 ;; Select another tab before deleting the current tab
484 (i-select 533 (when (eq current-index close-index)
485 (cond 534 (let ((to-index (or (if to-index (1- to-index))
486 ((eq tab-bar-close-tab-select 'left) 535 (pcase tab-bar-close-tab-select
487 (1- i-tab)) 536 ('left (1- current-index))
488 ((eq tab-bar-close-tab-select 'right) 537 ('right (if (> (length tabs) (1+ current-index))
489 ;; Do nothing: the next tab will take 538 (1+ current-index)
490 ;; the index of the closed tab 539 (1- current-index)))))))
491 i-tab) 540 (setq to-index (max 0 (min (or to-index 0) (1- (length tabs)))))
492 (t 0)))) 541 (tab-bar-select-tab (1+ to-index))
493 (setq tabs (delq tab tabs) 542 ;; Re-read tabs after selecting another tab
494 i-select (max 0 (min (1- (length tabs)) i-select)) 543 (setq tabs (tab-bar-tabs))))
495 select-tab (nth i-select tabs)))) 544
545 (set-frame-parameter nil 'tabs (delq (nth close-index tabs) tabs))
546
496 (when (and tab-bar-mode 547 (when (and tab-bar-mode
497 (and (natnump tab-bar-show) 548 (and (natnump tab-bar-show)
498 (<= (length tabs) tab-bar-show))) 549 (<= (length tabs) tab-bar-show)))
499 (tab-bar-mode -1)) 550 (tab-bar-mode -1))
500 (set-frame-parameter nil 'tabs tabs) 551 (if tab-bar-mode
501 (tab-bar-select-tab select-tab))) 552 (force-mode-line-update)
502 553 (message "Deleted tab and switched to %s" tab-bar-close-tab-select))))
503(defun tab-bar-close-tab (tab) 554
504 "Close the specified TAB. 555(defun tab-bar-close-tab-by-name (name)
505After closing the current tab switch to the tab 556 "Close the tab by NAME."
506specified by `tab-bar-close-tab-select'." 557 (interactive (list (completing-read "Close tab by name: "
507 (interactive (list (tab-bar-read-tab-name "Close tab by name: "))) 558 (mapcar (lambda (tab)
508 (when tab 559 (cdr (assq 'name tab)))
509 (if (eq (car tab) 'current-tab) 560 (tab-bar-tabs)))))
510 (tab-bar-close-current-tab tab) 561 (tab-bar-close-tab (1+ (tab-bar--tab-index-by-name name))))
511 (let ((tabs (tab-bar-tabs)))
512 ;; Close non-current tab, no need to switch to another tab
513 (when (and tab-bar-mode
514 (and (natnump tab-bar-show)
515 (<= (length tabs) tab-bar-show)))
516 (tab-bar-mode -1))
517 (set-frame-parameter nil 'tabs (delq tab tabs))
518 (when tab-bar-mode
519 (force-mode-line-update))))))
520 562
521 563
522;;; Non-graphical access to frame-local tabs (named window configurations) 564;;; Short aliases
523
524(defun tab-new ()
525 "Create a new named window configuration without having to click a tab."
526 (interactive)
527 (tab-bar-new-tab)
528 (unless tab-bar-mode
529 (message "Added new tab with the current window configuration")))
530
531(defun tab-close ()
532 "Delete the current window configuration without clicking a close button."
533 (interactive)
534 (tab-bar-close-current-tab)
535 (unless tab-bar-mode
536 (message "Deleted the current tab")))
537 565
538;; Short aliases 566(defalias 'tab-new 'tab-bar-new-tab)
539;; (defalias 'tab-switch 'tab-bar-switch-to-next-tab) 567(defalias 'tab-close 'tab-bar-close-tab)
540(defalias 'tab-select 'tab-bar-select-tab) 568(defalias 'tab-select 'tab-bar-select-tab)
569(defalias 'tab-next 'tab-bar-switch-to-next-tab)
541(defalias 'tab-previous 'tab-bar-switch-to-prev-tab) 570(defalias 'tab-previous 'tab-bar-switch-to-prev-tab)
542(defalias 'tab-next 'tab-bar-switch-to-next-tab) 571(defalias 'tab-list 'tab-bar-list)
543(defalias 'tab-list 'tab-bar-list) 572
573
574;;; Non-graphical access to frame-local tabs (named window configurations)
544 575
545(defun tab-bar-list () 576(defun tab-bar-list ()
546 "Display a list of named window configurations. 577 "Display a list of named window configurations.
547The list is displayed in the buffer `*Tabs*'. 578The list is displayed in the buffer `*Tabs*'.
579It's placed in the center of the frame to resemble a window list
580displayed by a window switcher in some window managers on Alt+Tab.
548 581
549In this list of window configurations you can delete or select them. 582In this list of window configurations you can delete or select them.
550Type ? after invocation to get help on commands available. 583Type ? after invocation to get help on commands available.
@@ -555,7 +588,7 @@ marked for deletion."
555 (interactive) 588 (interactive)
556 (let ((dir default-directory) 589 (let ((dir default-directory)
557 (minibuf (minibuffer-selected-window))) 590 (minibuf (minibuffer-selected-window)))
558 (let ((tab-bar-mode t)) ; don't enable tab-bar-mode if it's disabled 591 (let ((tab-bar-show nil)) ; don't enable tab-bar-mode if it's disabled
559 (tab-bar-new-tab)) 592 (tab-bar-new-tab))
560 ;; Handle the case when it's called in the active minibuffer. 593 ;; Handle the case when it's called in the active minibuffer.
561 (when minibuf (select-window (minibuffer-selected-window))) 594 (when minibuf (select-window (minibuffer-selected-window)))
@@ -660,7 +693,6 @@ Letters do not insert themselves; instead, they are commands.
660 (user-error "No window configuration on this line") 693 (user-error "No window configuration on this line")
661 nil)))) 694 nil))))
662 695
663
664(defun tab-bar-list-next-line (&optional arg) 696(defun tab-bar-list-next-line (&optional arg)
665 (interactive) 697 (interactive)
666 (forward-line arg) 698 (forward-line arg)
@@ -748,12 +780,10 @@ Then move up one line. Prefix arg means move that many lines."
748This command deletes and replaces all the previously existing windows 780This command deletes and replaces all the previously existing windows
749in the selected frame." 781in the selected frame."
750 (interactive) 782 (interactive)
751 (let* ((select-tab (tab-bar-list-current-tab t))) 783 (let* ((to-tab (tab-bar-list-current-tab t)))
752 (kill-buffer (current-buffer)) 784 (kill-buffer (current-buffer))
753 ;; Delete the current window configuration 785 ;; Delete the current window configuration
754 (tab-bar-close-current-tab nil select-tab) 786 (tab-bar-close-tab nil (1+ (tab-bar--tab-index to-tab)))))
755 ;; (tab-bar-select-tab select-tab)
756 ))
757 787
758(defun tab-bar-list-mouse-select (event) 788(defun tab-bar-list-mouse-select (event)
759 "Select the window configuration whose line you click on." 789 "Select the window configuration whose line you click on."