mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-27 10:41:58 +02:00
Option to control underline exclusion
This commit is contained in:
@@ -218,6 +218,14 @@ the curl will peak once per character, with dense twice.
|
||||
'''
|
||||
)
|
||||
|
||||
opt('underline_exclusion', '1', option_type='underline_exclusion', ctype='!underline_exclusion', long_text='''
|
||||
By default kitty renders gaps in underlines when they overlap with descenders
|
||||
(the parts of letters below the baseline, such as for y, q, p etc.). This option
|
||||
controls the thickness of the gaps. It can be either a unitless number in which
|
||||
case it is a fraction of the underline thickness as specified in the font or
|
||||
it can have a suffix of :code:`px` for pixels or :code:`pt` for points.
|
||||
''')
|
||||
|
||||
opt('text_composition_strategy', 'platform',
|
||||
ctype='!text_composition_strategy',
|
||||
long_text='''
|
||||
|
||||
9
kitty/options/parse.py
generated
9
kitty/options/parse.py
generated
@@ -19,9 +19,9 @@ from kitty.options.utils import (
|
||||
shell_integration, store_multiple, symbol_map, tab_activity_symbol, tab_bar_edge,
|
||||
tab_bar_margin_height, tab_bar_min_tabs, tab_fade, tab_font_style, tab_separator,
|
||||
tab_title_template, titlebar_color, to_cursor_shape, to_cursor_unfocused_shape, to_font_size,
|
||||
to_layout_names, to_modifiers, transparent_background_colors, url_prefixes, url_style,
|
||||
visual_bell_duration, visual_window_select_characters, window_border_width, window_logo_scale,
|
||||
window_size
|
||||
to_layout_names, to_modifiers, transparent_background_colors, underline_exclusion, url_prefixes,
|
||||
url_style, visual_bell_duration, visual_window_select_characters, window_border_width,
|
||||
window_logo_scale, window_size
|
||||
)
|
||||
|
||||
|
||||
@@ -1344,6 +1344,9 @@ class Parser:
|
||||
|
||||
choices_for_undercurl_style = frozenset(('thin-sparse', 'thin-dense', 'thick-sparse', 'thick-dense'))
|
||||
|
||||
def underline_exclusion(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['underline_exclusion'] = underline_exclusion(val)
|
||||
|
||||
def underline_hyperlinks(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
val = val.lower()
|
||||
if val not in self.choices_for_underline_hyperlinks:
|
||||
|
||||
15
kitty/options/to-c-generated.h
generated
15
kitty/options/to-c-generated.h
generated
@@ -83,6 +83,19 @@ convert_from_opts_undercurl_style(PyObject *py_opts, Options *opts) {
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_python_underline_exclusion(PyObject *val, Options *opts) {
|
||||
underline_exclusion(val, opts);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_opts_underline_exclusion(PyObject *py_opts, Options *opts) {
|
||||
PyObject *ret = PyObject_GetAttrString(py_opts, "underline_exclusion");
|
||||
if (ret == NULL) return;
|
||||
convert_from_python_underline_exclusion(ret, opts);
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_python_text_composition_strategy(PyObject *val, Options *opts) {
|
||||
text_composition_strategy(val, opts);
|
||||
@@ -1163,6 +1176,8 @@ convert_opts_from_python_opts(PyObject *py_opts, Options *opts) {
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_undercurl_style(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_underline_exclusion(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_text_composition_strategy(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_cursor_shape(py_opts, opts);
|
||||
|
||||
@@ -380,6 +380,16 @@ menu_map(PyObject *entry_dict, Options *opts) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
underline_exclusion(PyObject *val, Options *opts) {
|
||||
if (!PyTuple_Check(val)) { PyErr_SetString(PyExc_TypeError, "underline_exclusion must be a tuple"); return; }
|
||||
opts->underline_exclusion.thickness = PyFloat_AsFloat(PyTuple_GET_ITEM(val, 0));
|
||||
if (PyUnicode_CompareWithASCIIString(PyTuple_GET_ITEM(val, 1), "%")) opts->underline_exclusion.unit = 0;
|
||||
else if (PyUnicode_CompareWithASCIIString(PyTuple_GET_ITEM(val, 1), "px")) opts->underline_exclusion.unit = 1;
|
||||
else if (PyUnicode_CompareWithASCIIString(PyTuple_GET_ITEM(val, 1), "pt")) opts->underline_exclusion.unit = 2;
|
||||
else opts->underline_exclusion.unit = 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
text_composition_strategy(PyObject *val, Options *opts) {
|
||||
if (!PyUnicode_Check(val)) { PyErr_SetString(PyExc_TypeError, "text_rendering_strategy must be a string"); return; }
|
||||
|
||||
2
kitty/options/types.py
generated
2
kitty/options/types.py
generated
@@ -447,6 +447,7 @@ option_names = (
|
||||
'touch_scroll_multiplier',
|
||||
'transparent_background_colors',
|
||||
'undercurl_style',
|
||||
'underline_exclusion',
|
||||
'underline_hyperlinks',
|
||||
'update_check_interval',
|
||||
'url_color',
|
||||
@@ -615,6 +616,7 @@ class Options:
|
||||
touch_scroll_multiplier: float = 1.0
|
||||
transparent_background_colors: typing.Tuple[typing.Tuple[kitty.fast_data_types.Color, float], ...] = ()
|
||||
undercurl_style: choices_for_undercurl_style = 'thin-sparse'
|
||||
underline_exclusion: tuple[float, typing.Literal['%', 'px', 'pt']] = (1.0, '%')
|
||||
underline_hyperlinks: choices_for_underline_hyperlinks = 'hover'
|
||||
update_check_interval: float = 24.0
|
||||
url_color: Color = Color(0, 135, 189)
|
||||
|
||||
@@ -1017,6 +1017,20 @@ def shell_integration(x: str) -> FrozenSet[str]:
|
||||
return q
|
||||
|
||||
|
||||
def underline_exclusion(x: str) -> tuple[float, Literal['%', 'px', 'pt']]:
|
||||
try:
|
||||
return float(x), '%'
|
||||
except Exception:
|
||||
unit: Literal['%', 'pt', 'px'] = x[-2:] # type: ignore
|
||||
if unit not in ('px', 'pt', '%'):
|
||||
raise ValueError(f'Invalid underline_exclusion with unrecognized unit: {x}')
|
||||
try:
|
||||
val = float(x[:-2])
|
||||
except Exception:
|
||||
raise ValueError(f'Invalid underline_exclusion with non numberic value: {x}')
|
||||
return val, unit
|
||||
|
||||
|
||||
def paste_actions(x: str) -> FrozenSet[str]:
|
||||
s = frozenset({'quote-urls-at-prompt', 'confirm', 'filter', 'confirm-if-large', 'replace-dangerous-control-codes', 'replace-newline', 'no-op'})
|
||||
q = frozenset(x.lower().split(','))
|
||||
|
||||
Reference in New Issue
Block a user