diff --git a/input.c b/input.c index 361efae9..f87ad665 100644 --- a/input.c +++ b/input.c @@ -503,35 +503,35 @@ execute_binding(struct seat *seat, struct terminal *term, case BIND_ACTION_SELECT_BEGIN: selection_start( - term, seat->mouse.col, seat->mouse.row, SELECTION_CHAR_WISE, false); + term, (struct coord){.row = seat->mouse.row, .col = seat->mouse.col}, SELECTION_CHAR_WISE, false); return true; case BIND_ACTION_SELECT_BEGIN_BLOCK: selection_start( - term, seat->mouse.col, seat->mouse.row, SELECTION_BLOCK, false); + term, (struct coord){.row = seat->mouse.row, .col = seat->mouse.col}, SELECTION_BLOCK, false); return true; case BIND_ACTION_SELECT_EXTEND: selection_extend( - seat, term, seat->mouse.col, seat->mouse.row, term->selection.kind); + seat, term, (struct coord){.row = seat->mouse.row, .col = seat->mouse.col}, term->selection.kind); return true; case BIND_ACTION_SELECT_EXTEND_CHAR_WISE: if (term->selection.kind != SELECTION_BLOCK) { selection_extend( - seat, term, seat->mouse.col, seat->mouse.row, SELECTION_CHAR_WISE); + seat, term, (struct coord){.row = seat->mouse.row, .col = seat->mouse.col}, SELECTION_CHAR_WISE); return true; } return false; case BIND_ACTION_SELECT_WORD: selection_start( - term, seat->mouse.col, seat->mouse.row, SELECTION_WORD_WISE, false); + term, (struct coord){.row = seat->mouse.row, .col = seat->mouse.col}, SELECTION_WORD_WISE, false); return true; case BIND_ACTION_SELECT_WORD_WS: selection_start( - term, seat->mouse.col, seat->mouse.row, SELECTION_WORD_WISE, true); + term, (struct coord){.row = seat->mouse.row, .col = seat->mouse.col}, SELECTION_WORD_WISE, true); return true; case BIND_ACTION_SELECT_QUOTE: @@ -541,7 +541,7 @@ execute_binding(struct seat *seat, struct terminal *term, case BIND_ACTION_SELECT_ROW: selection_start( - term, seat->mouse.col, seat->mouse.row, SELECTION_LINE_WISE, false); + term, (struct coord){.row = seat->mouse.row, .col = seat->mouse.col}, SELECTION_LINE_WISE, false); return true; case BIND_ACTION_COUNT: @@ -2786,7 +2786,7 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, seat->mouse.y >= term->margins.top && seat->mouse.y < term->height - term->margins.bottom))) { - selection_update(term, seat->mouse.col, seat->mouse.row); + selection_update(term, (struct coord){.row = seat->mouse.row, .col = seat->mouse.col}); } } diff --git a/selection.c b/selection.c index 43cd75ca..b8dec4d7 100644 --- a/selection.c +++ b/selection.c @@ -665,7 +665,7 @@ static void selection_start_linewise(struct terminal* const term, term->selection.pivot.start = term->selection.coords.start; term->selection.pivot.end = (struct coord){end.col, term->grid->view + end.row}; - selection_update(term, end.col, end.row); + selection_update(term, end); } // TODO (kociap): The function could be extended to match arbitrary @@ -723,14 +723,14 @@ void selection_start_matching_delimiters(struct terminal* const term, term->selection.pivot.end = (struct coord){delimiter_end.col, term->grid->view + delimiter_end.row}; term->selection.kind = SELECTION_WORD_WISE; - selection_update(term, delimiter_end.col, delimiter_end.row); + selection_update(term, delimiter_end); } else { selection_start_linewise(term, start); } } void -selection_start(struct terminal *term, int col, int row, +selection_start(struct terminal *term, struct coord const start, enum selection_kind kind, bool spaces_only) { @@ -750,7 +750,7 @@ selection_start(struct terminal *term, int col, int row, switch (kind) { case SELECTION_CHAR_WISE: case SELECTION_BLOCK: - term->selection.coords.start = (struct coord){col, term->grid->view + row}; + term->selection.coords.start = (struct coord){start.col, term->grid->view + start.row}; term->selection.coords.end = (struct coord){-1, -1}; term->selection.pivot.start = term->selection.coords.start; @@ -758,8 +758,8 @@ selection_start(struct terminal *term, int col, int row, break; case SELECTION_WORD_WISE: { - struct coord start = {col, term->grid->view + row}; - struct coord end = {col, term->grid->view + row}; + struct coord start = {start.col, term->grid->view + start.row}; + struct coord end = {start.col, term->grid->view + start.row}; selection_find_word_boundary_left(term, &start, spaces_only); selection_find_word_boundary_right(term, &end, spaces_only, true); @@ -777,12 +777,12 @@ selection_start(struct terminal *term, int col, int row, * view-local. */ - selection_update(term, end.col, end.row - term->grid->view); + selection_update(term, (struct coord){end.col, end.row - term->grid->view}); break; } case SELECTION_LINE_WISE: - selection_start_linewise(term, (struct coord){.row = row, .col = col}); + selection_start_linewise(term, start); break; case SELECTION_NONE: @@ -1133,7 +1133,7 @@ set_pivot_point_for_block_and_char_wise(struct terminal *term, } void -selection_update(struct terminal *term, int col, int row) +selection_update(struct terminal *term, struct coord const updated_end) { if (term->selection.coords.start.row < 0) return; @@ -1141,10 +1141,10 @@ selection_update(struct terminal *term, int col, int row) if (!term->selection.ongoing) return; - xassert(term->grid->view + row != -1); + xassert(term->grid->view + updated_end.row != -1); struct coord new_start = term->selection.coords.start; - struct coord new_end = {col, term->grid->view + row}; + struct coord new_end = {updated_end.col, term->grid->view + updated_end.row}; LOG_DBG("selection updated: start = %d,%d, end = %d,%d -> %d, %d", term->selection.coords.start.row, term->selection.coords.start.col, @@ -1211,13 +1211,13 @@ selection_update(struct terminal *term, int col, int row) case SELECTION_WORD_WISE: switch (term->selection.direction) { case SELECTION_LEFT: - new_end = (struct coord){col, term->grid->view + row}; + new_end = (struct coord){updated_end.col, term->grid->view + updated_end.row}; selection_find_word_boundary_left( term, &new_end, term->selection.spaces_only); break; case SELECTION_RIGHT: - new_end = (struct coord){col, term->grid->view + row}; + new_end = (struct coord){updated_end.col, term->grid->view + updated_end.row}; selection_find_word_boundary_right( term, &new_end, term->selection.spaces_only, true); break; @@ -1230,14 +1230,14 @@ selection_update(struct terminal *term, int col, int row) case SELECTION_LINE_WISE: switch (term->selection.direction) { case SELECTION_LEFT: { - struct coord end = {0, row}; + struct coord end = {0, updated_end.row}; selection_find_line_boundary_left(term, &end); new_end = (struct coord){end.col, term->grid->view + end.row}; break; } case SELECTION_RIGHT: { - struct coord end = {col, row}; + struct coord end = updated_end; selection_find_line_boundary_right(term, &end); new_end = (struct coord){end.col, term->grid->view + end.row}; break; @@ -1505,7 +1505,7 @@ selection_extend_block(struct terminal *term, int col, int row) void selection_extend(struct seat *seat, struct terminal *term, - int col, int row, enum selection_kind new_kind) + struct coord point, enum selection_kind new_kind) { if (term->selection.coords.start.row < 0 || term->selection.coords.end.row < 0) { /* No existing selection */ @@ -1517,10 +1517,10 @@ selection_extend(struct seat *seat, struct terminal *term, term->selection.ongoing = true; - row += term->grid->view; + point.row += term->grid->view; - if ((row == term->selection.coords.start.row && col == term->selection.coords.start.col) || - (row == term->selection.coords.end.row && col == term->selection.coords.end.col)) + if ((point.row == term->selection.coords.start.row && point.col == term->selection.coords.start.col) || + (point.row == term->selection.coords.end.row && point.col == term->selection.coords.end.col)) { /* Extension point *is* one of the current end points */ return; @@ -1534,11 +1534,11 @@ selection_extend(struct seat *seat, struct terminal *term, case SELECTION_CHAR_WISE: case SELECTION_WORD_WISE: case SELECTION_LINE_WISE: - selection_extend_normal(term, col, row, new_kind); + selection_extend_normal(term, point.col, point.row, new_kind); break; case SELECTION_BLOCK: - selection_extend_block(term, col, row); + selection_extend_block(term, point.col, point.row); break; } } @@ -1700,12 +1700,12 @@ fdm_scroll_timer(struct fdm *fdm, int fd, int events, void *data) case SELECTION_SCROLL_UP: cmd_scrollback_up(term, expiration_count); - selection_update(term, term->selection.auto_scroll.col, 0); + selection_update(term, (struct coord){.col = term->selection.auto_scroll.col, .row = 0}); break; case SELECTION_SCROLL_DOWN: cmd_scrollback_down(term, expiration_count); - selection_update(term, term->selection.auto_scroll.col, term->rows - 1); + selection_update(term, (struct coord){.col = term->selection.auto_scroll.col, .row = term->rows - 1}); break; } diff --git a/selection.h b/selection.h index cbdf88de..a8727a56 100644 --- a/selection.h +++ b/selection.h @@ -8,9 +8,8 @@ extern const struct wl_data_device_listener data_device_listener; extern const struct zwp_primary_selection_device_v1_listener primary_selection_device_listener; -void selection_start( - struct terminal *term, int col, int row, - enum selection_kind new_kind, bool spaces_only); +void selection_start(struct terminal *term, struct coord start, + enum selection_kind kind, bool spaces_only); // selection_start_matching_delimiters // @@ -20,18 +19,21 @@ void selection_start( // Currently, the delimiters are restricted to single quote (') and // double quote ("). // -void selection_start_matching_delimiters(struct terminal* const term, - struct coord const start, +// Parameters: +// start - coordinate (view-relative) of the start of the selection. +// +void selection_start_matching_delimiters(struct terminal* term, + struct coord start, bool spaces_only); -void selection_update(struct terminal *term, int col, int row); +void selection_update(struct terminal *term, struct coord updated_end); void selection_finalize( struct seat *seat, struct terminal *term, uint32_t serial); void selection_dirty_cells(struct terminal *term); void selection_cancel(struct terminal *term); void selection_extend( struct seat *seat, struct terminal *term, - int col, int row, enum selection_kind kind); + struct coord point, enum selection_kind kind); bool selection_on_rows(const struct terminal *term, int start, int end); @@ -90,11 +92,5 @@ void selection_start_scroll_timer( enum selection_scroll_direction direction, int col); void selection_stop_scroll_timer(struct terminal *term); -void selection_find_word_boundary_left( - const struct terminal *term, struct coord *pos, bool spaces_only); -void selection_find_word_boundary_right( - const struct terminal *term, struct coord *pos, bool spaces_only, - bool stop_on_space_to_word_boundary); - struct coord selection_get_start(const struct terminal *term); struct coord selection_get_end(const struct terminal *term); diff --git a/vimode.c b/vimode.c index bb98e71c..d801f05f 100644 --- a/vimode.c +++ b/vimode.c @@ -42,11 +42,12 @@ static enum search_direction invert_direction(enum search_direction direction) { return direction == SEARCH_FORWARD ? SEARCH_BACKWARD : SEARCH_FORWARD; } -static struct coord offset_to_view_relative(struct terminal *const term, - struct coord coord) { - coord.row += term->grid->offset; - coord.row -= term->grid->view; - return coord; +static struct coord cursor_to_view_relative(struct terminal *const term, + struct coord cursor) { + cursor.row += term->grid->offset; + cursor.row -= term->grid->view; + return cursor; +} } static struct coord view_to_offset_relative(struct terminal *const term, @@ -86,7 +87,7 @@ static struct coord delta_cursor_to_abs_coord(struct terminal *const term, static void damage_cursor_cell(struct terminal *const term) { struct coord const cursor = - offset_to_view_relative(term, term->vimode.cursor); + cursor_to_view_relative(term, term->vimode.cursor); term_damage_cell_in_view(term, cursor.row, cursor.col); render_refresh(term); } @@ -131,30 +132,31 @@ static void center_view_on_cursor(struct terminal *const term) { } } -static void update_selection(struct seat *const seat, - struct terminal *const term) { +static void update_selection(struct terminal *const term) { enum vi_mode const mode = term->vimode.mode; if (is_mode_visual(mode)) { - struct coord const cursor = term->grid->cursor.point; - printf("UPDATING SELECTION [row=%d; col=%d]\n", cursor.row, cursor.col); - selection_update(term, cursor.col, cursor.row); + struct coord const cursor = + cursor_to_view_relative(term, term->vimode.cursor); + selection_update(term, cursor); + printf("UPDATING SELECTION [row=%d; col=%d; selection.start=(%d,%d); " + "selection.end=(%d,%d)]\n", + cursor.row, cursor.col, term->selection.coords.start.row, + term->selection.coords.start.col, term->selection.coords.end.row, + term->selection.coords.end.col); } } static void damage_highlights(struct terminal *const term) { struct highlight_location const *location = term->vimode.highlights; int const offset = term->grid->offset; - printf("DAMAGING HIGHLIGHT CELLS: "); while (location != NULL) { struct coord const start = location->range.start; struct coord const end = location->range.end; for (int col = start.col; col <= end.col; col += 1) { - printf("(%d, %d) ", start.row, col); term_damage_cell(term, start.row - offset, col); } location = location->next; } - printf("\n"); render_refresh(term); } @@ -225,15 +227,10 @@ static void update_highlights(struct terminal *const term) { clear_highlights(term); calculate_highlight_regions(term); struct highlight_location const *location = term->vimode.highlights; - printf("NEW HIGHLIGHT REGIONS: "); while (location != NULL) { struct highlight_location const *next = location->next; - printf("[(%d, %d) - (%d, %d)] ", location->range.start.row, - location->range.start.col, location->range.end.row, - location->range.end.col); location = next; } - printf("\n"); damage_highlights(term); } @@ -407,6 +404,7 @@ void vimode_cancel(struct terminal *term) { cancel_search(term, false); clear_highlights(term); + selection_cancel(term); term->is_vimming = false; @@ -416,7 +414,6 @@ void vimode_cancel(struct terminal *term) { term_ime_enable(term); } - selection_cancel(term); struct grid *const grid = term->grid; grid->view = grid->offset; term_damage_view(term); @@ -810,7 +807,7 @@ void vimode_view_down(struct terminal *const term, int const delta) { static void move_cursor_delta(struct terminal *const term, struct coord const delta) { damage_cursor_cell(term); - struct coord cursor = offset_to_view_relative(term, term->vimode.cursor); + struct coord cursor = cursor_to_view_relative(term, term->vimode.cursor); cursor.row += delta.row; cursor.col += delta.col; @@ -872,72 +869,73 @@ static void execute_vimode_binding(struct seat *seat, struct terminal *term, if (term->grid != &term->normal) { return; } - + printf("PRE-ACTION DATA [offset=%d; view=%d]\n", term->grid->offset, + term->grid->view); switch (action) { case BIND_ACTION_VIMODE_NONE: break; case BIND_ACTION_VIMODE_UP: move_cursor_vertical(term, -1); - update_selection(seat, term); + update_selection(term); update_highlights(term); break; case BIND_ACTION_VIMODE_DOWN: move_cursor_vertical(term, 1); - update_selection(seat, term); + update_selection(term); update_highlights(term); break; case BIND_ACTION_VIMODE_LEFT: move_cursor_horizontal(term, -1); - update_selection(seat, term); + update_selection(term); break; case BIND_ACTION_VIMODE_RIGHT: move_cursor_horizontal(term, 1); - update_selection(seat, term); + update_selection(term); break; case BIND_ACTION_VIMODE_UP_PAGE: cmd_scrollback_up(term, term->rows); clip_cursor_to_view(term); - update_selection(seat, term); + update_selection(term); update_highlights(term); break; case BIND_ACTION_VIMODE_DOWN_PAGE: cmd_scrollback_down(term, term->rows); clip_cursor_to_view(term); - update_selection(seat, term); + update_selection(term); update_highlights(term); break; case BIND_ACTION_VIMODE_UP_HALF_PAGE: cmd_scrollback_up(term, max(term->rows / 2, 1)); clip_cursor_to_view(term); - update_selection(seat, term); + update_selection(term); update_highlights(term); break; case BIND_ACTION_VIMODE_DOWN_HALF_PAGE: cmd_scrollback_down(term, max(term->rows / 2, 1)); clip_cursor_to_view(term); - update_selection(seat, term); + update_selection(term); update_highlights(term); break; case BIND_ACTION_VIMODE_UP_LINE: cmd_scrollback_up(term, 1); clip_cursor_to_view(term); - update_selection(seat, term); + update_selection(term); update_highlights(term); break; case BIND_ACTION_VIMODE_DOWN_LINE: cmd_scrollback_down(term, 1); clip_cursor_to_view(term); - update_selection(seat, term); + update_selection(term); update_highlights(term); break; @@ -947,7 +945,7 @@ static void execute_vimode_binding(struct seat *seat, struct terminal *term, int const view_row = view_to_scrollback_relative(term); term->vimode.cursor.row = cursor_from_scrollback_relative(term, view_row); damage_cursor_cell(term); - update_selection(seat, term); + update_selection(term); update_highlights(term); break; } @@ -957,7 +955,7 @@ static void execute_vimode_binding(struct seat *seat, struct terminal *term, damage_cursor_cell(term); term->vimode.cursor.row = term->rows - 1; damage_cursor_cell(term); - update_selection(seat, term); + update_selection(term); update_highlights(term); break; @@ -1003,8 +1001,8 @@ static void execute_vimode_binding(struct seat *seat, struct terminal *term, grid_row_abs_to_sb(term->grid, term->rows, match.start.row), cursor_to_scrollback_relative(term, term->vimode.cursor.row), match.start.row, match.start.col); - // TODO (kociap): update selection. move_cursor_delta(term, delta); + update_selection(term); } update_highlights(term); break; @@ -1030,19 +1028,20 @@ static void execute_vimode_binding(struct seat *seat, struct terminal *term, } else { selection_cancel(term); struct coord const start = term->vimode.selection.start; - selection_start(term, start.col, start.row, selection, false); - struct coord const cursor = term->grid->cursor.point; - selection_update(term, cursor.col, cursor.row); + selection_start(term, start, selection, false); + struct coord const cursor = + cursor_to_view_relative(term, term->vimode.cursor); + selection_update(term, cursor); term->vimode.mode = mode; } } else if (term->vimode.mode == VI_MODE_NORMAL) { - struct coord const cursor = term->grid->cursor.point; - selection_start(term, cursor.col, cursor.row, selection, false); - selection_update(term, cursor.col, cursor.row); + struct coord const cursor = + cursor_to_view_relative(term, term->vimode.cursor); + selection_start(term, cursor, selection, false); + // selection_update(term, cursor.col, cursor.row); term->vimode.selection.start = cursor; term->vimode.mode = mode; } - // render_refresh(term); break; } @@ -1050,8 +1049,8 @@ static void execute_vimode_binding(struct seat *seat, struct terminal *term, // TODO (kociap): Should yank executed in non-visual mode copy the // current line? if (is_mode_visual(term->vimode.mode)) { + // Copy, clear the selection and exit the visual mode. selection_finalize(seat, term, serial); - // finalize only copies, but we also want to clear the selection selection_cancel(term); term->vimode.mode = VI_MODE_NORMAL; } @@ -1113,9 +1112,9 @@ static void execute_vimode_search_binding(struct seat *seat, grid_row_abs_to_sb(term->grid, term->rows, search->match.row), cursor_to_scrollback_relative(term, term->vimode.cursor.row), search->match.row, search->match.col); - // TODO (kociap): update selection. move_cursor_delta(term, delta); center_view_on_cursor(term); + update_selection(term); } confirm_search(term); break; @@ -1265,12 +1264,12 @@ void vimode_input(struct seat *seat, struct terminal *term, term->vimode.search.match_len = term->vimode.search.len; struct coord const delta = delta_cursor_to_abs_coord(term, term->vimode.search.match); - // TODO (kociap): update selection. move_cursor_delta(term, delta); center_view_on_cursor(term); } else { restore_pre_search_state(term); } + update_selection(term); update_highlights(term); } }