Do fine grained clearing of URL ranges

This matches what is done for selections. This is a very slight
performance hit (one extra easily predicted branch)
since most of the time url ranges is empty.

Fixes #8414
This commit is contained in:
Kovid Goyal 2025-03-09 18:45:52 +05:30
parent a5d4ca3735
commit e84a8fd7e9
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C

View file

@ -48,6 +48,10 @@ clear_selection(Selections *selections) {
selections->count = 0;
}
static void
clear_all_selections(Screen *self) { clear_selection(&self->selections); clear_selection(&self->url_ranges); }
static void
init_tabstops(bool *tabstops, index_type count) {
// In terminfo we specify the number of initial tabstops (it) as 8
@ -202,8 +206,7 @@ screen_reset(Screen *self) {
init_tabstops(self->alt_tabstops, self->columns);
cursor_reset(self->cursor);
self->is_dirty = true;
clear_selection(&self->selections);
clear_selection(&self->url_ranges);
clear_all_selections(self);
screen_cursor_position(self, 1, 1);
set_dynamic_color(self, 110, NULL);
set_dynamic_color(self, 111, NULL);
@ -542,8 +545,7 @@ screen_resize(Screen *self, unsigned int lines, unsigned int columns) {
init_tabstops(self->main_tabstops, self->columns);
init_tabstops(self->alt_tabstops, self->columns);
self->is_dirty = true;
clear_selection(&self->selections);
clear_selection(&self->url_ranges);
clear_all_selections(self);
self->last_visited_prompt.is_set = false;
#define S(c, w) c->x = MIN(w.after.x, self->columns - 1); c->y = MIN(w.after.y, self->lines - 1);
S(self->cursor, cursor);
@ -687,10 +689,16 @@ selection_intersects_screen_lines(const Selections *selections, int a, int b) {
}
static void
clear_intersecting_selections(Screen *self, index_type y) {
if (selection_has_screen_line(&self->selections, y)) clear_selection(&self->selections);
if (selection_has_screen_line(&self->url_ranges, y)) clear_selection(&self->url_ranges);
}
static void
init_text_loop_line(Screen *self, text_loop_state *s) {
linebuf_init_cells(self->linebuf, self->cursor->y, &s->cp, &s->gp);
if (selection_has_screen_line(&self->selections, self->cursor->y)) clear_selection(&self->selections);
clear_intersecting_selections(self, self->cursor->y);
linebuf_mark_line_dirty(self->linebuf, self->cursor->y);
s->image_placeholder_marked = false;
}
@ -1501,7 +1509,7 @@ screen_toggle_screen_buffer(Screen *self, bool save_cursor, bool clear_alt_scree
screen_history_scroll(self, SCROLL_FULL, false);
self->is_dirty = true;
grman_mark_layers_dirty(self->grman);
clear_selection(&self->selections);
clear_all_selections(self);
global_state.check_for_active_animated_images = true;
}
@ -2328,7 +2336,7 @@ screen_erase_in_line(Screen *self, unsigned int how, bool private) {
line_apply_cursor(self->linebuf->line, self->cursor, s, n, true);
}
self->is_dirty = true;
if (selection_has_screen_line(&self->selections, self->cursor->y)) clear_selection(&self->selections);
clear_intersecting_selections(self, self->cursor->y);
linebuf_mark_line_dirty(self->linebuf, self->cursor->y);
}
}
@ -2428,6 +2436,7 @@ screen_erase_in_display(Screen *self, unsigned int how, bool private) {
if (nuke_multicell_chars) nuke_multicell_char_intersecting_with(self, 0, self->columns, a, b, false);
self->is_dirty = true;
if (selection_intersects_screen_lines(&self->selections, a, b)) clear_selection(&self->selections);
if (selection_intersects_screen_lines(&self->url_ranges, a, b)) clear_selection(&self->url_ranges);
}
if (how < 2) {
screen_erase_in_line(self, how, private);
@ -2451,7 +2460,7 @@ screen_insert_lines(Screen *self, unsigned int count) {
screen_dirty_line_graphics(self, top, bottom, self->linebuf == self->main_linebuf);
linebuf_insert_lines(self->linebuf, count, self->cursor->y, bottom);
self->is_dirty = true;
clear_selection(&self->selections);
clear_all_selections(self);
screen_carriage_return(self);
// remove split multiline chars at bottom of screen
cells = linebuf_cpu_cells_for_line(self->linebuf, bottom);
@ -2496,7 +2505,7 @@ screen_delete_lines(Screen *self, unsigned int count) {
screen_dirty_line_graphics(self, top, bottom, self->linebuf == self->main_linebuf);
linebuf_delete_lines(self->linebuf, count, self->cursor->y, bottom);
self->is_dirty = true;
clear_selection(&self->selections);
clear_all_selections(self);
screen_carriage_return(self);
}
}
@ -2513,7 +2522,7 @@ screen_insert_characters(Screen *self, unsigned int count) {
line_apply_cursor(self->linebuf->line, self->cursor, x, num, true);
linebuf_mark_line_dirty(self->linebuf, self->cursor->y);
self->is_dirty = true;
if (selection_has_screen_line(&self->selections, self->cursor->y)) clear_selection(&self->selections);
clear_intersecting_selections(self, self->cursor->y);
}
}
@ -2557,7 +2566,7 @@ screen_delete_characters(Screen *self, unsigned int count) {
line_apply_cursor(self->linebuf->line, self->cursor, self->columns - num, num, true);
linebuf_mark_line_dirty(self->linebuf, self->cursor->y);
self->is_dirty = true;
if (selection_has_screen_line(&self->selections, self->cursor->y)) clear_selection(&self->selections);
clear_intersecting_selections(self, self->cursor->y);
}
}
@ -2572,7 +2581,7 @@ screen_erase_characters(Screen *self, unsigned int count) {
line_apply_cursor(self->linebuf->line, self->cursor, x, num, true);
linebuf_mark_line_dirty(self->linebuf, self->cursor->y);
self->is_dirty = true;
if (selection_has_screen_line(&self->selections, self->cursor->y)) clear_selection(&self->selections);
clear_intersecting_selections(self, self->cursor->y);
}
// }}}
@ -3248,7 +3257,6 @@ screen_update_cell_data(Screen *self, void *address, FONTS_DATA_HANDLE fonts_dat
const bool is_overlay_active = screen_is_overlay_active(self);
unsigned int history_line_added_count = self->history_line_added_count;
index_type lnum;
bool was_dirty = self->is_dirty;
screen_reset_dirty(self);
update_overlay_position(self);
if (self->scrolled_by) self->scrolled_by = MIN(self->scrolled_by + history_line_added_count, self->historybuf->count);
@ -3287,7 +3295,6 @@ screen_update_cell_data(Screen *self, void *address, FONTS_DATA_HANDLE fonts_dat
}
update_overlay_line_data(self, address);
}
if (was_dirty) clear_selection(&self->url_ranges);
}
static bool