From a6ab23279a7b515b1f67d23a0dcc3fa21acf291c Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 20 Nov 2024 20:54:03 +0000 Subject: Fix word navigation on lines with tabs, from Alexander Arch. --- usr.bin/tmux/grid-reader.c | 19 ++++++++----------- usr.bin/tmux/grid.c | 26 +++++++++++++++++++++++++- usr.bin/tmux/tmux.h | 5 +++-- usr.bin/tmux/window-copy.c | 8 ++------ 4 files changed, 38 insertions(+), 20 deletions(-) diff --git a/usr.bin/tmux/grid-reader.c b/usr.bin/tmux/grid-reader.c index d1b1a4fb500..40c71a3ac36 100644 --- a/usr.bin/tmux/grid-reader.c +++ b/usr.bin/tmux/grid-reader.c @@ -1,4 +1,4 @@ -/* $OpenBSD: grid-reader.c,v 1.8 2024/10/25 15:00:18 nicm Exp $ */ +/* $OpenBSD: grid-reader.c,v 1.9 2024/11/20 20:54:02 nicm Exp $ */ /* * Copyright (c) 2020 Anindya Mukherjee @@ -180,19 +180,14 @@ grid_reader_handle_wrap(struct grid_reader *gr, u_int *xx, u_int *yy) int grid_reader_in_set(struct grid_reader *gr, const char *set) { - struct grid_cell gc; - - grid_get_cell(gr->gd, gr->cx, gr->cy, &gc); - if (gc.flags & GRID_FLAG_PADDING) - return (0); - return (utf8_cstrhas(set, &gc.data)); + return (grid_in_set(gr->gd, gr->cx, gr->cy, set)); } /* Move cursor to the start of the next word. */ void grid_reader_cursor_next_word(struct grid_reader *gr, const char *separators) { - u_int xx, yy; + u_int xx, yy, width; /* Do not break up wrapped words. */ if (grid_get_line(gr->gd, gr->cy)->flags & GRID_LINE_WRAPPED) @@ -229,8 +224,8 @@ grid_reader_cursor_next_word(struct grid_reader *gr, const char *separators) } } while (grid_reader_handle_wrap(gr, &xx, &yy) && - grid_reader_in_set(gr, WHITESPACE)) - gr->cx++; + (width = grid_reader_in_set(gr, WHITESPACE))) + gr->cx += width; } /* Move cursor to the end of the next word. */ @@ -425,7 +420,9 @@ grid_reader_cursor_back_to_indentation(struct grid_reader *gr) xx = grid_line_length(gr->gd, py); for (px = 0; px < xx; px++) { grid_get_cell(gr->gd, px, py, &gc); - if (gc.data.size != 1 || *gc.data.data != ' ') { + if ((gc.data.size != 1 || *gc.data.data != ' ') && + ~gc.flags & GRID_FLAG_TAB && + ~gc.flags & GRID_FLAG_PADDING) { gr->cx = px; gr->cy = py; return; diff --git a/usr.bin/tmux/grid.c b/usr.bin/tmux/grid.c index 9dfab95a165..03ab901ab3e 100644 --- a/usr.bin/tmux/grid.c +++ b/usr.bin/tmux/grid.c @@ -1,4 +1,4 @@ -/* $OpenBSD: grid.c,v 1.134 2024/11/08 08:51:36 nicm Exp $ */ +/* $OpenBSD: grid.c,v 1.135 2024/11/20 20:54:02 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -1561,3 +1561,27 @@ grid_line_length(struct grid *gd, u_int py) } return (px); } + +/* Check if character is in set. */ +int +grid_in_set(struct grid *gd, u_int px, u_int py, const char *set) +{ + struct grid_cell gc, tmp_gc; + u_int pxx; + + grid_get_cell(gd, px, py, &gc); + if (strchr(set, '\t')) { + if (gc.flags & GRID_FLAG_PADDING) { + pxx = px; + do + grid_get_cell(gd, --pxx, py, &tmp_gc); + while (pxx > 0 && tmp_gc.flags & GRID_FLAG_PADDING); + if (tmp_gc.flags & GRID_FLAG_TAB) + return (tmp_gc.data.width - (px - pxx)); + } else if (gc.flags & GRID_FLAG_TAB) + return (gc.data.width); + } + if (gc.flags & GRID_FLAG_PADDING) + return (0); + return (utf8_cstrhas(set, &gc.data)); +} diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 73985b8f8de..80a42c257b7 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1243 2024/11/15 14:09:04 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1244 2024/11/20 20:54:02 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -605,7 +605,7 @@ enum tty_code_code { }; /* Character classes. */ -#define WHITESPACE " " +#define WHITESPACE "\t " /* Mode keys. */ #define MODEKEY_EMACS 0 @@ -2944,6 +2944,7 @@ void grid_reflow(struct grid *, u_int); void grid_wrap_position(struct grid *, u_int, u_int, u_int *, u_int *); void grid_unwrap_position(struct grid *, u_int *, u_int *, u_int, u_int); u_int grid_line_length(struct grid *, u_int); +int grid_in_set(struct grid *, u_int, u_int, const char *); /* grid-reader.c */ void grid_reader_start(struct grid_reader *, struct grid *, u_int, u_int); diff --git a/usr.bin/tmux/window-copy.c b/usr.bin/tmux/window-copy.c index 078750f67f5..51ecb286ef7 100644 --- a/usr.bin/tmux/window-copy.c +++ b/usr.bin/tmux/window-copy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-copy.c,v 1.366 2024/11/12 10:06:35 nicm Exp $ */ +/* $OpenBSD: window-copy.c,v 1.367 2024/11/20 20:54:02 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -5033,12 +5033,8 @@ window_copy_in_set(struct window_mode_entry *wme, u_int px, u_int py, const char *set) { struct window_copy_mode_data *data = wme->data; - struct grid_cell gc; - grid_get_cell(data->backing->grid, px, py, &gc); - if (gc.flags & GRID_FLAG_PADDING) - return (0); - return (utf8_cstrhas(set, &gc.data)); + return (grid_in_set(data->backing->grid, px, py, set)); } static u_int -- cgit v1.2.3