@@ -103,6 +103,7 @@ def as_rgb(x: int) -> int:
103103
104104
105105VERTICAL_EDGES = frozenset ({LEFT_EDGE , RIGHT_EDGE })
106+ MAX_VERTICAL_TAB_LINES = 2
106107
107108
108109def is_vertical_edge (edge : int ) -> bool :
@@ -118,6 +119,14 @@ def edge_name(edge: int) -> EdgeLiteral:
118119 }.get (edge , 'bottom' )
119120
120121
122+ def normalized_tab_bar_align (align : str ) -> str :
123+ if align == 'left' :
124+ return 'start'
125+ if align == 'right' :
126+ return 'end'
127+ return align
128+
129+
121130@lru_cache
122131def report_template_failure (template : str , e : str ) -> None :
123132 log_error (f'Invalid tab title template: "{ template } " with error: { e } ' )
@@ -657,15 +666,16 @@ def apply_options(self) -> None:
657666 self .draw_func = load_custom_draw_tab ()
658667 else :
659668 self .draw_func = draw_tab_with_fade
660- if opts .tab_bar_align == 'center' :
669+ self .tab_bar_align = normalized_tab_bar_align (opts .tab_bar_align )
670+ if self .tab_bar_align == 'center' :
661671 self .align_factor = 2
662- elif opts .tab_bar_align == 'right ' :
672+ elif self .tab_bar_align == 'end ' :
663673 self .align_factor = 1
664674 else :
665675 self .align_factor = 0
666- if opts .tab_bar_align == 'center' :
676+ if self .tab_bar_align == 'center' :
667677 self .align : Callable [[], None ] = partial (self .align_with_factor , 2 )
668- elif opts .tab_bar_align == 'right ' :
678+ elif self .tab_bar_align == 'end ' :
669679 self .align = self .align_with_factor
670680 else :
671681 self .align = lambda : None
@@ -886,23 +896,33 @@ def update_vertical(self, data: Sequence[TabBarData]) -> None:
886896 if not data :
887897 return
888898 max_tab_length = max (1 , s .columns - 1 )
889- rows_to_draw = min (len (data ), s .lines )
890- draw_ellipsis = len (data ) > s .lines and s .lines > 1
899+ tab_line_height = max (1 , min (MAX_VERTICAL_TAB_LINES , s .lines // max (1 , len (data ))))
900+ rows_to_draw = min (len (data ), max (1 , s .lines // tab_line_height ))
901+ draw_ellipsis = len (data ) > rows_to_draw and s .lines > 1
891902 if draw_ellipsis :
903+ tab_line_height = 1
904+ rows_to_draw = min (len (data ), s .lines )
892905 rows_to_draw -= 1
906+ total_lines = rows_to_draw * tab_line_height + int (draw_ellipsis )
907+ if self .tab_bar_align == 'center' :
908+ start_row = max (0 , (s .lines - total_lines ) // 2 )
909+ elif self .tab_bar_align == 'end' :
910+ start_row = max (0 , s .lines - total_lines )
911+ else :
912+ start_row = 0
893913 cr : list [TabExtent ] = []
894914 for i , t in enumerate (data [:rows_to_draw ]):
895915 s .cursor .x = 0
896- s .cursor .y = i
916+ row = start_row + i * tab_line_height
917+ s .cursor .y = row
897918 s .cursor .bg = as_rgb (self .draw_data .tab_bg (t ))
898919 s .cursor .fg = as_rgb (self .draw_data .tab_fg (t ))
899920 s .cursor .bold , s .cursor .italic = self .active_font_style if t .is_active else self .inactive_font_style
900- end = self .draw_func (self .draw_data , s , t , 0 , max_tab_length , i + 1 , True , ExtraData ())
901- self .align_row (i , end )
902- cr .append (TabExtent (tab_id = t .tab_id , x = CellRange (0 , s .columns - 1 ), y = CellRange (i , i )))
921+ self .draw_func (self .draw_data , s , t , 0 , max_tab_length , i + 1 , True , ExtraData ())
922+ cr .append (TabExtent (tab_id = t .tab_id , x = CellRange (0 , s .columns - 1 ), y = CellRange (row , min (s .lines - 1 , row + tab_line_height - 1 ))))
903923 if draw_ellipsis :
904924 s .cursor .x = 0
905- s .cursor .y = s . lines - 1
925+ s .cursor .y = start_row + rows_to_draw * tab_line_height
906926 s .cursor .bg = as_rgb (color_as_int (self .draw_data .default_bg ))
907927 s .cursor .fg = as_rgb (0xff0000 )
908928 s .draw ('…' )
@@ -918,16 +938,6 @@ def align_with_factor(self, factor: int = 1) -> None:
918938 self .screen .insert_characters (shift )
919939 self .tab_extents = tuple (te .shifted (x = shift ) for te in self .tab_extents )
920940
921- def align_row (self , row : int , end : int ) -> None :
922- if not self .align_factor :
923- return
924- if end < self .screen .columns - 1 :
925- shift = (self .screen .columns - end ) // self .align_factor
926- if shift > 0 :
927- self .screen .cursor .y = row
928- self .screen .cursor .x = 0
929- self .screen .insert_characters (shift )
930-
931941 def destroy (self ) -> None :
932942 self .screen .reset_callbacks ()
933943 del self .screen
0 commit comments