[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Help customising the behaviour of the new Tab Line mode
From: |
R. Diez |
Subject: |
Re: Help customising the behaviour of the new Tab Line mode |
Date: |
Wed, 19 Aug 2020 09:16:32 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 |
It should not be too hard to write another function for `tab-line-tabs-function'
that will keep the manually sorted list of buffers, and a new command with a
name
`tab-line-move-tab' that will move the current tab in the internally maintained
sorted buffer list used to display tabs on the tab-line.
OK, thanks for the hint.
Given my very limited Lisp, I may as well wait a few months in the hope that
someone more adept has a go at it. O8-)
There probably are other things not directly related to Lisp. For example, how does the new routine learn that there is a new buffer and the
tab bar needs to repaint? I already mentioned that a new compilation output buffer does not appear on the tab list, but more such things
will undoubtedly come up. I haven't looked much, but I could not see any documentation in tab-line.el or elsewhere about how tabs work in
such detail.
Yes, it would be nice to hide the tab for some buffers, but that would be the exception. It could also get tricky, because, if such a buffer
is currently selected, it should then suddenly show up as a tab. Otherwise, it is confusing to be in no tab at the moment, if you are used
to always being on a tab.
This is the related code I have been using for years with the old tabbar.el:
-------8<-------8<-------8<-------8<-------
; I find the default "grouping" behaviour annoying, so display all buffers in
the same tab group.
(defun tabbar-buffer-all-in-one-group ()
"Return the list of group names BUFFER belongs to. Return only one group for each
buffer."
(list "AllInOneGroup")
)
(setq tabbar-buffer-groups-function 'tabbar-buffer-all-in-one-group)
(setq *tabbar-ignore-buffers* '("*Messages*" "*Completions*" "*Ediff Registry*" "*Ibuffer*"
"*etags-select*" "*xref*" "TAGS"))
(setq tabbar-buffer-list-function 'my-tabbar-buffer-list)
(defun my-tabbar-buffer-list ()
(cl-remove-if
(lambda (buffer)
(and (not (eq (current-buffer) buffer)) ; Always include the current
buffer.
(or (string-starts-with (buffer-name buffer) " ") ; Possible
alternative: (char-equal ?\ (aref ((buffer-name buffer) b) 0))
(loop for name in *tabbar-ignore-buffers* ; Remove buffer name
in this list.
thereis (string-equal (buffer-name buffer) name))
)
)
)
(buffer-list)
)
)
(defun my-tabbar-move-tab-left nil ""
(interactive)
(let* (
(tabset (tabbar-current-tabset my-tabbar-request-new-tabset))
(selected-tab (tabbar-selected-tab tabset))
(tabs-in-tabset (tabbar-tabs tabset))
(pos-from-right (length (memq selected-tab tabs-in-tabset)))
new-tablist)
(when (tabbar-tab-next tabset selected-tab t)
(setq new-tablist (append
(butlast tabs-in-tabset (+ pos-from-right 1))
(list selected-tab)
(list (nth (- (length tabs-in-tabset) pos-from-right 1)
tabs-in-tabset))
(last tabs-in-tabset (- pos-from-right 1))))
; (setq tabbar-window-cache nil) ; didn't help
(set tabset new-tablist)
(tabbar-set-template tabset nil)
; If the tab moves out of view, calling tabbar-click-on-tab did not help.
; I tried all combinations, before and after tabbar-display-update.
; (tabbar-click-on-tab selected-tab)
(tabbar-display-update)))
)
(defun my-tabbar-move-tab-right nil ""
(interactive)
(let* (
(tabset (tabbar-current-tabset my-tabbar-request-new-tabset))
(selected-tab (tabbar-selected-tab tabset))
(tabs-in-tabset (tabbar-tabs tabset))
(pos-from-right (length (memq selected-tab tabs-in-tabset)))
new-tablist)
(when (tabbar-tab-next tabset selected-tab nil)
(setq new-tablist (append
(butlast tabs-in-tabset pos-from-right)
(list (nth (- (length tabs-in-tabset) pos-from-right -1)
tabs-in-tabset))
(list selected-tab)
(last tabs-in-tabset (- pos-from-right 2))))
; (setq tabbar-window-cache nil) ; didn't help
(set tabset new-tablist)
(tabbar-set-template tabset nil)
; If the tab moves out of view, calling tabbar-click-on-tab did not help.
; I tried all combinations, before and after tabbar-display-update.
; (tabbar-click-on-tab selected-tab)
(tabbar-display-update)))
)
-------8<-------8<-------8<-------8<-------
Half of the code is not actually mine, and the other half is very old and could
probably be greatly improved.
tabbar.el is not very well documented, so the code above does not always work well in all scenarios, but my Emacs skills are too limited to
fix it.
Then the remaining question is where would you prefer a new buffer to appear?
When you visit a new buffer, it should be added to such list of buffers.
One possible place is to put the new buffer to the end of the list,
but then wouldn't it too inconvenient for you to move its tab from the end
of the list to a more appropriate place where you want it to be?
I'm actually OK with the end of the list. That is what Firefox and co do when
you press Ctrl+T to create a new tab.
If you right-click on a link on Firefox, and choose "Open Link in New Tab", Firefox is kind of smart about where it places the new tab. The
first one opens next to the current tab, to its right, but a second one from the same page opens further to the right, next to the first tab
opened this way. That kind of behaviour would be nice for functions like 'ff-find-other-file'. But that would be comfort in the luxury
class, reserved for expensive, top-of-the-line software like web browsers, and we don't want to spoil Emacs users, do we??? ;-)
By the way, I tried once package tabbar-ruler, which allows the user to reorder the tabs on the old tabbar.el by dragging them with the
mouse. Unfortunately, I had to disable it because it had too many bugs. But is supporting mouse users morally acceptable in Emacs? 8-D
Regards,
rdiez