When in alternate screen and using margins, index selections more intelligently, gives slightly nicer behavior with multiplexer horizontal panes.

This commit is contained in:
Kovid Goyal
2025-04-03 17:22:25 +05:30
parent 4c28200cab
commit 251ec3419b

View File

@@ -270,10 +270,42 @@ is_selection_empty(const Selection *s) {
return s->start.x == s->end.x && s->start.in_left_half_of_cell == s->end.in_left_half_of_cell && start_y == end_y;
}
static bool
selection_intersects_screen_lines(const Selections *selections, int a, int b) {
if (a > b) SWAP(a, b);
for (size_t i = 0; i < selections->count; i++) {
const Selection *s = selections->items + i;
if (!is_selection_empty(s)) {
int start = (int)s->start.y - s->start_scrolled_by;
int end = (int)s->end.y - s->end_scrolled_by;
int top = MIN(start, end);
int bottom = MAX(start, end);
if ((top <= a && bottom >= a) || (top >= a && top <= b)) return true;
}
}
return false;
}
static void
index_selection(const Screen *self, Selections *selections, bool up) {
index_selection(const Screen *self, Selections *selections, bool up, index_type top, index_type bottom) {
const bool needs_special_handling = self->linebuf == self->alt_linebuf && (top > 0 || bottom < self->lines - 1);
for (size_t i = 0; i < selections->count; i++) {
Selection *s = selections->items + i;
if (is_selection_empty(s)) continue;
if (needs_special_handling) {
int start = (int)s->start.y - s->start_scrolled_by;
int end = (int)s->end.y - s->end_scrolled_by;
int stop = MIN(start, end);
int sbottom = MAX(start, end);
if (stop < (int)top) {
if (sbottom < (int)top) continue;
clear_selection(selections); return;
} else {
if (stop > (int)bottom) continue;
if (sbottom > (int)bottom) { clear_selection(selections); return; }
}
}
if (up) {
if (s->start.y == 0) s->start_scrolled_by += 1;
else {
@@ -319,7 +351,7 @@ index_selection(const Screen *self, Selections *selections, bool up) {
} \
INDEX_GRAPHICS(1) \
self->is_dirty = true; \
index_selection(self, &self->selections, false); \
index_selection(self, &self->selections, false, top, bottom); \
clear_selection(&self->url_ranges);
@@ -674,23 +706,6 @@ selection_has_screen_line(const Selections *selections, const int y) {
return false;
}
static bool
selection_intersects_screen_lines(const Selections *selections, int a, int b) {
if (a > b) SWAP(a, b);
for (size_t i = 0; i < selections->count; i++) {
const Selection *s = selections->items + i;
if (!is_selection_empty(s)) {
int start = (int)s->start.y - s->start_scrolled_by;
int end = (int)s->end.y - s->end_scrolled_by;
int top = MIN(start, end);
int bottom = MAX(start, end);
if ((top <= a && bottom >= a) || (top >= a && top <= b)) return true;
}
}
return false;
}
static void
clear_intersecting_selections(Screen *self, index_type y) {
if (selection_has_screen_line(&self->selections, y)) clear_selection(&self->selections);
@@ -1998,7 +2013,7 @@ screen_cursor_to_column(Screen *self, unsigned int column) {
} \
linebuf_clear_line(self->linebuf, bottom, true); \
self->is_dirty = true; \
index_selection(self, &self->selections, true); \
index_selection(self, &self->selections, true, top, bottom); \
clear_selection(&self->url_ranges);
void