mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-17 22:14:53 +02:00
A new option to control when hyperlinks are underlined
While kitty is never going to underline detected URLs as the performance of that is absurd, underlining hyperlinks specifically is acceptable, since they dont require detection. See #6766
This commit is contained in:
@@ -486,7 +486,8 @@ opt('detect_urls', 'yes',
|
||||
long_text='''
|
||||
Detect URLs under the mouse. Detected URLs are highlighted with an underline and
|
||||
the mouse cursor becomes a hand over them. Even if this option is disabled, URLs
|
||||
are still clickable.
|
||||
are still clickable. See also the :opt:`underline_hyperlinks` option to control
|
||||
how hyperlinks (as opposed to plain text URLs) are displayed.
|
||||
'''
|
||||
)
|
||||
|
||||
@@ -510,6 +511,16 @@ When the mouse hovers over a terminal hyperlink, show the actual URL that will
|
||||
be activated when the hyperlink is clicked.
|
||||
''')
|
||||
|
||||
|
||||
opt('underline_hyperlinks', 'hover', choices=('hover', 'always', 'never'),
|
||||
ctype='underline_hyperlinks', long_text='''
|
||||
Control how hyperlinks are underlined. They can either be underlined on mouse
|
||||
``hover``, ``always`` (i.e. permanently underlined) or ``never`` which means
|
||||
that kitty will not apply any underline styling to hyperlinks.
|
||||
Uses the :opt:`url_style` and :opt:`url_color` settings for the underline style.
|
||||
''')
|
||||
|
||||
|
||||
opt('copy_on_select', 'no',
|
||||
option_type='copy_on_select',
|
||||
long_text='''
|
||||
|
||||
8
kitty/options/parse.py
generated
8
kitty/options/parse.py
generated
@@ -1308,6 +1308,14 @@ class Parser:
|
||||
|
||||
choices_for_undercurl_style = frozenset(('thin-sparse', 'thin-dense', 'thick-sparse', 'thick-dense'))
|
||||
|
||||
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:
|
||||
raise ValueError(f"The value {val} is not a valid choice for underline_hyperlinks")
|
||||
ans["underline_hyperlinks"] = val
|
||||
|
||||
choices_for_underline_hyperlinks = frozenset(('hover', 'always', 'never'))
|
||||
|
||||
def update_check_interval(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
|
||||
ans['update_check_interval'] = float(val)
|
||||
|
||||
|
||||
15
kitty/options/to-c-generated.h
generated
15
kitty/options/to-c-generated.h
generated
@@ -291,6 +291,19 @@ convert_from_opts_show_hyperlink_targets(PyObject *py_opts, Options *opts) {
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_python_underline_hyperlinks(PyObject *val, Options *opts) {
|
||||
opts->underline_hyperlinks = underline_hyperlinks(val);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_opts_underline_hyperlinks(PyObject *py_opts, Options *opts) {
|
||||
PyObject *ret = PyObject_GetAttrString(py_opts, "underline_hyperlinks");
|
||||
if (ret == NULL) return;
|
||||
convert_from_python_underline_hyperlinks(ret, opts);
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_python_select_by_word_characters(PyObject *val, Options *opts) {
|
||||
select_by_word_characters(val, opts);
|
||||
@@ -1143,6 +1156,8 @@ convert_opts_from_python_opts(PyObject *py_opts, Options *opts) {
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_show_hyperlink_targets(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_underline_hyperlinks(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_select_by_word_characters(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_select_by_word_characters_forward(py_opts, opts);
|
||||
|
||||
@@ -57,6 +57,16 @@ window_title_in(PyObject *title_in) {
|
||||
return ALL;
|
||||
}
|
||||
|
||||
static UnderlineHyperlinks
|
||||
underline_hyperlinks(PyObject *x) {
|
||||
const char *in = PyUnicode_AsUTF8(x);
|
||||
switch(in[0]) {
|
||||
case 'a': return UNDERLINE_ALWAYS;
|
||||
case 'n': return UNDERLINE_NEVER;
|
||||
default : return UNDERLINE_ON_HOVER;
|
||||
}
|
||||
}
|
||||
|
||||
static BackgroundImageLayout
|
||||
bglayout(PyObject *layout_name) {
|
||||
const char *name = PyUnicode_AsUTF8(layout_name);
|
||||
|
||||
3
kitty/options/types.py
generated
3
kitty/options/types.py
generated
@@ -29,6 +29,7 @@ choices_for_tab_bar_style = typing.Literal['fade', 'hidden', 'powerline', 'separ
|
||||
choices_for_tab_powerline_style = typing.Literal['angled', 'round', 'slanted']
|
||||
choices_for_tab_switch_strategy = typing.Literal['last', 'left', 'previous', 'right']
|
||||
choices_for_undercurl_style = typing.Literal['thin-sparse', 'thin-dense', 'thick-sparse', 'thick-dense']
|
||||
choices_for_underline_hyperlinks = typing.Literal['hover', 'always', 'never']
|
||||
choices_for_window_logo_position = typing.Literal['top-left', 'top', 'top-right', 'left', 'center', 'right', 'bottom-left', 'bottom', 'bottom-right']
|
||||
|
||||
option_names = ( # {{{
|
||||
@@ -432,6 +433,7 @@ option_names = ( # {{{
|
||||
'text_fg_override_threshold',
|
||||
'touch_scroll_multiplier',
|
||||
'undercurl_style',
|
||||
'underline_hyperlinks',
|
||||
'update_check_interval',
|
||||
'url_color',
|
||||
'url_excluded_characters',
|
||||
@@ -588,6 +590,7 @@ class Options:
|
||||
text_fg_override_threshold: float = 0.0
|
||||
touch_scroll_multiplier: float = 1.0
|
||||
undercurl_style: choices_for_undercurl_style = 'thin-sparse'
|
||||
underline_hyperlinks: choices_for_underline_hyperlinks = 'hover'
|
||||
update_check_interval: float = 24.0
|
||||
url_color: Color = Color(0, 135, 189)
|
||||
url_excluded_characters: str = ''
|
||||
|
||||
Reference in New Issue
Block a user