Centaur tabs
Contents
- What is this?
- Installation
- Customization
- Headline face
- Tab Styles
- Tab height
- Tab icons
- Plain icons
- Graying out icons
- Selected tab bar
- Customize the close button
- Customize the modified marker
- Change the font family and height
- Disable centaur-tabs in selected buffers
- Buffer groups
- Show buffer groups names instead of buffer names in tabs
- Enable Vim like tab motions
- Prevent the access to specified buffers
- Tab cycling
- Buffer reordering (thanks to jixiuf)
- Alphabetical buffer reordering (thanks to cburroughs)
- Fixed tab length
- Selectrum integration (revert to
completing-read
) - Helm integration
- Ivy integration
- Projectile integration
- Mouse support (thanks to alvarogonzalezsotillo)
- New-tab button (thanks to lucasgruss)
- Tab count (thanks to kamilwaheed)
- Ace jump (thanks to Simon-Lin)
- Key bindings
- TO DO
- My personal configuration
- Useful commands
- Common issues
- Known supported theme plugins
- How to contribute
What is this?
This projects aims to become an aesthetic, functional and efficient tabs plugin for Emacs with a lot of customization options. Although this is a fork from awesome-tab (that I forked with the permission from the author and itās also based on tabbar) itās been heavily modified so now it may be considered a different package. Also this package integrates functionalities from tabbar-ruler.
It currently looks like this (although thereās a ton of possible configurations):
Installation
You can download this package from MELPA. This is a basic use-package
configuration:
(use-package centaur-tabs
:demand
:config
(centaur-tabs-mode t)
:bind
("C-<prior>" . centaur-tabs-backward)
("C-<next>" . centaur-tabs-forward))
Or if you use require:
(require 'centaur-tabs)
(centaur-tabs-mode t)
(global-set-key (kbd "C-<prior>") 'centaur-tabs-backward)
(global-set-key (kbd "C-<next>") 'centaur-tabs-forward)
Customization
This package is heavily customizable, with many options available to the user. Here are some of them:
Headline face
You can make the headline face match the centaur-tabs-default face. This makes the tabbar have an uniform appearance. In your configuration use the following function:
(centaur-tabs-headline-match)
Tab Styles
To change the tab style, modify the centaur-tabs-style variable like this:
(setq centaur-tabs-style "bar")
The options available are:
- āalternateā
- ābarā
- āboxā
- āchamferā
- āroundedā
- āslantā
- āwaveā
- āzigzagā
Tab height
To change the tab height do
(setq centaur-tabs-height 32)
Tab icons
To display themed icons from all the icons
(setq centaur-tabs-set-icons t)
Plain icons
To make icons plain (same color as tabsā text):
(setq centaur-tabs-plain-icons t)
Graying out icons
To gray out icons for the unselected tabs:
(setq centaur-tabs-gray-out-icons 'buffer)
Selected tab bar
To display a colored bar at the left of the selected tab
(setq centaur-tabs-set-bar 'left)
To display an overline over the selected tab:
(setq centaur-tabs-set-bar 'over)
To display an underline over the selected tab:
(setq centaur-tabs-set-bar 'under)
;; Note: If you're not using Spacmeacs, in order for the underline to display
;; correctly you must add the following line:
(setq x-underline-at-descent-line t)
The color can be customized via the centaur-tabs-active-bar-face face.
Customize the close button
To disable the close button
(setq centaur-tabs-set-close-button nil)
To change the displayed string for the close button
(setq centaur-tabs-close-button "X")
Also there are two faces to customize the close button string: centaur-tabs-close-unselected and centaur-tabs-close-selected
Customize the modified marker
To display a marker indicating that a buffer has been modified (atom-style)
(setq centaur-tabs-set-modified-marker t)
To change the displayed string for the modified-marker
(setq centaur-tabs-modified-marker "*")
Also there are two faces to customize the close button string: centaur-tabs-modified-marker-unselected and centaur-tabs-modified-marker-selected
Change the font family and height
To easily customize the tabs font by changing itās height and font family use the following function:
(centaur-tabs-change-fonts "arial" 160)
Disable centaur-tabs in selected buffers
To disable the tabs in a buffer just add a hook to the centaur-tabs-local-mode
function like this:
(add-hook 'dired-mode-hook 'centaur-tabs-local-mode)
or with use-package
:
(use-package centaur-tabs
...
:hook
(dired-mode . centaur-tabs-local-mode)
...)
Buffer groups
To customize the way that the buffers are grouped modify the centaur-tabs-buffer-groups
function like this:
(defun centaur-tabs-buffer-groups ()
"`centaur-tabs-buffer-groups' control buffers' group rules.
Group centaur-tabs with mode if buffer is derived from `eshell-mode' `emacs-lisp-mode' `dired-mode' `org-mode' `magit-mode'.
All buffer name start with * will group to \"Emacs\".
Other buffer group by `centaur-tabs-get-group-name' with project name."
(list
(cond
((or (string-equal "*" (substring (buffer-name) 0 1))
(memq major-mode '(magit-process-mode
magit-status-mode
magit-diff-mode
magit-log-mode
magit-file-mode
magit-blob-mode
magit-blame-mode
)))
"Emacs")
((derived-mode-p 'prog-mode)
"Editing")
((derived-mode-p 'dired-mode)
"Dired")
((memq major-mode '(helpful-mode
help-mode))
"Help")
((memq major-mode '(org-mode
org-agenda-clockreport-mode
org-src-mode
org-agenda-mode
org-beamer-mode
org-indent-mode
org-bullets-mode
org-cdlatex-mode
org-agenda-log-mode
diary-mode))
"OrgMode")
(t
(centaur-tabs-get-group-name (current-buffer))))))
Show buffer groups names instead of buffer names in tabs
If you want your tabs to display buffer groups names instead of buffer names you can put the following in your configuration:
(setq centaur-tabs--buffer-show-groups t)
You can toggle between the two options interactively with the (centaur-tabs-toggle-groups)
command.
Enable Vim like tab motions
To enable Vim like tab changing binds
(define-key evil-normal-state-map (kbd "g t") 'centaur-tabs-forward)
(define-key evil-normal-state-map (kbd "g T") 'centaur-tabs-backward)
or with use-package
:
(use-package centaur-tabs
...
:bind
(:map evil-normal-state-map
("g t" . centaur-tabs-forward)
("g T" . centaur-tabs-backward))
...)
Prevent the access to specified buffers
You can prevent the access to some buffers via tab motions changing the following function like this:
(defun centaur-tabs-hide-tab (x)
"Do no to show buffer X in tabs."
(let ((name (format "%s" x)))
(or
;; Current window is not dedicated window.
(window-dedicated-p (selected-window))
;; Buffer name not match below blacklist.
(string-prefix-p "*epc" name)
(string-prefix-p "*helm" name)
(string-prefix-p "*Helm" name)
(string-prefix-p "*Compile-Log*" name)
(string-prefix-p "*lsp" name)
(string-prefix-p "*company" name)
(string-prefix-p "*Flycheck" name)
(string-prefix-p "*tramp" name)
(string-prefix-p " *Mini" name)
(string-prefix-p "*help" name)
(string-prefix-p "*straight" name)
(string-prefix-p " *temp" name)
(string-prefix-p "*Help" name)
(string-prefix-p "*mybuf" name)
;; Is not magit buffer.
(and (string-prefix-p "magit" name)
(not (file-name-extension name)))
)))
The function shown is the default function from the centaur-tabs
configuration, adding the (string-prefix-p "*āmybuf" name)
part to prevent the access to every buffer with its name ending in āmybufā. You can either add this function as it is to preserve centaur-tabs
default filters and add any Boolean function that you want to filter your buffers (i.e string-prefix-p
or string-suffix-p
) like in this example with the āmybufā line, or completely override the function with your custom filters if you completely know what youāre doing.
Tab cycling
The default behaviour from the centaur-tabs-forward/backward
functions is to go through all the tabs in the current group and then change the group. If this is something that is to desired to be changed the centaur-tabs-cycle-scope
custom must be changed like this:
(setq centaur-tabs-cycle-scope 'tabs)
There are three options:
- ādefault: (Already described)
- ātabs: Cycle through visible tabs (that is, the tabs in the current group)
- āgroups: Navigate through tab groups only
Buffer reordering (thanks to jixiuf)
To enable an automatic buffer reordering function use the following function in your configuration:
(centaur-tabs-enable-buffer-reordering)
;; When the currently selected tab(A) is at the right of the last visited
;; tab(B), move A to the right of B. When the currently selected tab(A) is
;; at the left of the last visited tab(B), move A to the left of B
(setq centaur-tabs-adjust-buffer-order t)
;; Move the currently selected tab to the left of the the last visited tab.
(setq centaur-tabs-adjust-buffer-order 'left)
;; Move the currently selected tab to the right of the the last visited tab.
(setq centaur-tabs-adjust-buffer-order 'right)
This works the following way. If thereās a certain group of tabs like the following:
tab1.el | tab2.js | tab3.c | tab4.py |
If youāre in a tab and change to another tab in the group (via Ido, Ivy or Helm) the new tab will move to the right side of the tab you were, so if youāre on tab1.el
and you clicked tab4.py
the tabs order will be the following:
tab1.el | tab4.py | tab2.js | tab3.c |
And then if you were on tab4.py
and changed to tab2.js
, the tabs order will be the following:
tab1.el | tab4.py | tab2.js | tab3.c |
the order doesnāt change, because the tabs are already next to each other.
And now if you were on tab2.js
and changed to tab1.el
, the tabs order will be the following:
tab4.py | tab1.el | tab2.js | tab3.c |
This functionality doesnāt take effect when using centaur-tabs motion functions like centaur-tabs-backward/forward
.
Alphabetical buffer reordering (thanks to cburroughs)
To enable an automatic alpabetical buffer reordering, put the following lines in your configuration.
(centaur-tabs-enable-buffer-alphabetical-reordering)
(setq centaur-tabs-adjust-buffer-order t)
This function will trigger each time a non centaur-tabs motion command is executed. NOTE: Given the Emacs behaviour when opening a new file is a little bit funky, when a new tab is opened, it will always be placed at the right of the last visited buffer. This behaviour needs to be investigated in order to see if a possible solution exists.
Fixed tab length
If you desire to make the width of your tabs fixed, you have to modify the centaur-tabs-label-fixed-length
custom variable with the maximum length desired (defaults to 0 for dynamic). Example:
(setq centaur-tabs-label-fixed-length 8)
Would render the following tabs:
foo.org | a_very_dā¦ | bar.org |
Selectrum integration (revert to completing-read
)
Turn off default ido-mode
completions by customising centaur-tabs-enable-ido-completion
in order to revert to Emacsā native completing-read
.
Helm integration
You can integrate Helm with centaur-tabs for changing tab-groups. Just add helm-source-centaur-tabs-group in helm-source-list. Then youāll be able to use (centaur-tabs-build-helm-source)
function and bind it to any key you want. (Iām not a Helm user so Iāll not be able to solve problems related to this).
Ivy integration
You can integrate Ivy with centaur-tabs for changing tab-groups. Just use the (centaur-tabs-counsel-switch-group)
and bind it to any key you want.
Projectile integration
You can group your tabs by Projectileās project. Just use the following function in your configuration:
(centaur-tabs-group-by-projectile-project)
This function can be called interactively to enable Projectile grouping. To go back to centaur-tabsās user defined (or default) buffer grouping function you can interactively call:
(centaur-tabs-group-buffer-groups)
Mouse support (thanks to alvarogonzalezsotillo)
- Just click in a tab to change the buffer of the current window.
- Click the mouse wheel to close a buffer.
- Right click on empty space to show a tab groups popup.
- Right click on a tab to show a context menu. The options are inspired by the options provided by VSCode.
- Use the mouse wheel to invoke
centaur-tabs-backward/forward
. - Set the
centaur-tabs-show-navigation-buttons
custom variable tot
to display cool navigation buttons. With the CTRL key, the left and right navigation buttons will move the tabs through the tab line.
New-tab button (thanks to lucasgruss)
The new-tab button is a button at the right of the tabs that will spawn a new
tab based on the current context. For instance in
vterm/eshell/ansi-term
mode, the new tab will spawn a new buffer
corresponding to the current major mode. In eww
, you are prompted for a
search term and the result is displayed in a new buffer. The default
behaviour in other modes is to open a new empty buffer.
- the variable
centaur-tabs-show-new-tab-button
controls whether the button is shown. - the variable
centaur-tabs-new-tab-text
controls the appearance of the button. - the function
centaur-tabs--create-new-tab
controls the behaviour of the context-based new tab.
Tab count (thanks to kamilwaheed)
Adds a count of the current tab position in the total number of
tabs in the current window. Controlled by the variable
centaur-tabs-show-count
.
Ace jump (thanks to Simon-Lin)
Enables quick tab switching through an Ace-jump/Avy-like interface. To use it, interactively call the centaur-tabs-ace-jump
function. While on Ace-jump mode, you can press ?
to display a menu showing the possible actions available.
Key bindings
If you want to enable a series of key bindings with different tab managing functions, put the following in your configuration before the package is loaded (if you use use-package
, this should go in the :init
section):
(setq centaur-tabs-enable-key-bindings t)
This will enable a series of key bindings for centaur-tabs prefixed by āC-c tā.
TO DO [17/19]
- [X] Integrate all-the-icons
- [X] Improve all the icons placing
- [X] Fix all the icons background
- [X] Add selected, unselected, selected-modified and unselected-modified faces
- [X] Make function to inherit tabbar faces
- [X] Group tabs by projectileās project (was already implemented but not for projectile)
- [X] Create PR to different theme packages for this package
- [X] Add modified marker icon option
- [X] Add sideline for selected tab (atom style)
- [X] Add overline for selected tab (atom style). Itās easy to add to the text, but not to the icon, so for any who figures it out a PR is welcome.
- [ ] Add easy tab style configuration function. (Atom, Sublime, VS Codeā¦ like
(centaur-tabs-tab-theme "atom")
) - [X] Make icon insert after the separator
- [X] Add a customizable close button
- [X] Explore if
after-modifying-buffer
function can be improved - [X] Fix messages buffer icon an FontAwesome errors
- [X] Check for Elscreen compatibility
- [X] Add this package to MELPA
- [X] Make a configuration to display buffer groups names instead of buffer names in tabs
- [ ] Add full evil-mode support with tab commands
My personal configuration
My personal configuration for reference:
(use-package centaur-tabs
:init
(setq centaur-tabs-enable-key-bindings t)
:config
(setq centaur-tabs-style "bar"
centaur-tabs-height 32
centaur-tabs-set-icons t
centaur-tabs-show-new-tab-button t
centaur-tabs-set-modified-marker t
centaur-tabs-show-navigation-buttons t
centaur-tabs-set-bar 'under
centaur-tabs-show-count nil
;; centaur-tabs-label-fixed-length 15
;; centaur-tabs-gray-out-icons 'buffer
;; centaur-tabs-plain-icons t
x-underline-at-descent-line t
centaur-tabs-left-edge-margin nil)
(centaur-tabs-change-fonts (face-attribute 'default :font) 110)
(centaur-tabs-headline-match)
;; (centaur-tabs-enable-buffer-alphabetical-reordering)
;; (setq centaur-tabs-adjust-buffer-order t)
(centaur-tabs-mode t)
(setq uniquify-separator "/")
(setq uniquify-buffer-name-style 'forward)
(defun centaur-tabs-buffer-groups ()
"`centaur-tabs-buffer-groups' control buffers' group rules.
Group centaur-tabs with mode if buffer is derived from `eshell-mode' `emacs-lisp-mode' `dired-mode' `org-mode' `magit-mode'.
All buffer name start with * will group to \"Emacs\".
Other buffer group by `centaur-tabs-get-group-name' with project name."
(list
(cond
;; ((not (eq (file-remote-p (buffer-file-name)) nil))
;; "Remote")
((or (string-equal "*" (substring (buffer-name) 0 1))
(memq major-mode '(magit-process-mode
magit-status-mode
magit-diff-mode
magit-log-mode
magit-file-mode
magit-blob-mode
magit-blame-mode
)))
"Emacs")
((derived-mode-p 'prog-mode)
"Editing")
((derived-mode-p 'dired-mode)
"Dired")
((memq major-mode '(helpful-mode
help-mode))
"Help")
((memq major-mode '(org-mode
org-agenda-clockreport-mode
org-src-mode
org-agenda-mode
org-beamer-mode
org-indent-mode
org-bullets-mode
org-cdlatex-mode
org-agenda-log-mode
diary-mode))
"OrgMode")
(t
(centaur-tabs-get-group-name (current-buffer))))))
:hook
(dashboard-mode . centaur-tabs-local-mode)
(term-mode . centaur-tabs-local-mode)
(calendar-mode . centaur-tabs-local-mode)
(org-agenda-mode . centaur-tabs-local-mode)
:bind
("C-<prior>" . centaur-tabs-backward)
("C-<next>" . centaur-tabs-forward)
("C-S-<prior>" . centaur-tabs-move-current-tab-to-left)
("C-S-<next>" . centaur-tabs-move-current-tab-to-right)
(:map evil-normal-state-map
("g t" . centaur-tabs-forward)
("g T" . centaur-tabs-backward)))
Useful commands
Centaur tabs has plenty of useful commands for manipulating tabs and tab groups. Some of them are:
(centaur-tabs-kill-all-buffers-in-current-group)
: Kills all buffers in current tab group.(centaur-tabs-kill-match-buffers-in-current-group)
: Kills all buffers in current tab group with the same extension as the current buffer.(centaur-tabs-keep-match-buffers-in-current-group)
: Asks for a file extension and kills all the buffers with a different extension.(centaur-tabs-kill-other-buffers-in-current-group)
: Kills all buffers in current tab group except the current buffer.(centaur-tabs-kill-unmodified-buffers-in-current-group)
: Kills all buffers in current tab group that are unmodified.(centaur-tabs-select-beg-tab)
: Selects the first tab of the group.(centaur-tabs-select-end-tab)
: Selects the last tab of the group.(centaur-tabs-forward-group)
: Go to the next tab group.(centaur-tabs-backward-group)
: Go to the previous tab group.
Common issues
Icons not showing
If the icons in your tabs are not showing, it is likely because of one of the two following reasons:
all-the-icons not installed
If all-the-icons is not installed properly, your mode icons wonāt show up. To solve this issue, you have to install all-the-icons and follow the instructions indicated in its repository.
Font with required unicode symbols missing
If you get something like the following image in your tabs:
it is likely that youāre missing a font that has the required unicode symbols. To solve this issue, simply install a font that has this symbols such as Google Noto Sans Symbols2.
Known supported theme plugins
- Atom One Dark Theme
- Base16
- Chocolate Theme
- Doom Themes
- Kaolin Themes
- Spacemacs Theme
- Tron Legacy
- Wilmersdorf Theme
- Zenburn
- Solarized
How to contribute
You can contribute by forking the repo and then creating a pull request with the changes you consider will improve the package. Thereās a TO DO list with wanted features so you can start from there. Iāll be glad to receive help. Please try to keep the code as clear and documented as possible.