From 7f344ed1590b81323e24cdedf77477ae57cb49f9 Mon Sep 17 00:00:00 2001 From: Jared Finder Date: Fri, 26 Jan 2024 09:49:03 -0800 Subject: [PATCH 1/3] Enable multiple modes to appear in tab line This adds space for window-tool-bar-mode, which will be added in an upcoming commit. * lisp/tab-line.el (tab-line-format-template): Add separator space. (tab-line-display-order): New user variable to control display order. (tab-line--runtime-display-order, tab-line--cookie): New internal variables. (tab-line-set-display): New function for modes to call to enable only their content. (tab-line-mode): Call `tab-line-set-display'. --- lisp/tab-line.el | 89 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 80 insertions(+), 9 deletions(-) diff --git a/lisp/tab-line.el b/lisp/tab-line.el index cc60f94c9c5..c7283641cbd 100644 --- a/lisp/tab-line.el +++ b/lisp/tab-line.el @@ -573,7 +573,8 @@ tab-line-format-template (when (and (eq tab-line-tabs-function #'tab-line-tabs-window-buffers) tab-line-new-button-show tab-line-new-button) - (list tab-line-new-button))))) + (list tab-line-new-button)) + (list " ")))) (defun tab-line-tab-face-inactive-alternating (tab tabs face _buffer-p selected-p) "Return FACE for TAB in TABS with alternation. @@ -997,18 +998,88 @@ tab-line-event-start (event-start event))) +;;; Tab line display ordering +(defcustom tab-line-display-order + (copy-tree '(tab-line-mode window-tool-bar-mode)) + "The order to display content in the tab-line. + +This is a list of symbols. By convention, the symbols correspond +to the mode name that enables / disables content. Any symbol not +listed here will automatically be put at the end of the tab line. + +See `tab-line-set-display' for the Lisp interface to add and +remove content." + :type '(repeat symbol) + :group 'tab-line + :version "30.1") + +(defvar tab-line--runtime-display-order + nil + "Symbols that contain content but are not in `tab-line-display-order'. +This list ensures that content stays in a stable position in the +tab line.") + +(defconst tab-line--cookie + '(tab-line-set-display nil) + "Cookie used by `tab-line-set-display'. +This is used to tell if the tab line is being set based on +`tab-line-display-order' or was overridden by the user.") + +(defun tab-line-set-display (sym value) + "Lisp interface to add or remove content from the tab line. + +After calling this, if there is no content in the tab line, it +will be automatically hidden. + +SYM is a symbol, usually the symbol corresponding to the mode +showing content such as `tab-line-mode'. + +VALUE is the content to display and will be added to +`tab-line-format' at an appropriate index based on +`tab-line-display-order'. If you want to remove content because +the mode is being disabled, set this to nil." + ;; Preserve tab-line-format if altered outside of this function. + (when (or (null tab-line-format) + ;; Assume that user modifications will not use this + ;; cookie. + (equal (car tab-line-format) tab-line--cookie)) + (let (pos) + (setf pos (seq-position tab-line-display-order sym)) + (unless pos + (when-let ((append-pos (seq-position tab-line--runtime-display-order sym))) + (setf pos (+ (length tab-line-display-order) + append-pos)))) + (unless pos + (warn "Symbol %S not found in `tab-line-display-order'. Putting at end." + sym) + (setf pos (+ (length tab-line-display-order) + (length tab-line--runtime-display-order)) + tab-line--runtime-display-order + (append tab-line--runtime-display-order + (list sym)))) + + (let ((desired-length (+ pos 2)) ;Plus 1 additional for the cookie, + (current-length (length tab-line-format))) + (when (> desired-length current-length) + (setf tab-line-format + (append tab-line-format + (make-list (- desired-length current-length) nil)) + ;; If tab-line-format was nil, then the cookie needs to be set. + (car tab-line-format) tab-line--cookie))) + + (setf (nth (1+ pos) tab-line-format) value)) + + ;; If the entire display has been disabled, tab line would display + ;; as empty. Explicitly hide the tab line in this case. + (when (seq-every-p #'null (cdr tab-line-format)) + (setf tab-line-format nil)))) + ;;;###autoload (define-minor-mode tab-line-mode "Toggle display of tab line in the windows displaying the current buffer." :lighter nil - (let ((default-value '(:eval (tab-line-format)))) - (if tab-line-mode - ;; Preserve the existing tab-line set outside of this mode - (unless tab-line-format - (setq tab-line-format default-value)) - ;; Reset only values set by this mode - (when (equal tab-line-format default-value) - (setq tab-line-format nil))))) + (tab-line-set-display 'tab-line-mode + (if tab-line-mode '(:eval (tab-line-format)) nil))) (defcustom tab-line-exclude-modes '(completion-list-mode) -- 2.39.2