Back in 2018 I posted about making tabbar.el look pretty. Emacs 27 includes two built-in ways to display tabs:
tab-bar-mode
works per frame to show window configurationstab-line-mode
works per window to show buffers
Tab-line mode seems similar to tabbar.el, so I decided to switch from tabbar.el to tab-line.
![Screenshot of emacs 27 tab-line-mode](https://www.redblobgames.com/x/screenshots/emacs-tab-line.png)
I had customized tabbar.el to show only the buffers from the current project, sorted alphabetically. It's even easier with tab-line: tab-line-tabs-function
can be set to group mode, which uses tab-line-tabs-buffer-group-function
to choose the group name and tab-line-tabs-buffer-group-sort-function
to sort the buffers in the group.
(require 's) (defun my/tab-line-buffer-group (buffer) "Use the project.el name for the buffer group" (with-current-buffer buffer (s-chop-suffix "/" (car (project-roots (project-current)))))) (defun my/buffer-sort (a b) (string< (buffer-name a) (buffer-name b))) (setq tab-line-tabs-buffer-group-sort-function #'my/buffer-sort) (setq tab-line-tabs-buffer-group-function #'my/tab-line-buffer-group) (setq tab-line-tabs-function #'tab-line-tabs-buffer-groups)
Next, I wanted to make the tabs look nicer. As before, I used powerline for this. I disabled the extra buttons by setting tab-line-new-button-show
and tab-line-close-button-show
to nil, then set tab-line-tab-name-function
to a function that adds powerline wave symbols to both sides of the tab name:
(require 'powerline) (defvar my/tab-height 22) (defvar my/tab-left (powerline-wave-right 'tab-line nil my/tab-height)) (defvar my/tab-right (powerline-wave-left nil 'tab-line my/tab-height)) (defun my/tab-line-tab-name-buffer (buffer &optional _buffers) (powerline-render (list my/tab-left (format " %s " (buffer-name buffer)) my/tab-right))) (setq tab-line-tab-name-function #'my/tab-line-tab-name-buffer) (setq tab-line-new-button-show nil) (setq tab-line-close-button-show nil)
I used a color scheme that's consistent with my modeline:
(set-face-attribute 'tab-line nil ;; background behind tabs :background "gray40" :foreground "gray60" :distant-foreground "gray50" :family "Fira Sans Condensed" :height 1.0 :box nil) (set-face-attribute 'tab-line-tab nil ;; active tab in another window :inherit 'tab-line :foreground "gray70" :background "gray90" :box nil) (set-face-attribute 'tab-line-tab-current nil ;; active tab in current window :background "#b34cb3" :foreground "white" :box nil) (set-face-attribute 'tab-line-tab-inactive nil ;; inactive tab :background "gray80" :foreground "black" :box nil) (set-face-attribute 'tab-line-highlight nil ;; mouseover :background "white" :foreground 'unspecified)
Finally, I want to use keys to navigate the tabs. I bound H-j to tab-line-switch-to-prev-tab
and H-k to tab-line-switch-to-next-tab
. I use these same keys for terminals and web browsers.
I'm pretty happy with tab-line mode so far.
Labels: emacs
One thing that confuses me is that tab-line-tab-current is supposed to be for the active window but I often find the active window has the tab-line-tab color. For now I'm going to set these two to the same.
Hi Amit,
executing your code gives me a
Symbol's function definition is void: hsl
I saw a package named hsluv, installed it, changed your code snippet from "hsl" to "hsluv", but received a similar message:
Symbol's function definition is void: hsluv
What is hsl?
Best regards,
Alex
Oh! Sorry about that!
(require 'color)
(defun hsl (H S L)
"Convert HSL to a #rrggbb string, using HSL 0-360, S 0-1, L 0-1"
(apply 'color-rgb-to-hex (color-hsl-to-rgb (/ H 360.0) S L)))
I will update the blog post.
Why switch from tabbar.el? Is it because tab-line is built-in, or is there some reason that tab-line fits your workflow better?
Great post and very useful.
Quick question: I have seen that the waves powerline leaves a gray space where the tab rectangle is cut, how can I change the color of that gray space? I fiddled with the tab-line faces but I cannot find where the color is defined.
Thanks in advance.
Anonymous: tabbar.el uses the header line, and there are other packages that also want to use the header line, so I thought it would be nice to switch to tab-line so that I could use those other packages. For example lsp-mode uses the header line to show "breadcrumbs", and I think magit also has some code to use the header line.
Xavier: it seems like some platforms have color differences that might be what you're seeing. If you're on mac, try either (setq ns-use-srgb-colorspace t) or (setq ns-use-srgb-colorspace nil) to see if that makes a difference. I've also heard it affects Linux but haven't had the problem on my Linux system.
Your point about the header-line is well taken, but I don't like how tab-line mode works.
I took tabbar.el and changed all instances of header-line to tab-line. It worked perfectly. It still uses the tabbar faces.
Beautiful. How did you manage to customize the line numbers gutter? I can't find the face property for that.
Thanks Alexandre! I set the line-number, line-number-current-line, and line-number-major-tick faces to be a small font, and I set display-line-numbers-width to 4, and display-line-numbers-major-tick to 5.
What font are you using sir?
新闻剪报 : I usually use Iosevka https://typeof.net/Iosevka/
Post a Comment