help-gnu-emacs
[Top][All Lists]
Advanced

[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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]