parent
868626c79c
commit
a82bc6738c
@ -7,6 +7,9 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
|||||||
0.23.2 [future]
|
0.23.2 [future]
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
- A new option :option:`tab_bar_align` to draw the tab bar centered or right
|
||||||
|
aligned (:iss:`3946`)
|
||||||
|
|
||||||
- Allow the user to supply a custom Python function to draw tab bar. See
|
- Allow the user to supply a custom Python function to draw tab bar. See
|
||||||
:option:`tab_bar_style`
|
:option:`tab_bar_style`
|
||||||
|
|
||||||
|
|||||||
@ -1058,6 +1058,9 @@ class Screen:
|
|||||||
def has_activity_since_last_focus(self) -> bool:
|
def has_activity_since_last_focus(self) -> bool:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def insert_characters(self, num: int) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def set_tab_bar_render_data(
|
def set_tab_bar_render_data(
|
||||||
os_window_id: int, xstart: float, ystart: float, dx: float, dy: float,
|
os_window_id: int, xstart: float, ystart: float, dx: float, dy: float,
|
||||||
|
|||||||
@ -907,6 +907,8 @@ The tab bar style, can be one of:
|
|||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
|
|
||||||
|
opt('tab_bar_align', 'left', choices=('left', 'center', 'right'), long_text='The horizontal alignment of the tab bar')
|
||||||
|
|
||||||
opt('tab_bar_min_tabs', '2',
|
opt('tab_bar_min_tabs', '2',
|
||||||
option_type='tab_bar_min_tabs', ctype='uint',
|
option_type='tab_bar_min_tabs', ctype='uint',
|
||||||
long_text='The minimum number of tabs that must exist before the tab bar is shown'
|
long_text='The minimum number of tabs that must exist before the tab bar is shown'
|
||||||
|
|||||||
8
kitty/options/parse.py
generated
8
kitty/options/parse.py
generated
@ -1152,6 +1152,14 @@ class Parser:
|
|||||||
def tab_activity_symbol(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
def tab_activity_symbol(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||||
ans['tab_activity_symbol'] = tab_activity_symbol(val)
|
ans['tab_activity_symbol'] = tab_activity_symbol(val)
|
||||||
|
|
||||||
|
def tab_bar_align(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||||
|
val = val.lower()
|
||||||
|
if val not in self.choices_for_tab_bar_align:
|
||||||
|
raise ValueError(f"The value {val} is not a valid choice for tab_bar_align")
|
||||||
|
ans["tab_bar_align"] = val
|
||||||
|
|
||||||
|
choices_for_tab_bar_align = frozenset(('left', 'center', 'right'))
|
||||||
|
|
||||||
def tab_bar_background(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
def tab_bar_background(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||||
ans['tab_bar_background'] = to_color_or_none(val)
|
ans['tab_bar_background'] = to_color_or_none(val)
|
||||||
|
|
||||||
|
|||||||
4
kitty/options/types.py
generated
4
kitty/options/types.py
generated
@ -23,6 +23,7 @@ if typing.TYPE_CHECKING:
|
|||||||
choices_for_pointer_shape_when_dragging = typing.Literal['arrow', 'beam', 'hand']
|
choices_for_pointer_shape_when_dragging = typing.Literal['arrow', 'beam', 'hand']
|
||||||
choices_for_pointer_shape_when_grabbed = typing.Literal['arrow', 'beam', 'hand']
|
choices_for_pointer_shape_when_grabbed = typing.Literal['arrow', 'beam', 'hand']
|
||||||
choices_for_strip_trailing_spaces = typing.Literal['always', 'never', 'smart']
|
choices_for_strip_trailing_spaces = typing.Literal['always', 'never', 'smart']
|
||||||
|
choices_for_tab_bar_align = typing.Literal['left', 'center', 'right']
|
||||||
choices_for_tab_bar_style = typing.Literal['fade', 'hidden', 'powerline', 'separator', 'slant', 'custom']
|
choices_for_tab_bar_style = typing.Literal['fade', 'hidden', 'powerline', 'separator', 'slant', 'custom']
|
||||||
choices_for_tab_powerline_style = typing.Literal['angled', 'round', 'slanted']
|
choices_for_tab_powerline_style = typing.Literal['angled', 'round', 'slanted']
|
||||||
choices_for_tab_switch_strategy = typing.Literal['last', 'left', 'previous', 'right']
|
choices_for_tab_switch_strategy = typing.Literal['last', 'left', 'previous', 'right']
|
||||||
@ -35,6 +36,7 @@ else:
|
|||||||
choices_for_pointer_shape_when_dragging = str
|
choices_for_pointer_shape_when_dragging = str
|
||||||
choices_for_pointer_shape_when_grabbed = str
|
choices_for_pointer_shape_when_grabbed = str
|
||||||
choices_for_strip_trailing_spaces = str
|
choices_for_strip_trailing_spaces = str
|
||||||
|
choices_for_tab_bar_align = str
|
||||||
choices_for_tab_bar_style = str
|
choices_for_tab_bar_style = str
|
||||||
choices_for_tab_powerline_style = str
|
choices_for_tab_powerline_style = str
|
||||||
choices_for_tab_switch_strategy = str
|
choices_for_tab_switch_strategy = str
|
||||||
@ -404,6 +406,7 @@ option_names = ( # {{{
|
|||||||
'symbol_map',
|
'symbol_map',
|
||||||
'sync_to_monitor',
|
'sync_to_monitor',
|
||||||
'tab_activity_symbol',
|
'tab_activity_symbol',
|
||||||
|
'tab_bar_align',
|
||||||
'tab_bar_background',
|
'tab_bar_background',
|
||||||
'tab_bar_edge',
|
'tab_bar_edge',
|
||||||
'tab_bar_margin_height',
|
'tab_bar_margin_height',
|
||||||
@ -536,6 +539,7 @@ class Options:
|
|||||||
strip_trailing_spaces: choices_for_strip_trailing_spaces = 'never'
|
strip_trailing_spaces: choices_for_strip_trailing_spaces = 'never'
|
||||||
sync_to_monitor: bool = True
|
sync_to_monitor: bool = True
|
||||||
tab_activity_symbol: typing.Optional[str] = None
|
tab_activity_symbol: typing.Optional[str] = None
|
||||||
|
tab_bar_align: choices_for_tab_bar_align = 'left'
|
||||||
tab_bar_background: typing.Optional[kitty.rgb.Color] = None
|
tab_bar_background: typing.Optional[kitty.rgb.Color] = None
|
||||||
tab_bar_edge: int = 3
|
tab_bar_edge: int = 3
|
||||||
tab_bar_margin_height: TabBarMarginHeight = TabBarMarginHeight(outer=0, inner=0)
|
tab_bar_margin_height: TabBarMarginHeight = TabBarMarginHeight(outer=0, inner=0)
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from functools import lru_cache, wraps
|
from functools import lru_cache, partial, wraps
|
||||||
from typing import (
|
from typing import (
|
||||||
Any, Callable, Dict, List, NamedTuple, Optional, Sequence, Tuple
|
Any, Callable, Dict, List, NamedTuple, Optional, Sequence, Tuple
|
||||||
)
|
)
|
||||||
@ -415,6 +415,12 @@ class TabBar:
|
|||||||
self.draw_func = load_custom_draw_tab()
|
self.draw_func = load_custom_draw_tab()
|
||||||
else:
|
else:
|
||||||
self.draw_func = draw_tab_with_fade
|
self.draw_func = draw_tab_with_fade
|
||||||
|
if opts.tab_bar_align == 'center':
|
||||||
|
self.align: Callable[[], None] = partial(self.align_with_factor, 2)
|
||||||
|
elif opts.tab_bar_align == 'right':
|
||||||
|
self.align = self.align_with_factor
|
||||||
|
else:
|
||||||
|
self.align = lambda: None
|
||||||
|
|
||||||
def patch_colors(self, spec: Dict[str, Any]) -> None:
|
def patch_colors(self, spec: Dict[str, Any]) -> None:
|
||||||
if 'active_tab_foreground' in spec:
|
if 'active_tab_foreground' in spec:
|
||||||
@ -497,6 +503,17 @@ class TabBar:
|
|||||||
break
|
break
|
||||||
s.erase_in_line(0, False) # Ensure no long titles bleed after the last tab
|
s.erase_in_line(0, False) # Ensure no long titles bleed after the last tab
|
||||||
self.cell_ranges = cr
|
self.cell_ranges = cr
|
||||||
|
self.align()
|
||||||
|
|
||||||
|
def align_with_factor(self, factor: int = 1) -> None:
|
||||||
|
if not self.cell_ranges:
|
||||||
|
return
|
||||||
|
end = self.cell_ranges[-1][1]
|
||||||
|
if end < self.screen.columns - 1:
|
||||||
|
shift = (self.screen.columns - end) // factor
|
||||||
|
self.screen.cursor.x = 0
|
||||||
|
self.screen.insert_characters(shift)
|
||||||
|
self.cell_ranges = [(s + shift, e + shift) for (s, e) in self.cell_ranges]
|
||||||
|
|
||||||
def destroy(self) -> None:
|
def destroy(self) -> None:
|
||||||
self.screen.reset_callbacks()
|
self.screen.reset_callbacks()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user