kovidgoyal / kitty

Cross-platform, fast, feature-rich, GPU based terminal
https://sw.kovidgoyal.net/kitty/
GNU General Public License v3.0
24.11k stars 972 forks source link

Better tab width management #5548

Closed ces42 closed 2 years ago

ces42 commented 2 years ago

Is your feature request related to a problem? Please describe. It seems like the current way of drawing tabs just allocates # of columns // # of tabs columns to every tab and tells the draw function for every tab to draw the tab with at most that width. I usually have plenty of tabs whose titles are short, e.g. just ~, so it is annoying when long tab titles get shortened even though there is plenty of space in the tab bar.

Describe the solution you'd like I suppose several things could improve the situation:

Ideally there would be some algorithm to

  1. ask every tab "how much space it would like to have" (some function that can be customized similar to draw_tab)
  2. check by how much the sum exceeds the available space
  3. determine how much space every tab will get (e.g. every tab must "save" the same absolute number of characters, or every tab must save a number of character proportional to the number it requested)
  4. call the tab draw function with max_title_length set to the number determined for this tab

Another thing that might be helpful and should be easy to implement would be allocating the remainder of the divion # of columns // # of tabs to the currently active tab. (The only drawback of this is that switching tabs could cause things in the tab bar to "jump" which might potentially be annoying)

Describe alternatives you've considered If there's some hacky way to access the list of tabs in the current window and get their titles I guess I'd also be fine with implementing the width allocation in a custom draw_tab function.

page-down commented 2 years ago

... I usually have plenty of tabs whose titles are short ...

Looks like you need a configuration such as the following?

tab_title_template "{title:<{max_title_length}}"

Adding numerous options for customizing tabs (which I already thought of many aspects that could be customized) would make user configuration and code maintenance difficult.

I would prefer to provide some useful metadata and utility functions.

EDIT: I don't believe the above configuration will solve the problem you are asking.

... when long tab titles get shortened even though there is plenty of space ...

If I'm not mistaken, what you are requesting is that for the default styles the tab width allocation strategy can be configured to use the most space possible.


Run the following command to reproduce:

kitty --config=NONE -o tab_bar_style=separator -o allow_remote_control=y sh -c 'for i in {1..20}; do kitty @ launch --type=tab --title=1; done; kitty @ launch --type=tab --title=long_tab_title_here_long_tab_title_here'

When there are too many short titles, the long ones don't display properly at all, even if there is very enough space.

ces42 commented 2 years ago

Yes, I don't think what I would like is possible currently. But actually if you assume that the tab drawing function is only going to display the title + some other stuff (like powerline decorations) that always occupies the same number of characters then it would suffice to just specify that maximum number of extra characters in either kitty.conf or maybe as a global variable in a custom tab_bar.py.

page-down commented 2 years ago

@kovidgoyal

After running the command I posted above, press ctrl+shift+t, at which point the new tab is not displayed on the tab bar. When ctrl+shift+tab is pressed to switch to the previous tab, the new tab just created will then be displayed at the end of the tab bar.

EDIT: The issue was resolved after updating to the latest commit a few minutes ago.

kovidgoyal commented 1 year ago

On Mon, Oct 03, 2022 at 03:57:26AM -0700, page-down wrote:

@kovidgoyal

After running the command I posted above, press ctrl+shift+t, at which point the new tab is not displayed on the tab bar. When ctrl+shift+tab is pressed to switch to the previous tab, the new tab just created will then be displayed at the end of the tab bar.

Doesnt happen for me, note that I just committed a fix for a possibly related bug.

ces42 commented 1 year ago

@kovidgoyal I've been trying to fiddle around with this trying to make it more efficient (currently if there's 20 extra, the default length is 10 and there's two "over-achievers" with ideal lengths 11 and 29 the over-achievers will get lengths 11 and 20 which is sub-optimal). In theory this isn't hard but I the issue that I have is that draw_tab is very opaque to me... It seems that when you use it in https://github.com/kovidgoyal/kitty/blob/master/kitty/tab_bar.py#L610 to determine the ideal width of a tab the number that you get will be (for the built-in tab formats) the width of the tab (including "decorations") plus that of the separating character (e.g. ">" for powerline) plus one. Is this correct? Also there seem to be situations where the powerline draw_tab function is called with a certain value of max_tab_length but the resulting tab ends up being one character longer (length measured as including the separator on the right but not on the left). Is there some reason for this?

kovidgoyal commented 1 year ago

On Sat, Oct 22, 2022 at 11:55:14PM -0700, Carlos Esparza wrote:

@kovidgoyal I've been trying to fiddle around with this trying to make it more efficient (currently if there's 20 extra, the default length is 10 and there's two "over-achievers" with ideal lengths 11 and 29 the over-achievers will get lengths 11 and 20 which is sub-optimal). In theory this isn't hard but I the issue that I have is that draw_tab is very opaque to me... It seems that when you use it in https://github.com/kovidgoyal/kitty/blob/master/kitty/tab_bar.py#L610 to determine the ideal width of a tab the number that you get will be (for the built-in tab formats) the width of the tab (including "decorations") plus that of the separating character (e.g. ">" for powerline) plus one. Is this correct?

No idea, I haven't memorised the output of that function in all cases :) It should include the full tab width including all content, decorations and separator, since draw_tab() is responsible for drawing all that. Dont know about the plus one. The idea is that draw_tab() puts the cursor at the position for drawing the next tab once it returns, so the length of the tab is defined as everything that comes before the start of the next tab.

Also there seem to be situations where the powerline draw_tab function is called with a certain value of max_tab_length but the resulting tab ends up being one character longer (length measured as including the separator on the right but not on the left). Is there some reason for this?

That sounds like a bug in the powerline implementation. I am not too familiar with it, as IIRC it was written by someone else (check git blame).