Skip to content

Commit 12f37bc

Browse files
committed
Dont strip trailing punctuation from end of URL if next line startswith url characters
1 parent e86c712 commit 12f37bc

File tree

4 files changed

+32
-7
lines changed

4 files changed

+32
-7
lines changed

kitty/line.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,24 @@ line_url_start_at(Line *self, index_type x) {
133133
}
134134

135135
index_type
136-
line_url_end_at(Line *self, index_type x, bool check_short, char_type sentinel) {
136+
line_url_end_at(Line *self, index_type x, bool check_short, char_type sentinel, bool next_line_starts_with_url_chars) {
137137
index_type ans = x;
138138
if (x >= self->xnum || (check_short && self->xnum <= MIN_URL_LEN + 3)) return 0;
139139
if (sentinel) { while (ans < self->xnum && self->cpu_cells[ans].ch != sentinel && is_url_char(self->cpu_cells[ans].ch)) ans++; }
140140
else { while (ans < self->xnum && is_url_char(self->cpu_cells[ans].ch)) ans++; }
141141
if (ans) ans--;
142-
while (ans > x && can_strip_from_end_of_url(self->cpu_cells[ans].ch)) ans--;
142+
if (ans < self->xnum - 1 || !next_line_starts_with_url_chars) {
143+
while (ans > x && can_strip_from_end_of_url(self->cpu_cells[ans].ch)) ans--;
144+
}
143145
return ans;
144146
}
145147

148+
bool
149+
line_startswith_url_chars(Line *self) {
150+
return is_url_char(self->cpu_cells[0].ch);
151+
}
152+
153+
146154
static PyObject*
147155
url_start_at(Line *self, PyObject *x) {
148156
#define url_start_at_doc "url_start_at(x) -> Return the start cell number for a URL containing x or self->xnum if not found"
@@ -153,8 +161,9 @@ static PyObject*
153161
url_end_at(Line *self, PyObject *args) {
154162
#define url_end_at_doc "url_end_at(x) -> Return the end cell number for a URL containing x or 0 if not found"
155163
unsigned int x, sentinel = 0;
156-
if (!PyArg_ParseTuple(args, "I|I", &x, &sentinel)) return NULL;
157-
return PyLong_FromUnsignedLong((unsigned long)line_url_end_at(self, x, true, sentinel));
164+
int next_line_starts_with_url_chars = 0;
165+
if (!PyArg_ParseTuple(args, "I|Ip", &x, &sentinel, &next_line_starts_with_url_chars)) return NULL;
166+
return PyLong_FromUnsignedLong((unsigned long)line_url_end_at(self, x, true, sentinel, next_line_starts_with_url_chars));
158167
}
159168

160169
// }}}

kitty/lineops.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ void line_set_char(Line *, unsigned int , uint32_t , unsigned int , Cursor *, bo
6161
void line_right_shift(Line *, unsigned int , unsigned int );
6262
void line_add_combining_char(Line *, uint32_t , unsigned int );
6363
index_type line_url_start_at(Line *self, index_type x);
64-
index_type line_url_end_at(Line *self, index_type x, bool, char_type);
64+
index_type line_url_end_at(Line *self, index_type x, bool, char_type, bool);
65+
bool line_startswith_url_chars(Line*);
6566
index_type line_as_ansi(Line *self, Py_UCS4 *buf, index_type buflen, bool*, const GPUCell**) __attribute__((nonnull));
6667
unsigned int line_length(Line *self);
6768
size_t cell_as_unicode(CPUCell *cell, bool include_cc, Py_UCS4 *buf, char_type);

kitty/mouse.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,11 +227,14 @@ extend_url(Screen *screen, Line *line, index_type *x, index_type *y, char_type s
227227
unsigned int count = 0;
228228
while(count++ < 10) {
229229
if (*x != line->xnum - 1) break;
230+
bool next_line_starts_with_url_chars = false;
231+
line = screen_visual_line(screen, *y + 2);
232+
if (line) next_line_starts_with_url_chars = line_startswith_url_chars(line);
230233
line = screen_visual_line(screen, *y + 1);
231234
if (!line) break;
232235
// we deliberately allow non-continued lines as some programs, like
233236
// mutt split URLs with newlines at line boundaries
234-
index_type new_x = line_url_end_at(line, 0, false, sentinel);
237+
index_type new_x = line_url_end_at(line, 0, false, sentinel, next_line_starts_with_url_chars);
235238
if (!new_x) break;
236239
*y += 1; *x = new_x;
237240
}
@@ -274,7 +277,15 @@ detect_url(Screen *screen, unsigned int x, unsigned int y) {
274277
if (line) {
275278
url_start = line_url_start_at(line, x);
276279
sentinel = get_url_sentinel(line, url_start);
277-
if (url_start < line->xnum) url_end = line_url_end_at(line, x, true, sentinel);
280+
if (url_start < line->xnum) {
281+
bool next_line_starts_with_url_chars = false;
282+
if (y < screen->lines - 1) {
283+
line = screen_visual_line(screen, y+1);
284+
next_line_starts_with_url_chars = line_startswith_url_chars(line);
285+
line = screen_visual_line(screen, y);
286+
}
287+
url_end = line_url_end_at(line, x, true, sentinel, next_line_starts_with_url_chars);
288+
}
278289
has_url = url_end > url_start;
279290
}
280291
if (has_url) {

kitty_tests/datatypes.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,10 @@ def no_url(t):
285285
l4 = create('http://a.b?q=1' + trail)
286286
self.ae(l4.url_end_at(1), len(l4) - 1)
287287

288+
l4 = create('http://a.b.')
289+
self.ae(l4.url_end_at(0), len(l4) - 2)
290+
self.ae(l4.url_end_at(0, 0, True), len(l4) - 1)
291+
288292
def rewrap(self, lb, lb2):
289293
hb = HistoryBuf(lb2.ynum, lb2.xnum)
290294
cy = lb.rewrap(lb2, hb)

0 commit comments

Comments
 (0)