;;; syd-tabs.el -*- lexical-binding: t; -*- ;; Many themes neglect tab-bar customisation, leaving it completely unstyled. ;; `vim-tab-bar' will style it to look like Vim's tab-bar, but more importantly, ;; it will colour it to match the current theme. (use-package vim-tab-bar :commands vim-tab-bar-mode) (with-eval-after-load 'tab-bar (setq tab-bar-new-tab-to 'rightmost) (defun syd-tab-bar-make-free-name () (cl-loop for i from 1 with candidate = nil do (setq candidate (format "#%d" i)) while (tab-bar--tab-index-by-name candidate) finally return candidate)) (defun syd-tab-bar-rename-tab (tab new-name) ;; HACK: Using `tab-bar-rename-tab' doesn't work, for some reason. This ;; relies on the internal representation of tabs. (setf (alist-get 'name tab) new-name (alist-get 'explicit-name tab) t)) (defvar syd-tab-bar-name-function #'syd-tab-bar-make-free-name "Nullary function expected to return the name for a new tab.") (defvar syd-tab-bar-default-buffer-function #'scratch-buffer) (syd-add-hook 'tab-bar-tab-post-open-functions (defun syd-tab-bar--name-new-tab-h (tab) "Hooks to `tab-bar-tab-post-open-functions' such that new tabs will be given \"explicit names\" that are static." (syd-tab-bar-rename-tab tab (funcall syd-tab-bar-name-function))) (defun syd-tab-bar--show-tab-bar-h (_tab) "Show the tab-bar if it is not already visible. See `syd-tab-bar-hide-tab-bar-h'." (unless vim-tab-bar-mode (vim-tab-bar-mode 1)))) (defun syd-tab-bar-new-tab () (interactive) (let ((tab-bar-tab-post-open-functions (cons (lambda (_tab) (switch-to-buffer (funcall syd-tab-bar-default-buffer-function))) tab-bar-tab-post-open-functions))) (tab-bar-new-tab))) (syd-add-hook 'tab-bar-tab-pre-close-functions (defun syd-tab-bar-hide-tab-bar-h (_tab _final-tab-p) "Hide the tab-bar when there is only a single tab to show. See `syd-tab-bar--show-tab-bar-h'." (when (<= (length (tab-bar-tabs)) 2) ; The tab hasn't yet been removed. (tab-bar-mode -1)))) (defun syd-tab-bar-new-named-tab (name) (interactive (list (read-string "Tab name: "))) ;; Relies on `syd-tab-bar--name-new-tab-h'. (let ((syd-tab-bar-name-function (lambda () name))) (syd-tab-bar-new-tab))) (general-def :prefix-map 'syd-leader-tab-map "[" #'tab-previous "]" #'tab-next "r" #'tab-rename "R" #'tab-rename "n" #'syd-tab-bar-new-tab "N" #'syd-tab-bar-new-named-tab "d" #'tab-close) (general-def :keymaps 'syd-leader-map "TAB" `("Tabs" . ,syd-leader-tab-map) "" `("Tabs" . ,syd-leader-tab-map))) (provide 'syd-tabs)