Allow using templates with text formatting for tab_activity_symbol

Fixes #4507
This commit is contained in:
Kovid Goyal 2022-01-14 08:18:04 +05:30
parent ecf4fcdeb0
commit 017da1159c
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 62 additions and 42 deletions

View File

@ -79,6 +79,9 @@ Detailed list of changes
- macOS: Allow opening text files, images and directories with kitty when
launched using "Open with" in Finder (:iss:`4460`)
- Allow using templates with text formatting for :opt:`tab_activity_symbol`
(:pull:`4507`)
- macOS: Persist "Secure Keyboard Entry" across restarts to match the behavior
of Terminal.app (:iss:`4471`)

View File

@ -1054,7 +1054,8 @@
long_text='''
Some text or a unicode symbol to show on the tab if a window in the tab that
does not have focus has some activity. If you want to use leading or trailing spaces
surround the text with quotes.
surround the text with quotes. You can also use text formatting via the same templating
system as for :opt:`tab_title_template`.
'''
)

View File

@ -4,7 +4,7 @@
import os
from functools import lru_cache, partial, wraps
from typing import (
Any, Callable, Dict, List, NamedTuple, Optional, Sequence, Tuple, Union
Any, Callable, Dict, List, NamedTuple, Optional, Sequence, Tuple, Union, TYPE_CHECKING
)
from .borders import Border, BorderColor
@ -20,6 +20,10 @@
from .utils import color_as_int, log_error
if TYPE_CHECKING:
import re
class TabBarData(NamedTuple):
title: str
is_active: bool
@ -152,48 +156,15 @@ class ExtraData:
next_tab: Optional[TabBarData] = None
def draw_title(draw_data: DrawData, screen: Screen, tab: TabBarData, index: int) -> None:
if tab.needs_attention and draw_data.bell_on_tab:
fg = screen.cursor.fg
screen.cursor.fg = draw_data.bell_fg
screen.draw('🔔 ')
screen.cursor.fg = fg
if tab.has_activity_since_last_focus and draw_data.tab_activity_symbol:
fg = screen.cursor.fg
screen.cursor.fg = draw_data.bell_fg
screen.draw(draw_data.tab_activity_symbol)
screen.cursor.fg = fg
@run_once
def attributed_string_pat() -> 're.Pattern[str]':
import re
return re.compile('(\x1b\\[[^m]*m)')
template = draw_data.title_template
if tab.is_active and draw_data.active_title_template is not None:
template = draw_data.active_title_template
try:
data = {
'index': index,
'layout_name': tab.layout_name,
'num_windows': tab.num_windows,
'num_window_groups': tab.num_window_groups,
'title': tab.title,
}
ColorFormatter.draw_data = draw_data
ColorFormatter.tab_data = tab
eval_locals = {
'index': index,
'layout_name': tab.layout_name,
'num_windows': tab.num_windows,
'num_window_groups': tab.num_window_groups,
'title': tab.title,
'fmt': Formatter,
'sup': SupSub(data),
'sub': SupSub(data, True),
}
title = eval(compile_template(template), {'__builtins__': {}}, eval_locals)
except Exception as e:
report_template_failure(template, str(e))
title = tab.title
def draw_attributed_string(title: str, screen: Screen) -> None:
if '\x1b' in title:
import re
for x in re.split('(\x1b\\[[^m]*m)', title):
for x in attributed_string_pat().split(title):
if x.startswith('\x1b') and x.endswith('m'):
screen.apply_sgr(x[2:-1])
else:
@ -202,6 +173,51 @@ def draw_title(draw_data: DrawData, screen: Screen, tab: TabBarData, index: int)
screen.draw(title)
def draw_title(draw_data: DrawData, screen: Screen, tab: TabBarData, index: int) -> None:
data = {
'index': index,
'layout_name': tab.layout_name,
'num_windows': tab.num_windows,
'num_window_groups': tab.num_window_groups,
'title': tab.title,
}
ColorFormatter.draw_data = draw_data
ColorFormatter.tab_data = tab
eval_locals = {
'index': index,
'layout_name': tab.layout_name,
'num_windows': tab.num_windows,
'num_window_groups': tab.num_window_groups,
'title': tab.title,
'fmt': Formatter,
'sup': SupSub(data),
'sub': SupSub(data, True),
}
if tab.needs_attention and draw_data.bell_on_tab:
fg = screen.cursor.fg
screen.cursor.fg = draw_data.bell_fg
screen.draw('🔔 ')
screen.cursor.fg = fg
if tab.has_activity_since_last_focus and draw_data.tab_activity_symbol:
template = draw_data.tab_activity_symbol
try:
text = eval(compile_template(template), {'__builtins__': {}}, eval_locals)
except Exception as e:
report_template_failure(template, str(e))
else:
draw_attributed_string(text, screen)
template = draw_data.title_template
if tab.is_active and draw_data.active_title_template is not None:
template = draw_data.active_title_template
try:
title = eval(compile_template(template), {'__builtins__': {}}, eval_locals)
except Exception as e:
report_template_failure(template, str(e))
title = tab.title
draw_attributed_string(title, screen)
DrawTabFunc = Callable[[DrawData, Screen, TabBarData, int, int, int, bool, ExtraData], int]