aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuri Linkov2021-03-14 11:29:31 +0200
committerJuri Linkov2021-03-14 11:29:31 +0200
commitf9b737fb9d21ac7adff403274167e76e77d033b8 (patch)
tree98b6a2af59fad4e3ea1a363fafdc138e55d65a81
parent0a60e5d33c82803d68970c71a2e9ac9fcde5c2c6 (diff)
downloademacs-f9b737fb9d21ac7adff403274167e76e77d033b8.tar.gz
emacs-f9b737fb9d21ac7adff403274167e76e77d033b8.zip
* lisp/tab-bar.el: Tab groups can be displayed with tab-bar-format-tabs-groups
* lisp/tab-bar.el (tab-bar-format): Turn defvar into defcustom. Add :options and force-mode-line-update in :set. (tab-bar--format-tab): New function refactored from tab-bar-format-tabs. (tab-bar-format-tabs): Move most of code to tab-bar--format-tab and call it. (tab-bar-tab-group-format-function): New defcustom. (tab-bar-tab-group-format-default): New function. (tab-bar--format-tab-group, tab-bar-format-tabs-groups): New functions. (tab-bar-format-align-right, tab-bar-format-global): Shorten id. (tab-bar-change-tab-group): Add refs to tab-bar-format in docstring.
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/tab-bar.el146
2 files changed, 109 insertions, 41 deletions
diff --git a/etc/NEWS b/etc/NEWS
index fa8784db59c..01fd7af65bf 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -519,11 +519,13 @@ It can be used to enable/disable the tab bar individually on each frame
519independently from the value of 'tab-bar-mode' and 'tab-bar-show'. 519independently from the value of 'tab-bar-mode' and 'tab-bar-show'.
520 520
521--- 521---
522*** New variable 'tab-bar-format' defines a list of tab bar items. 522*** New option 'tab-bar-format' defines a list of tab bar items.
523When it contains 'tab-bar-format-global' (possibly appended after 523When it contains 'tab-bar-format-global' (possibly appended after
524'tab-bar-format-align-right'), then after enabling 'display-time-mode' 524'tab-bar-format-align-right'), then after enabling 'display-time-mode'
525(or any other mode that uses 'global-mode-string') it displays time 525(or any other mode that uses 'global-mode-string') it displays time
526aligned to the right on the tab bar instead of the mode line. 526aligned to the right on the tab bar instead of the mode line.
527When 'tab-bar-format-tabs' is replaced with 'tab-bar-format-tabs-groups',
528then the tab bar displays tab groups.
527 529
528--- 530---
529*** 'Mod-9' bound to 'tab-last' now switches to the last tab. 531*** 'Mod-9' bound to 'tab-last' now switches to the last tab.
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index 29465aae63f..5c6f73ab376 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -519,10 +519,10 @@ the formatted tab name to display in the tab bar."
519 "")) 519 ""))
520 'face (if current-p 'tab-bar-tab 'tab-bar-tab-inactive)))) 520 'face (if current-p 'tab-bar-tab 'tab-bar-tab-inactive))))
521 521
522(defvar tab-bar-format '(tab-bar-format-history 522(defcustom tab-bar-format '(tab-bar-format-history
523 tab-bar-format-tabs 523 tab-bar-format-tabs
524 tab-bar-separator 524 tab-bar-separator
525 tab-bar-format-add-tab) 525 tab-bar-format-add-tab)
526 "Template for displaying tab bar items. 526 "Template for displaying tab bar items.
527Every item in the list is a function that returns 527Every item in the list is a function that returns
528a string, or a list of menu-item elements, or nil. 528a string, or a list of menu-item elements, or nil.
@@ -530,7 +530,22 @@ When you add more items `tab-bar-format-align-right' and
530`tab-bar-format-global' to the end, then after enabling 530`tab-bar-format-global' to the end, then after enabling
531`display-time-mode' (or any other mode that uses `global-mode-string') 531`display-time-mode' (or any other mode that uses `global-mode-string')
532it will display time aligned to the right on the tab bar instead of 532it will display time aligned to the right on the tab bar instead of
533the mode line.") 533the mode line. Replacing `tab-bar-format-tabs' with
534`tab-bar-format-tabs-groups' will group tabs on the tab bar."
535 :type 'hook
536 :options '(tab-bar-format-history
537 tab-bar-format-tabs
538 tab-bar-format-tabs-groups
539 tab-bar-separator
540 tab-bar-format-add-tab
541 tab-bar-format-align-right
542 tab-bar-format-global)
543 :initialize 'custom-initialize-default
544 :set (lambda (sym val)
545 (set-default sym val)
546 (force-mode-line-update))
547 :group 'tab-bar
548 :version "28.1")
534 549
535(defun tab-bar-format-history () 550(defun tab-bar-format-history ()
536 (when (and tab-bar-history-mode tab-bar-history-buttons-show) 551 (when (and tab-bar-history-mode tab-bar-history-buttons-show)
@@ -543,39 +558,90 @@ the mode line.")
543 menu-item ,tab-bar-forward-button tab-bar-history-forward 558 menu-item ,tab-bar-forward-button tab-bar-history-forward
544 :help "Click to go forward in tab history")))) 559 :help "Click to go forward in tab history"))))
545 560
561(defun tab-bar--format-tab (tab i)
562 (append
563 `((,(intern (format "sep-%i" i)) menu-item ,(tab-bar-separator) ignore))
564 (cond
565 ((eq (car tab) 'current-tab)
566 `((current-tab
567 menu-item
568 ,(funcall tab-bar-tab-name-format-function tab i)
569 ignore
570 :help "Current tab")))
571 (t
572 `((,(intern (format "tab-%i" i))
573 menu-item
574 ,(funcall tab-bar-tab-name-format-function tab i)
575 ,(or
576 (alist-get 'binding tab)
577 `(lambda ()
578 (interactive)
579 (tab-bar-select-tab ,i)))
580 :help "Click to visit tab"))))
581 `((,(if (eq (car tab) 'current-tab) 'C-current-tab (intern (format "C-tab-%i" i)))
582 menu-item ""
583 ,(or
584 (alist-get 'close-binding tab)
585 `(lambda ()
586 (interactive)
587 (tab-bar-close-tab ,i)))))))
588
546(defun tab-bar-format-tabs () 589(defun tab-bar-format-tabs ()
547 (let ((separator (tab-bar-separator)) 590 (let ((i 0))
548 (tabs (funcall tab-bar-tabs-function))
549 (i 0))
550 (mapcan 591 (mapcan
551 (lambda (tab) 592 (lambda (tab)
552 (setq i (1+ i)) 593 (setq i (1+ i))
553 (append 594 (tab-bar--format-tab tab i))
554 `((,(intern (format "sep-%i" i)) menu-item ,separator ignore)) 595 (funcall tab-bar-tabs-function))))
555 (cond 596
556 ((eq (car tab) 'current-tab) 597(defcustom tab-bar-tab-group-format-function #'tab-bar-tab-group-format-default
557 `((current-tab 598 "Function to format a tab group name.
558 menu-item 599Function gets two arguments, a tab with a group name and its number,
559 ,(funcall tab-bar-tab-name-format-function tab i) 600and should return the formatted tab group name to display in the tab bar."
560 ignore 601 :type 'function
561 :help "Current tab"))) 602 :initialize 'custom-initialize-default
562 (t 603 :set (lambda (sym val)
563 `((,(intern (format "tab-%i" i)) 604 (set-default sym val)
564 menu-item 605 (force-mode-line-update))
565 ,(funcall tab-bar-tab-name-format-function tab i) 606 :group 'tab-bar
566 ,(or 607 :version "28.1")
567 (alist-get 'binding tab) 608
568 `(lambda () 609(defun tab-bar-tab-group-format-default (tab i)
569 (interactive) 610 (propertize
570 (tab-bar-select-tab ,i))) 611 (concat (if tab-bar-tab-hints (format "%d " i) "")
571 :help "Click to visit tab")))) 612 (alist-get 'group tab))
572 `((,(if (eq (car tab) 'current-tab) 'C-current-tab (intern (format "C-tab-%i" i))) 613 'face 'tab-bar-tab-inactive))
573 menu-item "" 614
574 ,(or 615(defun tab-bar--format-tab-group (tab i)
575 (alist-get 'close-binding tab) 616 (append
576 `(lambda () 617 `((,(intern (format "sep-%i" i)) menu-item ,(tab-bar-separator) ignore))
577 (interactive) 618 `((,(intern (format "group-%i" i))
578 (tab-bar-close-tab ,i))))))) 619 menu-item
620 ,(funcall tab-bar-tab-group-format-function tab i)
621 ,(or
622 (alist-get 'binding tab)
623 `(lambda ()
624 (interactive)
625 (tab-bar-select-tab ,i)))
626 :help "Click to visit group"))))
627
628(defun tab-bar-format-tabs-groups ()
629 (let* ((tabs (funcall tab-bar-tabs-function))
630 (current-group (alist-get 'group (tab-bar--current-tab-find tabs)))
631 (previous-group nil)
632 (i 0))
633 (mapcan
634 (lambda (tab)
635 (let ((tab-group (alist-get 'group tab)))
636 (setq i (1+ i))
637 (prog1 (if (or (not tab-group) (equal tab-group current-group))
638 ;; Show current group and ungrouped tabs
639 (tab-bar--format-tab tab i)
640 ;; Otherwise, show first group tab with a group name,
641 ;; but hide other group tabs
642 (unless (equal previous-group tab-group)
643 (tab-bar--format-tab-group tab i)))
644 (setq previous-group tab-group))))
579 tabs))) 645 tabs)))
580 646
581(defun tab-bar-format-add-tab () 647(defun tab-bar-format-add-tab ()
@@ -590,7 +656,7 @@ the mode line.")
590 (rest (mapconcat (lambda (item) (nth 2 item)) rest "")) 656 (rest (mapconcat (lambda (item) (nth 2 item)) rest ""))
591 (hpos (length rest)) 657 (hpos (length rest))
592 (str (propertize " " 'display `(space :align-to (- right ,hpos))))) 658 (str (propertize " " 'display `(space :align-to (- right ,hpos)))))
593 `((tab-bar-format-align-right menu-item ,str ignore)))) 659 `((align-right menu-item ,str ignore))))
594 660
595(defun tab-bar-format-global () 661(defun tab-bar-format-global ()
596 "Format `global-mode-string' to display it in the tab bar. 662 "Format `global-mode-string' to display it in the tab bar.
@@ -599,10 +665,7 @@ When `tab-bar-format-global' is added to `tab-bar-format'
599then modes that display information on the mode line 665then modes that display information on the mode line
600using `global-mode-string' will display the same text 666using `global-mode-string' will display the same text
601on the tab bar instead." 667on the tab bar instead."
602 `((tab-bar-format-global 668 `((global menu-item ,(format-mode-line global-mode-string) ignore)))
603 menu-item
604 ,(format-mode-line global-mode-string)
605 ignore)))
606 669
607(defun tab-bar-format-list (format-list) 670(defun tab-bar-format-list (format-list)
608 (let ((i 0)) 671 (let ((i 0))
@@ -1256,7 +1319,10 @@ function `tab-bar-tab-name-function'."
1256 "Add the tab specified by its absolute position ARG to GROUP-NAME. 1319 "Add the tab specified by its absolute position ARG to GROUP-NAME.
1257If no ARG is specified, then set the GROUP-NAME for the current tab. 1320If no ARG is specified, then set the GROUP-NAME for the current tab.
1258ARG counts from 1. 1321ARG counts from 1.
1259If GROUP-NAME is the empty string, then remove the tab from any group." 1322If GROUP-NAME is the empty string, then remove the tab from any group.
1323While using this command, you might also want to replace
1324`tab-bar-format-tabs' with `tab-bar-format-tabs-groups' in
1325`tab-bar-format' to group tabs on the tab bar."
1260 (interactive 1326 (interactive
1261 (let* ((tabs (funcall tab-bar-tabs-function)) 1327 (let* ((tabs (funcall tab-bar-tabs-function))
1262 (tab-index (or current-prefix-arg (1+ (tab-bar--current-tab-index tabs)))) 1328 (tab-index (or current-prefix-arg (1+ (tab-bar--current-tab-index tabs))))