From 43ac8c281d5f80b19fac39213b898b812a3341d8 Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 5 Oct 2024 00:32:55 +0000 Subject: [PATCH] Add copy-mode-position-format to configure the position indicator. --- usr.bin/tmux/options-table.c | 14 +++++++- usr.bin/tmux/screen-write.c | 24 ++++++++++---- usr.bin/tmux/tmux.1 | 6 ++-- usr.bin/tmux/window-copy.c | 64 +++++++++++++++--------------------- 4 files changed, 61 insertions(+), 47 deletions(-) diff --git a/usr.bin/tmux/options-table.c b/usr.bin/tmux/options-table.c index 72b28c5f067..93c60b6bf3c 100644 --- a/usr.bin/tmux/options-table.c +++ b/usr.bin/tmux/options-table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: options-table.c,v 1.179 2024/10/02 11:51:15 nicm Exp $ */ +/* $OpenBSD: options-table.c,v 1.180 2024/10/05 00:32:55 nicm Exp $ */ /* * Copyright (c) 2011 Nicholas Marriott @@ -971,6 +971,18 @@ const struct options_table_entry options_table[] = { .text = "Style of the marked line in copy mode." }, + { .name = "copy-mode-position-format", + .type = OPTIONS_TABLE_STRING, + .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE, + .default_str = "#[align=right]" + "#{t/p:top_line_time}#{?#{e|>:#{top_line_time},0}, ,}" + "[#{scroll_position}/#{history_size}]" + "#{?search_timed_out, (timed out)," + "#{?search_count, (#{search_count}" + "#{?search_count_partial,+,} results),}}", + .text = "Format of the position indicator in copy mode." + }, + { .name = "fill-character", .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_WINDOW, diff --git a/usr.bin/tmux/screen-write.c b/usr.bin/tmux/screen-write.c index 17dfb1d33cb..66eb3fc7236 100644 --- a/usr.bin/tmux/screen-write.c +++ b/usr.bin/tmux/screen-write.c @@ -1,4 +1,4 @@ -/* $OpenBSD: screen-write.c,v 1.226 2024/08/21 04:17:09 nicm Exp $ */ +/* $OpenBSD: screen-write.c,v 1.227 2024/10/05 00:32:55 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -567,9 +567,11 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src, u_int px, u_int py, u_int nx, u_int ny) { struct screen *s = ctx->s; + struct window_pane *wp = ctx->wp; + struct tty_ctx ttyctx; struct grid *gd = src->grid; struct grid_cell gc; - u_int xx, yy, cx, cy; + u_int xx, yy, cx = s->cx, cy = s->cy; if (nx == 0 || ny == 0) return; @@ -578,18 +580,28 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src, for (yy = py; yy < py + ny; yy++) { if (yy >= gd->hsize + gd->sy) break; - cx = s->cx; + s->cx = cx; + if (wp != NULL) + screen_write_initctx(ctx, &ttyctx, 0); for (xx = px; xx < px + nx; xx++) { if (xx >= grid_get_line(gd, yy)->cellsize) break; grid_get_cell(gd, xx, yy, &gc); if (xx + gc.data.width > px + nx) break; - grid_view_set_cell(ctx->s->grid, cx, cy, &gc); - cx++; + grid_view_set_cell(ctx->s->grid, s->cx, s->cy, &gc); + if (wp != NULL) { + ttyctx.cell = &gc; + tty_write(tty_cmd_cell, &ttyctx); + ttyctx.ocx++; + } + s->cx++; } - cy++; + s->cy++; } + + s->cx = cx; + s->cy = cy; } /* Select character set for drawing border lines. */ diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index b11b13685dd..3968f6760b5 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.961 2024/10/04 22:36:11 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.962 2024/10/05 00:32:55 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: October 4 2024 $ +.Dd $Mdocdate: October 5 2024 $ .Dt TMUX 1 .Os .Sh NAME @@ -4833,6 +4833,8 @@ see the .Sx STYLES section. .Pp +.It Ic copy-mode-position-format Ar format +Format of the position indicator in copy mode. .It Xo Ic mode-keys .Op Ic vi | emacs .Xc diff --git a/usr.bin/tmux/window-copy.c b/usr.bin/tmux/window-copy.c index c06d1f14da1..d8f48cf4751 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.355 2024/10/04 07:03:08 nicm Exp $ */ +/* $OpenBSD: window-copy.c,v 1.356 2024/10/05 00:32:55 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -815,6 +815,11 @@ static void window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft) { struct window_copy_mode_data *data = wme->data; + u_int hsize = screen_hsize(data->backing); + struct grid_line *gl; + + gl = grid_get_line(data->backing->grid, hsize - data->oy); + format_add(ft, "top_line_time", "%llu", (unsigned long long)gl->time); format_add(ft, "scroll_position", "%d", data->oy); format_add(ft, "rectangle_toggle", "%d", data->rectflag); @@ -842,6 +847,7 @@ window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft) } format_add(ft, "search_present", "%d", data->searchmark != NULL); + format_add(ft, "search_timed_out", "%d", data->timeout); if (data->searchcount != -1) { format_add(ft, "search_count", "%d", data->searchcount); format_add(ft, "search_count_partial", "%d", data->searchmore); @@ -4190,11 +4196,12 @@ window_copy_write_line(struct window_mode_entry *wme, struct window_copy_mode_data *data = wme->data; struct screen *s = &data->screen; struct options *oo = wp->window->options; - struct grid_line *gl; struct grid_cell gc, mgc, cgc, mkgc; - char hdr[512], tmp[256], *t; - size_t size = 0; + u_int sx = screen_size_x(s); u_int hsize = screen_hsize(data->backing); + const char *value; + char *expanded; + struct format_tree *ft; style_apply(&gc, oo, "mode-style", NULL); gc.flags |= GRID_FLAG_NOPALETTE; @@ -4205,42 +4212,22 @@ window_copy_write_line(struct window_mode_entry *wme, style_apply(&mkgc, oo, "copy-mode-mark-style", NULL); mkgc.flags |= GRID_FLAG_NOPALETTE; - if (py == 0 && s->rupper < s->rlower && !data->hide_position) { - gl = grid_get_line(data->backing->grid, hsize - data->oy); - if (gl->time == 0) - xsnprintf(tmp, sizeof tmp, "[%u/%u]", data->oy, hsize); - else { - t = format_pretty_time(gl->time, 1); - xsnprintf(tmp, sizeof tmp, "%s [%u/%u]", t, data->oy, - hsize); - free(t); - } + window_copy_write_one(wme, ctx, py, hsize - data->oy + py, + screen_size_x(s), &mgc, &cgc, &mkgc); - if (data->searchmark == NULL) { - if (data->timeout) { - size = xsnprintf(hdr, sizeof hdr, - "(timed out) %s", tmp); - } else - size = xsnprintf(hdr, sizeof hdr, "%s", tmp); - } else { - if (data->searchcount == -1) - size = xsnprintf(hdr, sizeof hdr, "%s", tmp); - else { - size = xsnprintf(hdr, sizeof hdr, - "(%d%s results) %s", data->searchcount, - data->searchmore ? "+" : "", tmp); + if (py == 0 && s->rupper < s->rlower && !data->hide_position) { + value = options_get_string(oo, "copy-mode-position-format"); + if (*value != '\0') { + ft = format_create_defaults(NULL, NULL, NULL, NULL, wp); + expanded = format_expand(ft, value); + if (*expanded != '\0') { + log_debug("--> %s", expanded); + screen_write_cursormove(ctx, 0, 0, 0); + format_draw(ctx, &gc, sx, expanded, NULL, 0); } + free(expanded); + format_free(ft); } - if (size > screen_size_x(s)) - size = screen_size_x(s); - screen_write_cursormove(ctx, screen_size_x(s) - size, 0, 0); - screen_write_puts(ctx, &gc, "%s", hdr); - } else - size = 0; - - if (size < screen_size_x(s)) { - window_copy_write_one(wme, ctx, py, hsize - data->oy + py, - screen_size_x(s) - size, &mgc, &cgc, &mkgc); } if (py == data->cy && data->cx == screen_size_x(s)) { @@ -4673,7 +4660,8 @@ window_copy_copy_buffer(struct window_mode_entry *wme, const char *prefix, struct window_pane *wp = wme->wp; struct screen_write_ctx ctx; - if (set_clip && options_get_number(global_options, "set-clipboard") != 0) { + if (set_clip && + options_get_number(global_options, "set-clipboard") != 0) { screen_write_start_pane(&ctx, wp, NULL); screen_write_setselection(&ctx, "", buf, len); screen_write_stop(&ctx); -- 2.20.1