Allow controlling placement of bell and activity symbols in the tab title template
Fixes #4581
This commit is contained in:
parent
68d2ea3f27
commit
9c13e8a549
@ -92,8 +92,9 @@ Detailed list of changes
|
||||
|
||||
- Improve the UI of the ask kitten (:iss:`4545`)
|
||||
|
||||
- Allow using templates with text formatting for :opt:`tab_activity_symbol`
|
||||
(:pull:`4507`)
|
||||
- Allow customizing the placement and formatting of the
|
||||
:opt:`tab_activity_symbol` and :opt:`bell_on_tab` symbols
|
||||
by adding them to the :opt:`tab_title_template` (:iss:`4581`, :pull:`4507`)
|
||||
|
||||
- macOS: Persist "Secure Keyboard Entry" across restarts to match the behavior
|
||||
of Terminal.app (:iss:`4471`)
|
||||
|
||||
@ -695,11 +695,17 @@ taskbar flash on linux.
|
||||
'''
|
||||
)
|
||||
|
||||
opt('bell_on_tab', 'yes',
|
||||
option_type='to_bool',
|
||||
opt('bell_on_tab', '"🔔 "',
|
||||
option_type='bell_on_tab',
|
||||
long_text='''
|
||||
Show a bell symbol on the tab if a bell occurs in one of the windows in the tab
|
||||
and the window is not the currently focused window
|
||||
Some text or a unicode symbol to show on the tab if a window in the tab that
|
||||
does not have focus has a bell. If you want to use leading or trailing
|
||||
spaces surround the text with quotes. See :opt:`tab_title_template` for how
|
||||
this is rendered.
|
||||
|
||||
For backwards compatibility, values of :code:`yes`, :code:`y`, :code:`true` are
|
||||
converted to the default bell symbol and :code:`no`, :code:`n`, :code:`false`,
|
||||
:code:`none` are converted to the empty string.
|
||||
'''
|
||||
)
|
||||
|
||||
@ -1054,16 +1060,15 @@ opt('tab_activity_symbol', 'none',
|
||||
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. You can also use text formatting via the same templating
|
||||
system as for :opt:`tab_title_template`.
|
||||
surround the text with quotes. See :opt:`tab_title_template` for how this is rendered.
|
||||
'''
|
||||
)
|
||||
|
||||
opt('tab_title_template', '"{title}"',
|
||||
opt('tab_title_template', '"{fmt.fg.red}{bell_symbol}{activity_symbol}{fmt.fg.default}{title}"',
|
||||
option_type='tab_title_template',
|
||||
long_text='''
|
||||
A template to render the tab title. The default just renders the title. If you
|
||||
wish to include the tab-index as well, use something like: :code:`{index}:
|
||||
A template to render the tab title. The default just renders the title with optional symbols for bell and activity.
|
||||
If you wish to include the tab-index as well, use something like: :code:`{index}:
|
||||
{title}`. Useful if you have shortcuts mapped for :code:`goto_tab N`. If you
|
||||
prefer to see the index as a superscript, use {sup.index}. In
|
||||
addition you can use :code:`{layout_name}` for the current layout name,
|
||||
@ -1077,6 +1082,8 @@ directives, for example:
|
||||
:code:`{fmt.fg.red}red{fmt.fg.default}normal{fmt.bg._00FF00}green
|
||||
bg{fmt.bg.tab}`. Similarly, for bold and italic:
|
||||
:code:`{fmt.bold}bold{fmt.nobold}normal{fmt.italic}italic{fmt.noitalic}`.
|
||||
Note that for backward compatibility, if :code:`{bell_symbol}` or :code:`{activity_symbol}`
|
||||
are not present in the template, they are prepended to it.
|
||||
'''
|
||||
)
|
||||
|
||||
|
||||
4
kitty/options/parse.py
generated
4
kitty/options/parse.py
generated
@ -7,7 +7,7 @@ from kitty.conf.utils import (
|
||||
)
|
||||
from kitty.options.utils import (
|
||||
action_alias, active_tab_title_template, adjust_baseline, adjust_line_height, allow_hyperlinks,
|
||||
allow_remote_control, box_drawing_scale, clear_all_mouse_actions, clear_all_shortcuts,
|
||||
allow_remote_control, bell_on_tab, box_drawing_scale, clear_all_mouse_actions, clear_all_shortcuts,
|
||||
clipboard_control, config_or_absolute_path, copy_on_select, cursor_text_color,
|
||||
deprecated_hide_window_decorations_aliases, deprecated_macos_show_window_title_in_menubar_alias,
|
||||
deprecated_send_text, disable_ligatures, edge_width, env, font_features, hide_window_decorations,
|
||||
@ -83,7 +83,7 @@ class Parser:
|
||||
ans['bell_border_color'] = to_color(val)
|
||||
|
||||
def bell_on_tab(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['bell_on_tab'] = to_bool(val)
|
||||
ans['bell_on_tab'] = bell_on_tab(val)
|
||||
|
||||
def bell_path(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['bell_path'] = config_or_absolute_path(val)
|
||||
|
||||
6
kitty/options/types.py
generated
6
kitty/options/types.py
generated
@ -465,7 +465,7 @@ class Options:
|
||||
background_opacity: float = 1.0
|
||||
background_tint: float = 0
|
||||
bell_border_color: Color = Color(255, 90, 0)
|
||||
bell_on_tab: bool = True
|
||||
bell_on_tab: str = '🔔 '
|
||||
bell_path: typing.Optional[str] = None
|
||||
bold_font: str = 'auto'
|
||||
bold_italic_font: str = 'auto'
|
||||
@ -552,7 +552,7 @@ class Options:
|
||||
startup_session: typing.Optional[str] = None
|
||||
strip_trailing_spaces: choices_for_strip_trailing_spaces = 'never'
|
||||
sync_to_monitor: bool = True
|
||||
tab_activity_symbol: typing.Optional[str] = None
|
||||
tab_activity_symbol: str = ''
|
||||
tab_bar_align: choices_for_tab_bar_align = 'left'
|
||||
tab_bar_background: typing.Optional[kitty.fast_data_types.Color] = None
|
||||
tab_bar_edge: int = 3
|
||||
@ -565,7 +565,7 @@ class Options:
|
||||
tab_powerline_style: choices_for_tab_powerline_style = 'angled'
|
||||
tab_separator: str = ' ┇'
|
||||
tab_switch_strategy: choices_for_tab_switch_strategy = 'previous'
|
||||
tab_title_template: str = '{title}'
|
||||
tab_title_template: str = '{fmt.fg.red}{bell_symbol}{activity_symbol}{fmt.fg.default}{title}'
|
||||
term: str = 'xterm-kitty'
|
||||
touch_scroll_multiplier: float = 1.0
|
||||
update_check_interval: float = 24.0
|
||||
|
||||
@ -639,10 +639,19 @@ def tab_fade(x: str) -> Tuple[float, ...]:
|
||||
return tuple(map(unit_float, x.split()))
|
||||
|
||||
|
||||
def tab_activity_symbol(x: str) -> Optional[str]:
|
||||
def tab_activity_symbol(x: str) -> str:
|
||||
if x == 'none':
|
||||
return None
|
||||
return tab_title_template(x) or None
|
||||
return ''
|
||||
return tab_title_template(x)
|
||||
|
||||
|
||||
def bell_on_tab(x: str) -> str:
|
||||
xl = x.lower()
|
||||
if xl in ('yes', 'y', 'true'):
|
||||
return '🔔 '
|
||||
if xl in ('no', 'n', 'false', 'none'):
|
||||
return ''
|
||||
return tab_title_template(x)
|
||||
|
||||
|
||||
def tab_title_template(x: str) -> str:
|
||||
|
||||
@ -38,8 +38,7 @@ class DrawData(NamedTuple):
|
||||
leading_spaces: int
|
||||
sep: str
|
||||
trailing_spaces: int
|
||||
bell_on_tab: bool
|
||||
bell_fg: int
|
||||
bell_on_tab: str
|
||||
alpha: Sequence[float]
|
||||
active_fg: Color
|
||||
active_bg: Color
|
||||
@ -48,7 +47,7 @@ class DrawData(NamedTuple):
|
||||
default_bg: Color
|
||||
title_template: str
|
||||
active_title_template: Optional[str]
|
||||
tab_activity_symbol: Optional[str]
|
||||
tab_activity_symbol: str
|
||||
powerline_style: PowerlineStyle
|
||||
tab_bar_edge: EdgeLiteral
|
||||
|
||||
@ -182,28 +181,16 @@ def draw_title(draw_data: DrawData, screen: Screen, tab: TabBarData, index: int)
|
||||
'fmt': Formatter,
|
||||
'sup': SupSub(data),
|
||||
'sub': SupSub(data, True),
|
||||
'bell_symbol': draw_data.bell_on_tab if tab.needs_attention else '',
|
||||
'activity_symbol': draw_data.tab_activity_symbol if tab.has_activity_since_last_focus else '',
|
||||
}
|
||||
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
|
||||
fg = screen.cursor.fg
|
||||
screen.cursor.fg = draw_data.bell_fg
|
||||
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)
|
||||
if screen.cursor.fg == draw_data.bell_fg:
|
||||
screen.cursor.fg = fg
|
||||
|
||||
template = draw_data.title_template
|
||||
if tab.is_active and draw_data.active_title_template is not None:
|
||||
template = draw_data.active_title_template
|
||||
if '{activity_symbol' not in template:
|
||||
template = '{fmt.fg.red}{activity_symbol}{fmt.fg.default}' + template
|
||||
if '{bell_symbol' not in template:
|
||||
template = '{fmt.fg.red}{bell_symbol}{fmt.fg.default}' + template
|
||||
try:
|
||||
title = eval(compile_template(template), {'__builtins__': {}}, eval_locals)
|
||||
except Exception as e:
|
||||
@ -445,9 +432,8 @@ class TabBar:
|
||||
|
||||
self.active_bg = as_rgb(color_as_int(opts.active_tab_background))
|
||||
self.active_fg = as_rgb(color_as_int(opts.active_tab_foreground))
|
||||
self.bell_fg = as_rgb(0xff0000)
|
||||
self.draw_data = DrawData(
|
||||
self.leading_spaces, self.sep, self.trailing_spaces, opts.bell_on_tab, self.bell_fg,
|
||||
self.leading_spaces, self.sep, self.trailing_spaces, opts.bell_on_tab,
|
||||
opts.tab_fade, opts.active_tab_foreground, opts.active_tab_background,
|
||||
opts.inactive_tab_foreground, opts.inactive_tab_background,
|
||||
opts.tab_bar_background or opts.background, opts.tab_title_template,
|
||||
@ -567,7 +553,7 @@ class TabBar:
|
||||
if s.cursor.x > s.columns - max_title_length and t is not last_tab:
|
||||
s.cursor.x = s.columns - 2
|
||||
s.cursor.bg = as_rgb(color_as_int(self.draw_data.default_bg))
|
||||
s.cursor.fg = self.bell_fg
|
||||
s.cursor.fg = as_rgb(0xff0000)
|
||||
s.draw(' …')
|
||||
break
|
||||
s.erase_in_line(0, False) # Ensure no long titles bleed after the last tab
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user