Allow stopping of URL detection at newlines via url_excluded_characters

Fixes #6122
This commit is contained in:
Kovid Goyal 2023-03-21 08:04:42 +05:30
parent 856fddec3c
commit f046884f23
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 23 additions and 10 deletions

View File

@ -82,6 +82,8 @@ Detailed list of changes
- X11: Fix a crash if the X server requests clipboard data after we have relinquished the clipboard (:iss:`5650`)
- Allow stopping of URL detection at newlines via :opt:`url_excluded_characters` (:iss:`6122`)
0.27.1 [2023-02-07]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -469,10 +469,15 @@
)
opt('url_excluded_characters', '',
ctype='!url_excluded_characters',
option_type='python_string', ctype='!url_excluded_characters',
long_text='''
Additional characters to be disallowed from URLs, when detecting URLs under the
mouse cursor. By default, all characters that are legal in URLs are allowed.
Additionally, newlines are allowed (but stripped). This is to accommodate
programs such as mutt that add hard line breaks even for continued lines.
:code:`\\\\n` can be added to this option to disable this behavior. Special
characters can be specified using backslash escapes, to specify a backslash use
a double backslash.
'''
)

View File

@ -3,8 +3,8 @@
# isort: skip_file
import typing
from kitty.conf.utils import (
merge_dicts, positive_float, positive_int, to_bool, to_cmdline, to_color, to_color_or_none,
unit_float
merge_dicts, positive_float, positive_int, python_string, to_bool, to_cmdline, to_color,
to_color_or_none, unit_float
)
from kitty.options.utils import (
action_alias, active_tab_title_template, allow_hyperlinks, bell_on_tab, box_drawing_scale,
@ -1302,7 +1302,7 @@ def url_color(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
ans['url_color'] = to_color(val)
def url_excluded_characters(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
ans['url_excluded_characters'] = str(val)
ans['url_excluded_characters'] = python_string(val)
def url_prefixes(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
ans['url_prefixes'] = url_prefixes(val)

View File

@ -2793,17 +2793,21 @@ screen_open_url(Screen *self) {
// URLs {{{
static void
extend_url(Screen *screen, Line *line, index_type *x, index_type *y, char_type sentinel) {
extend_url(Screen *screen, Line *line, index_type *x, index_type *y, char_type sentinel, bool newlines_allowed) {
unsigned int count = 0;
bool has_newline = false;
while(count++ < 10) {
if (*x != line->xnum - 1) break;
has_newline = !line->gpu_cells[line->xnum-1].attrs.next_char_was_wrapped;
if (*x != line->xnum - 1 || (!newlines_allowed && has_newline)) break;
bool next_line_starts_with_url_chars = false;
line = screen_visual_line(screen, *y + 2);
if (line) next_line_starts_with_url_chars = line_startswith_url_chars(line);
if (line) {
next_line_starts_with_url_chars = line_startswith_url_chars(line);
has_newline = !line->attrs.is_continued;
if (next_line_starts_with_url_chars && has_newline && !newlines_allowed) next_line_starts_with_url_chars = false;
}
line = screen_visual_line(screen, *y + 1);
if (!line) break;
// we deliberately allow non-continued lines as some programs, like
// mutt split URLs with newlines at line boundaries
index_type new_x = line_url_end_at(line, 0, false, sentinel, next_line_starts_with_url_chars);
if (!new_x && !line_startswith_url_chars(line)) break;
*y += 1; *x = new_x;
@ -2845,6 +2849,7 @@ screen_detect_url(Screen *screen, unsigned int x, unsigned int y) {
return hid;
}
char_type sentinel = 0;
bool newlines_allowed = !is_excluded_from_url('\n');
if (line) {
url_start = line_url_start_at(line, x);
if (url_start < line->xnum) {
@ -2852,6 +2857,7 @@ screen_detect_url(Screen *screen, unsigned int x, unsigned int y) {
if (y < screen->lines - 1) {
line = screen_visual_line(screen, y+1);
next_line_starts_with_url_chars = line_startswith_url_chars(line);
if (next_line_starts_with_url_chars && !newlines_allowed && !line->attrs.is_continued) next_line_starts_with_url_chars = false;
line = screen_visual_line(screen, y);
}
sentinel = get_url_sentinel(line, url_start);
@ -2861,7 +2867,7 @@ screen_detect_url(Screen *screen, unsigned int x, unsigned int y) {
}
if (has_url) {
index_type y_extended = y;
extend_url(screen, line, &url_end, &y_extended, sentinel);
extend_url(screen, line, &url_end, &y_extended, sentinel, newlines_allowed);
screen_mark_url(screen, url_start, y, url_end, y_extended);
} else {
screen_mark_url(screen, 0, 0, 0, 0);