[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs
From: |
Juri Linkov |
Subject: |
bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs |
Date: |
Tue, 22 Oct 2019 01:20:42 +0300 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) |
>> But maybe tab-button granularity is fine. The only problem is that
>> I still studying the code to understand where to begin. Could you suggest
>> in what function to implement all this scrolling?
>
> I think you will need a new function. A tab-line is generated from a
> Lisp string, and we don't have code for hscrolling screen lines
> produced from strings (as opposed to from buffer text).
>
> The general idea is to identify the first (leftmost) tab you want to
> be visible, and then make changes in display_mode_line to start
> display from that tab. I think the first part is the more complex of
> these two. format-mode-line shows an example of how to generate
> display derived from Lisp and C strings without displaying anything;
> you could use that for finding the X coordinate (in it.current_x) of
> the beginning of the Nth tab's button. Each click on the right fringe
> increases N, each click on the left decreases it. The X coordinate
> you compute is the value to use for it.first_visible_x in
> display_mode_line.
This is so overwhelming that I'm still struggling with understanding the
details of the display engine. If hscrolling was already implemented
for the header-line, we could just copy the existing solution to the
tab-line.
So I looked how packages cope with the requirement of keeping hscrolling
of the header-line in sync with hscrolling of the buffer, and found that
the 'proced' package uses so simple solution that we could just do
the same. This is what it does:
(defun proced-header-line ()
"Return header line for Proced buffer."
(list (propertize " "
'display
(list 'space :align-to
(line-number-display-width 'columns)))
(if (<= (window-hscroll) (length proced-header-line))
(replace-regexp-in-string ;; preserve text properties
"\\(%\\)" "\\1\\1"
(substring proced-header-line (window-hscroll))))))
i.e. it just cuts scrolled content from the beginning.
Adapting the same idea to the tab-line provides the workable and
reliable solution with just a dozen lines of Lisp code. You can
evaluate this, and everything works smoothly:
(advice-add 'tab-line-format :around
(lambda (orig-fun)
(let ((tabs (funcall orig-fun))
(hscroll (window-parameter nil 'hscroll)))
(if hscroll (nthcdr hscroll tabs) tabs)))
'((name . tab-line-format-hscroll)))
(defun tab-line-hscroll (&optional arg window)
(let* ((hscroll (window-parameter window 'hscroll)))
(set-window-parameter
window 'hscroll (max 0 (min (+ (or hscroll 0) (or arg 1))
(1- (length (funcall
tab-line-tabs-function))))))))
(defun tab-line-hscroll-left (&optional arg mouse-event)
(interactive (list current-prefix-arg last-nonmenu-event))
(tab-line-hscroll arg (and (listp mouse-event) (posn-window (event-start
mouse-event))))
(force-mode-line-update))
(defun tab-line-hscroll-right (&optional arg mouse-event)
(interactive (list current-prefix-arg last-nonmenu-event))
(tab-line-hscroll (- (or arg 1)) (and (listp mouse-event) (posn-window
(event-start mouse-event))))
(force-mode-line-update))
(global-set-key [tab-line mouse-4] 'tab-line-hscroll-left)
(global-set-key [tab-line mouse-5] 'tab-line-hscroll-right)
(global-set-key [tab-line wheel-up] 'tab-line-hscroll-left)
(global-set-key [tab-line wheel-down] 'tab-line-hscroll-right)
Thus mouse-wheel hscrolls the tab-line exactly like mouse-wheel
hscrolls tabs in Firefox.
Also these two commands can be used via M-x, and can be bound
to some key that could used via a transitive keymap, e.g.
some prefix initiates a key sequence, then consecutive
<right> keys continue hscrolling.
Later advice-add will be moved into the body of tab-line-format.
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, (continued)
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Eli Zaretskii, 2019/10/15
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Eli Zaretskii, 2019/10/15
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Juri Linkov, 2019/10/15
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Eli Zaretskii, 2019/10/16
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Juri Linkov, 2019/10/16
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Eli Zaretskii, 2019/10/17
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Juri Linkov, 2019/10/17
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Eli Zaretskii, 2019/10/18
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Juri Linkov, 2019/10/20
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Eli Zaretskii, 2019/10/21
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs,
Juri Linkov <=
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Eli Zaretskii, 2019/10/22
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Juri Linkov, 2019/10/22
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Eli Zaretskii, 2019/10/23
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Juri Linkov, 2019/10/28
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Eli Zaretskii, 2019/10/29
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Juri Linkov, 2019/10/29
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Eli Zaretskii, 2019/10/30
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Juri Linkov, 2019/10/30
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Eli Zaretskii, 2019/10/31
- bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs, Juri Linkov, 2019/10/31