Add copy-mode-current-line-style to set style for current line in copy

mode, GitHub issue 5391 from Leo Henon.
This commit is contained in:
nicm
2026-07-21 11:52:13 +00:00
committed by tmux update bot
parent 0e2576a842
commit abd2f3a9a5
3 changed files with 63 additions and 10 deletions

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: options-table.c,v 1.239 2026/07/19 17:36:38 nicm Exp $ */ /* $OpenBSD: options-table.c,v 1.240 2026/07/21 11:52:13 nicm Exp $ */
/* /*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com> * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1431,6 +1431,15 @@ const struct options_table_entry options_table[] = {
.text = "Style of current line number in copy mode." .text = "Style of current line number in copy mode."
}, },
{ .name = "copy-mode-current-line-style",
.type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW,
.default_str = "default",
.flags = OPTIONS_TABLE_IS_STYLE,
.separator = ",",
.text = "Style of the line containing the cursor in copy mode."
},
{ .name = "copy-mode-line-number-style", { .name = "copy-mode-line-number-style",
.type = OPTIONS_TABLE_STRING, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW, .scope = OPTIONS_TABLE_WINDOW,

12
tmux.1
View File

@@ -1,4 +1,4 @@
.\" $OpenBSD: tmux.1,v 1.1144 2026/07/19 17:36:38 nicm Exp $ .\" $OpenBSD: tmux.1,v 1.1145 2026/07/21 11:52:13 nicm Exp $
.\" .\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\" .\"
@@ -14,7 +14,7 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" .\"
.Dd $Mdocdate: July 19 2026 $ .Dd $Mdocdate: July 21 2026 $
.Dt TMUX 1 .Dt TMUX 1
.Os .Os
.Sh NAME .Sh NAME
@@ -5771,6 +5771,14 @@ see the
.Sx STYLES .Sx STYLES
section. section.
.Pp .Pp
.It Ic copy\-mode\-current\-line\-style Ar style
Set the style of the line containing the cursor in copy mode.
For how to specify
.Ar style ,
see the
.Sx STYLES
section.
.Pp
.It Ic copy\-mode\-line\-number\-style Ar style .It Ic copy\-mode\-line\-number\-style Ar style
Set style of line numbers in copy mode. Set style of line numbers in copy mode.
For how to specify For how to specify

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: window-copy.c,v 1.422 2026/07/20 11:16:33 nicm Exp $ */ /* $OpenBSD: window-copy.c,v 1.423 2026/07/21 11:52:13 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -62,6 +62,7 @@ static void window_copy_set_line_numbers1(struct window_mode_entry *, int,
static int window_copy_line_number_mode(struct window_mode_entry *); static int window_copy_line_number_mode(struct window_mode_entry *);
static int window_copy_line_number_is_absolute(struct window_mode_entry *); static int window_copy_line_number_is_absolute(struct window_mode_entry *);
static int window_copy_line_numbers_active(struct window_mode_entry *); static int window_copy_line_numbers_active(struct window_mode_entry *);
static int window_copy_cursor_line_active(struct window_mode_entry *);
static u_int window_copy_line_number_width(struct window_mode_entry *); static u_int window_copy_line_number_width(struct window_mode_entry *);
static u_int window_copy_cursor_offset(struct window_mode_entry *, u_int, static u_int window_copy_cursor_offset(struct window_mode_entry *, u_int,
u_int); u_int);
@@ -5027,7 +5028,8 @@ window_copy_match_at_cursor(struct window_copy_mode_data *data)
static void static void
window_copy_update_style(struct window_mode_entry *wme, u_int fx, u_int fy, window_copy_update_style(struct window_mode_entry *wme, u_int fx, u_int fy,
struct grid_cell *gc, const struct grid_cell *mgc, struct grid_cell *gc, const struct grid_cell *mgc,
const struct grid_cell *cgc, const struct grid_cell *mkgc) const struct grid_cell *cgc, const struct grid_cell *mkgc,
const struct grid_cell *clgc)
{ {
struct window_pane *wp = wme->wp; struct window_pane *wp = wme->wp;
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
@@ -5035,6 +5037,15 @@ window_copy_update_style(struct window_mode_entry *wme, u_int fx, u_int fy,
int inv = 0, found = 0; int inv = 0, found = 0;
int keys; int keys;
cy = screen_hsize(data->backing) - data->oy + data->cy;
if (fy == cy) {
if (clgc->fg != 8)
gc->fg = clgc->fg;
if (clgc->bg != 8)
gc->bg = clgc->bg;
gc->attr |= clgc->attr;
}
if (data->showmark && fy == data->my) { if (data->showmark && fy == data->my) {
gc->attr = mkgc->attr; gc->attr = mkgc->attr;
if (fx == data->mx) if (fx == data->mx)
@@ -5058,7 +5069,6 @@ window_copy_update_style(struct window_mode_entry *wme, u_int fx, u_int fy,
if (mark == 0) if (mark == 0)
return; return;
cy = screen_hsize(data->backing) - data->oy + data->cy;
if (window_copy_search_mark_at(data, data->cx, cy, &cursor) == 0) { if (window_copy_search_mark_at(data, data->cx, cy, &cursor) == 0) {
keys = options_get_number(wp->window->options, "mode-keys"); keys = options_get_number(wp->window->options, "mode-keys");
if (cursor != 0 && if (cursor != 0 &&
@@ -5102,7 +5112,7 @@ static void
window_copy_write_one(struct window_mode_entry *wme, window_copy_write_one(struct window_mode_entry *wme,
struct screen_write_ctx *ctx, u_int px, u_int py, u_int fy, u_int nx, struct screen_write_ctx *ctx, u_int px, u_int py, u_int fy, u_int nx,
const struct grid_cell *mgc, const struct grid_cell *cgc, const struct grid_cell *mgc, const struct grid_cell *cgc,
const struct grid_cell *mkgc) const struct grid_cell *mkgc, const struct grid_cell *clgc)
{ {
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
struct grid *gd = data->backing->grid; struct grid *gd = data->backing->grid;
@@ -5114,7 +5124,7 @@ window_copy_write_one(struct window_mode_entry *wme,
grid_get_cell(gd, fx, fy, &gc); grid_get_cell(gd, fx, fy, &gc);
if (fx + gc.data.width <= nx) { if (fx + gc.data.width <= nx) {
window_copy_update_style(wme, fx, fy, &gc, mgc, cgc, window_copy_update_style(wme, fx, fy, &gc, mgc, cgc,
mkgc); mkgc, clgc);
if (gc.flags & GRID_FLAG_PADDING) { if (gc.flags & GRID_FLAG_PADDING) {
if (ctx->s->cy == py && ctx->s->cx <= px + fx) { if (ctx->s->cy == py && ctx->s->cx <= px + fx) {
gc.flags &= ~GRID_FLAG_PADDING; gc.flags &= ~GRID_FLAG_PADDING;
@@ -5172,6 +5182,16 @@ window_copy_line_numbers_active(struct window_mode_entry *wme)
WINDOW_COPY_LINE_NUMBERS_OFF); WINDOW_COPY_LINE_NUMBERS_OFF);
} }
static int
window_copy_cursor_line_active(struct window_mode_entry *wme)
{
struct options *oo = wme->wp->window->options;
const char *s;
s = options_get_string(oo, "copy-mode-current-line-style");
return (strcmp(s, "default") != 0);
}
static u_int static u_int
window_copy_line_number_width(struct window_mode_entry *wme) window_copy_line_number_width(struct window_mode_entry *wme)
{ {
@@ -5288,7 +5308,8 @@ window_copy_write_line(struct window_mode_entry *wme,
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
struct screen *s = &data->screen; struct screen *s = &data->screen;
struct options *oo = wp->window->options; struct options *oo = wp->window->options;
struct grid_cell gc, mgc, cgc, mkgc, ln_gc, cur_ln_gc; struct grid_cell gc, mgc, cgc, mkgc, clgc, ln_gc;
struct grid_cell cur_ln_gc;
u_int sx = screen_size_x(s); u_int sx = screen_size_x(s);
u_int hsize = screen_hsize(data->backing); u_int hsize = screen_hsize(data->backing);
u_int width; u_int width;
@@ -5318,6 +5339,8 @@ window_copy_write_line(struct window_mode_entry *wme,
cgc.flags |= GRID_FLAG_NOPALETTE; cgc.flags |= GRID_FLAG_NOPALETTE;
style_apply(&mkgc, oo, "copy-mode-mark-style", ft); style_apply(&mkgc, oo, "copy-mode-mark-style", ft);
mkgc.flags |= GRID_FLAG_NOPALETTE; mkgc.flags |= GRID_FLAG_NOPALETTE;
style_apply(&clgc, oo, "copy-mode-current-line-style", ft);
clgc.flags |= GRID_FLAG_NOPALETTE;
if (width != 0) { if (width != 0) {
style_apply(&ln_gc, oo, "copy-mode-line-number-style", ft); style_apply(&ln_gc, oo, "copy-mode-line-number-style", ft);
ln_gc.flags |= GRID_FLAG_NOPALETTE; ln_gc.flags |= GRID_FLAG_NOPALETTE;
@@ -5346,7 +5369,7 @@ window_copy_write_line(struct window_mode_entry *wme,
} }
window_copy_write_one(wme, ctx, width, py, hsize - data->oy + py, window_copy_write_one(wme, ctx, width, py, hsize - data->oy + py,
content_sx, &mgc, &cgc, &mkgc); content_sx, &mgc, &cgc, &mkgc, &clgc);
if (py == 0 && s->rupper < s->rlower && !data->hide_position) { if (py == 0 && s->rupper < s->rlower && !data->hide_position) {
value = options_get_string(oo, "copy-mode-position-format"); value = options_get_string(oo, "copy-mode-position-format");
@@ -5598,6 +5621,11 @@ window_copy_update_cursor(struct window_mode_entry *wme, u_int cx, u_int cy)
screen_write_stop(&ctx); screen_write_stop(&ctx);
return; return;
} }
if (old_cy != data->cy && window_copy_cursor_line_active(wme)) {
window_copy_redraw_lines(wme, old_cy, 1);
window_copy_redraw_lines(wme, data->cy, 1);
return;
}
if (old_cx == screen_size_x(s)) if (old_cx == screen_size_x(s))
window_copy_redraw_lines(wme, old_cy, 1); window_copy_redraw_lines(wme, old_cy, 1);
if (data->cx == screen_size_x(s)) if (data->cx == screen_size_x(s))
@@ -6799,6 +6827,10 @@ window_copy_scroll_up(struct window_mode_entry *wme, u_int ny)
if (data->searchmark != NULL && !data->timeout) if (data->searchmark != NULL && !data->timeout)
window_copy_search_marks(wme, NULL, data->searchregex, 1); window_copy_search_marks(wme, NULL, data->searchregex, 1);
window_copy_update_selection_view(wme, 0, 0); window_copy_update_selection_view(wme, 0, 0);
if (window_copy_cursor_line_active(wme)) {
window_copy_redraw_screen(wme);
return;
}
if (window_copy_line_numbers_active(wme)) { if (window_copy_line_numbers_active(wme)) {
if (window_copy_line_number_mode(wme) != if (window_copy_line_number_mode(wme) !=
WINDOW_COPY_LINE_NUMBERS_ABSOLUTE) { WINDOW_COPY_LINE_NUMBERS_ABSOLUTE) {
@@ -6866,6 +6898,10 @@ window_copy_scroll_down(struct window_mode_entry *wme, u_int ny)
if (data->searchmark != NULL && !data->timeout) if (data->searchmark != NULL && !data->timeout)
window_copy_search_marks(wme, NULL, data->searchregex, 1); window_copy_search_marks(wme, NULL, data->searchregex, 1);
window_copy_update_selection_view(wme, 0, 0); window_copy_update_selection_view(wme, 0, 0);
if (window_copy_cursor_line_active(wme)) {
window_copy_redraw_screen(wme);
return;
}
if (window_copy_line_numbers_active(wme)) { if (window_copy_line_numbers_active(wme)) {
if (window_copy_line_number_mode(wme) != if (window_copy_line_number_mode(wme) !=
WINDOW_COPY_LINE_NUMBERS_ABSOLUTE) { WINDOW_COPY_LINE_NUMBERS_ABSOLUTE) {