Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam 2023-08-08 12:01:10 +01:00
commit 4c60afde78
11 changed files with 218 additions and 68 deletions

View File

@ -38,10 +38,11 @@ const struct cmd_entry cmd_display_menu_entry = {
.name = "display-menu", .name = "display-menu",
.alias = "menu", .alias = "menu",
.args = { "c:t:S:OT:x:y:", 1, -1, cmd_display_menu_args_parse }, .args = { "b:c:C:t:s:S:OT:x:y:", 1, -1, cmd_display_menu_args_parse },
.usage = "[-O] [-c target-client] [-S starting-choice] " .usage = "[-O] [-b border-lines] [-c target-client] "
CMD_TARGET_PANE_USAGE " [-T title] [-x position] " "[-C starting-choice] [-s style] [-S border-style] "
"[-y position] name key command ...", CMD_TARGET_PANE_USAGE "[-T title] [-x position] [-y position] "
"name key command ...",
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },
@ -288,19 +289,25 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
struct client *tc = cmdq_get_target_client(item); struct client *tc = cmdq_get_target_client(item);
struct menu *menu = NULL; struct menu *menu = NULL;
struct menu_item menu_item; struct menu_item menu_item;
const char *key, *name; const char *key, *name, *value;
const char *style = args_get(args, 's');
const char *border_style = args_get(args, 'S');
enum box_lines lines = BOX_LINES_DEFAULT;
char *title, *cause; char *title, *cause;
int flags = 0, starting_choice = 0; int flags = 0, starting_choice = 0;
u_int px, py, i, count = args_count(args); u_int px, py, i, count = args_count(args);
struct options *o = target->s->curw->window->options;
struct options_entry *oe;
if (tc->overlay_draw != NULL) if (tc->overlay_draw != NULL)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
if (args_has(args, 'S')) { if (args_has(args, 'C')) {
if (strcmp(args_get(args, 'S'), "-") == 0) if (strcmp(args_get(args, 'C'), "-") == 0)
starting_choice = -1; starting_choice = -1;
else { else {
starting_choice = args_strtonum(args, 'S', 0, UINT_MAX, starting_choice = args_strtonum(args, 'C', 0, UINT_MAX,
&cause); &cause);
if (cause != NULL) { if (cause != NULL) {
cmdq_error(item, "starting choice %s", cause); cmdq_error(item, "starting choice %s", cause);
@ -351,12 +358,24 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
value = args_get(args, 'b');
if (value != NULL) {
oe = options_get(o, "menu-border-lines");
lines = options_find_choice(options_table_entry(oe), value,
&cause);
if (lines == -1) {
cmdq_error(item, "menu-border-lines %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
}
if (args_has(args, 'O')) if (args_has(args, 'O'))
flags |= MENU_STAYOPEN; flags |= MENU_STAYOPEN;
if (!event->m.valid) if (!event->m.valid)
flags |= MENU_NOMOUSE; flags |= MENU_NOMOUSE;
if (menu_display(menu, flags, starting_choice, item, px, py, tc, target, if (menu_display(menu, flags, starting_choice, item, px, py, tc, lines,
NULL, NULL) != 0) style, border_style, target, NULL, NULL) != 0)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
return (CMD_RETURN_WAIT); return (CMD_RETURN_WAIT);
} }

View File

@ -2756,6 +2756,9 @@ input_osc_133(struct input_ctx *ictx, const char *p)
case 'A': case 'A':
gl->flags |= GRID_LINE_START_PROMPT; gl->flags |= GRID_LINE_START_PROMPT;
break; break;
case 'C':
gl->flags |= GRID_LINE_START_OUTPUT;
break;
} }
} }

51
menu.c
View File

@ -27,6 +27,10 @@ struct menu_data {
struct cmdq_item *item; struct cmdq_item *item;
int flags; int flags;
struct grid_cell style;
struct grid_cell border_style;
enum box_lines border_lines;
struct cmd_find_state fs; struct cmd_find_state fs;
struct screen s; struct screen s;
@ -199,12 +203,17 @@ menu_draw_cb(struct client *c, void *data,
u_int i, px = md->px, py = md->py; u_int i, px = md->px, py = md->py;
struct grid_cell gc; struct grid_cell gc;
style_apply(&gc, c->session->curw->window->options, "mode-style", NULL);
screen_write_start(&ctx, s); screen_write_start(&ctx, s);
screen_write_clearscreen(&ctx, 8); screen_write_clearscreen(&ctx, 8);
screen_write_menu(&ctx, menu, md->choice, BOX_LINES_DEFAULT,
&grid_default_cell, &grid_default_cell, &gc); if (md->border_lines != BOX_LINES_NONE) {
screen_write_box(&ctx, menu->width + 4, menu->count + 2,
md->border_lines, &md->border_style, menu->title);
}
style_apply(&gc, c->session->curw->window->options, "mode-style", NULL);
screen_write_menu(&ctx, menu, md->choice, md->border_lines,
&md->style, &md->border_style, &gc);
screen_write_stop(&ctx); screen_write_stop(&ctx);
for (i = 0; i < screen_size_y(&md->s); i++) { for (i = 0; i < screen_size_y(&md->s); i++) {
@ -432,11 +441,14 @@ chosen:
struct menu_data * struct menu_data *
menu_prepare(struct menu *menu, int flags, int starting_choice, menu_prepare(struct menu *menu, int flags, int starting_choice,
struct cmdq_item *item, u_int px, u_int py, struct client *c, struct cmdq_item *item, u_int px, u_int py, struct client *c,
enum box_lines lines, const char *style, const char *border_style,
struct cmd_find_state *fs, menu_choice_cb cb, void *data) struct cmd_find_state *fs, menu_choice_cb cb, void *data)
{ {
struct menu_data *md; struct menu_data *md;
int choice; int choice;
const char *name; const char *name;
struct style sytmp;
struct options *o = c->session->curw->window->options;
if (c->tty.sx < menu->width + 4 || c->tty.sy < menu->count + 2) if (c->tty.sx < menu->width + 4 || c->tty.sy < menu->count + 2)
return (NULL); return (NULL);
@ -445,9 +457,35 @@ menu_prepare(struct menu *menu, int flags, int starting_choice,
if (py + menu->count + 2 > c->tty.sy) if (py + menu->count + 2 > c->tty.sy)
py = c->tty.sy - menu->count - 2; py = c->tty.sy - menu->count - 2;
if (lines == BOX_LINES_DEFAULT)
lines = options_get_number(o, "menu-border-lines");
md = xcalloc(1, sizeof *md); md = xcalloc(1, sizeof *md);
md->item = item; md->item = item;
md->flags = flags; md->flags = flags;
md->border_lines = lines;
memcpy(&md->style, &grid_default_cell, sizeof md->style);
style_apply(&md->style, o, "menu-style", NULL);
if (style != NULL) {
style_set(&sytmp, &grid_default_cell);
if (style_parse(&sytmp, &md->style, style) == 0) {
md->style.fg = sytmp.gc.fg;
md->style.bg = sytmp.gc.bg;
}
}
md->style.attr = 0;
memcpy(&md->border_style, &grid_default_cell, sizeof md->border_style);
style_apply(&md->border_style, o, "menu-border-style", NULL);
if (border_style != NULL) {
style_set(&sytmp, &grid_default_cell);
if (style_parse(&sytmp, &md->border_style, border_style) == 0) {
md->border_style.fg = sytmp.gc.fg;
md->border_style.bg = sytmp.gc.bg;
}
}
md->border_style.attr = 0;
if (fs != NULL) if (fs != NULL)
cmd_find_copy_state(&md->fs, fs); cmd_find_copy_state(&md->fs, fs);
@ -501,12 +539,13 @@ menu_prepare(struct menu *menu, int flags, int starting_choice,
int int
menu_display(struct menu *menu, int flags, int starting_choice, menu_display(struct menu *menu, int flags, int starting_choice,
struct cmdq_item *item, u_int px, u_int py, struct client *c, struct cmdq_item *item, u_int px, u_int py, struct client *c,
enum box_lines lines, const char *style, const char *border_style,
struct cmd_find_state *fs, menu_choice_cb cb, void *data) struct cmd_find_state *fs, menu_choice_cb cb, void *data)
{ {
struct menu_data *md; struct menu_data *md;
md = menu_prepare(menu, flags, starting_choice, item, px, py, c, fs, cb, md = menu_prepare(menu, flags, starting_choice, item, px, py, c, lines,
data); style, border_style, fs, cb, data);
if (md == NULL) if (md == NULL)
return (-1); return (-1);
server_client_set_overlay(c, 0, NULL, menu_mode_cb, menu_draw_cb, server_client_set_overlay(c, 0, NULL, menu_mode_cb, menu_draw_cb,

View File

@ -962,8 +962,8 @@ mode_tree_display_menu(struct mode_tree_data *mtd, struct client *c, u_int x,
x -= (menu->width + 4) / 2; x -= (menu->width + 4) / 2;
else else
x = 0; x = 0;
if (menu_display(menu, 0, 0, NULL, x, y, c, NULL, if (menu_display(menu, 0, 0, NULL, x, y, c, BOX_LINES_DEFAULT, NULL,
mode_tree_menu_callback, mtm) != 0) NULL, NULL, mode_tree_menu_callback, mtm) != 0)
menu_free(menu); menu_free(menu);
} }

View File

@ -326,6 +326,33 @@ const struct options_table_entry options_table[] = {
"Empty does not write a history file." "Empty does not write a history file."
}, },
{ .name = "menu-style",
.type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW,
.flags = OPTIONS_TABLE_IS_STYLE,
.default_str = "default",
.separator = ",",
.text = "Default style of menu."
},
{ .name = "menu-border-style",
.type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW,
.default_str = "default",
.flags = OPTIONS_TABLE_IS_STYLE,
.separator = ",",
.text = "Default style of menu borders."
},
{ .name = "menu-border-lines",
.type = OPTIONS_TABLE_CHOICE,
.scope = OPTIONS_TABLE_WINDOW,
.choices = options_table_popup_border_lines_list,
.default_num = BOX_LINES_SINGLE,
.text = "Type of characters used to draw menu border lines. Some of "
"these are only supported on terminals with UTF-8 support."
},
{ .name = "message-limit", { .name = "message-limit",
.type = OPTIONS_TABLE_NUMBER, .type = OPTIONS_TABLE_NUMBER,
.scope = OPTIONS_TABLE_SERVER, .scope = OPTIONS_TABLE_SERVER,

View File

@ -574,8 +574,8 @@ menu:
x = m->x - (pd->menu->width + 4) / 2; x = m->x - (pd->menu->width + 4) / 2;
else else
x = 0; x = 0;
pd->md = menu_prepare(pd->menu, 0, 0, NULL, x, m->y, c, NULL, pd->md = menu_prepare(pd->menu, 0, 0, NULL, x, m->y, c,
popup_menu_done, pd); BOX_LINES_DEFAULT, NULL, NULL, NULL, popup_menu_done, pd);
c->flags |= CLIENT_REDRAWOVERLAY; c->flags |= CLIENT_REDRAWOVERLAY;
out: out:

View File

@ -713,15 +713,16 @@ screen_write_menu(struct screen_write_ctx *ctx, struct menu *menu, int choice,
name = menu->items[i].name; name = menu->items[i].name;
if (name == NULL) { if (name == NULL) {
screen_write_cursormove(ctx, cx, cy + 1 + i, 0); screen_write_cursormove(ctx, cx, cy + 1 + i, 0);
screen_write_hline(ctx, width + 4, 1, 1, lines, gc); screen_write_hline(ctx, width + 4, 1, 1, lines,
border_gc);
continue; continue;
} }
if (choice >= 0 && i == (u_int)choice && *name != '-') if (choice >= 0 && i == (u_int)choice && *name != '-')
gc = choice_gc; gc = choice_gc;
screen_write_cursormove(ctx, cx + 2, cy + 1 + i, 0); screen_write_cursormove(ctx, cx + 1, cy + 1 + i, 0);
for (j = 0; j < width; j++) for (j = 0; j < width + 2; j++)
screen_write_putc(ctx, gc, ' '); screen_write_putc(ctx, gc, ' ');
screen_write_cursormove(ctx, cx + 2, cy + 1 + i, 0); screen_write_cursormove(ctx, cx + 2, cy + 1 + i, 0);

View File

@ -1764,8 +1764,9 @@ status_prompt_complete_list_menu(struct client *c, char **list, u_int size,
else else
offset = 0; offset = 0;
if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset, if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset, py, c,
py, c, NULL, status_prompt_menu_callback, spm) != 0) { BOX_LINES_DEFAULT, NULL, NULL, NULL, status_prompt_menu_callback,
spm) != 0) {
menu_free(menu); menu_free(menu);
free(spm); free(spm);
return (0); return (0);
@ -1857,8 +1858,9 @@ status_prompt_complete_window_menu(struct client *c, struct session *s,
else else
offset = 0; offset = 0;
if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset, if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset, py, c,
py, c, NULL, status_prompt_menu_callback, spm) != 0) { BOX_LINES_DEFAULT, NULL, NULL, NULL, status_prompt_menu_callback,
spm) != 0) {
menu_free(menu); menu_free(menu);
free(spm); free(spm);
return (NULL); return (NULL);

107
tmux.1
View File

@ -1785,29 +1785,35 @@ Exit copy mode.
.Xc .Xc
Clear the current selection. Clear the current selection.
.It Xo .It Xo
.Ic copy-end-of-line [<prefix>] .Ic copy-end-of-line
.Op Ar prefix
.Xc .Xc
Copy from the cursor position to the end of the line. Copy from the cursor position to the end of the line.
.Ar prefix .Ar prefix
is used to name the new paste buffer. is used to name the new paste buffer.
.It Xo .It Xo
.Ic copy-end-of-line-and-cancel [<prefix>] .Ic copy-end-of-line-and-cancel
.Op Ar prefix
.Xc .Xc
Copy from the cursor position and exit copy mode. Copy from the cursor position and exit copy mode.
.It Xo .It Xo
.Ic copy-line [<prefix>] .Ic copy-line
.Op Ar prefix
.Xc .Xc
Copy the entire line. Copy the entire line.
.It Xo .It Xo
.Ic copy-line-and-cancel [<prefix>] .Ic copy-line-and-cancel
.Op Ar prefix
.Xc .Xc
Copy the entire line and exit copy mode. Copy the entire line and exit copy mode.
.It Xo .It Xo
.Ic copy-selection [<prefix>] .Ic copy-selection
.Op Ar prefix
.Xc .Xc
Copies the current selection. Copies the current selection.
.It Xo .It Xo
.Ic copy-selection-and-cancel [<prefix>] .Ic copy-selection-and-cancel
.Op Ar prefix
(vi: Enter) (vi: Enter)
(emacs: M-w) (emacs: M-w)
.Xc .Xc
@ -1843,7 +1849,8 @@ Move the cursor up.
.Xc .Xc
Move the cursor to the end of the line. Move the cursor to the end of the line.
.It Xo .It Xo
.Ic goto-line <line> .Ic goto-line
.Ar line
(vi: :) (vi: :)
(emacs: g) (emacs: g)
.Xc .Xc
@ -1867,13 +1874,15 @@ Scroll to the top of the history.
.Xc .Xc
Repeat the last jump. Repeat the last jump.
.It Xo .It Xo
.Ic jump-backward <to> .Ic jump-backward
.Ar to
(vi: F) (vi: F)
(emacs: F) (emacs: F)
.Xc .Xc
Jump backwards to the specified text. Jump backwards to the specified text.
.It Xo .It Xo
.Ic jump-forward <to> .Ic jump-forward
.Ar to
(vi: f) (vi: f)
(emacs: f) (emacs: f)
.Xc .Xc
@ -1904,6 +1913,7 @@ Move to the next matching bracket.
Move to the next paragraph. Move to the next paragraph.
.It Xo .It Xo
.Ic next-prompt .Ic next-prompt
.Op Fl o
.Xc .Xc
Move to the next prompt. Move to the next prompt.
.It Xo .It Xo
@ -1936,6 +1946,7 @@ Move to the previous matching bracket.
Move to the previous paragraph. Move to the previous paragraph.
.It Xo .It Xo
.Ic previous-prompt .Ic previous-prompt
.Op Fl o
.Xc .Xc
Move to the previous prompt. Move to the previous prompt.
.It Xo .It Xo
@ -1963,12 +1974,14 @@ Refresh the content from the pane.
.Xc .Xc
Repeat the last search. Repeat the last search.
.It Xo .It Xo
.Ic search-backward <for> .Ic search-backward
.Ar text
(vi: ?) (vi: ?)
.Xc .Xc
Search backwards for the specified text. Search backwards for the specified text.
.It Xo .It Xo
.Ic search-forward <for> .Ic search-forward
.Ar text
(vi: /) (vi: /)
.Xc .Xc
Search forward for the specified text. Search forward for the specified text.
@ -2036,6 +2049,9 @@ move between shell prompts, but require the shell to emit an escape sequence
.Nm .Nm
where the prompts are located; if the shell does not do this, these commands where the prompts are located; if the shell does not do this, these commands
will do nothing. will do nothing.
The
.Fl o
flag jumps to the beginning of the command output instead of the shell prompt.
.Pp .Pp
Copy commands may take an optional buffer prefix argument which is used Copy commands may take an optional buffer prefix argument which is used
to generate the buffer name (the default is to generate the buffer name (the default is
@ -4076,6 +4092,26 @@ The default is to run
.Xr lock 1 .Xr lock 1
with with
.Fl np . .Fl np .
.It Ic menu-style Ar style
Set the menu style.
See the
.Sx STYLES
section on how to specify
.Ar style .
Attributes are ignored.
.It Ic menu-border-style Ar style
Set the menu border style.
See the
.Sx STYLES
section on how to specify
.Ar style .
Attributes are ignored.
.It Ic menu-border-lines Ar type
Set the type of characters used for drawing menu borders.
See
.Ic popup-border-lines
for possible values for
.Ar type .
.It Ic message-command-style Ar style .It Ic message-command-style Ar style
Set status line message command style. Set status line message command style.
This is used for the command prompt with This is used for the command prompt with
@ -4543,20 +4579,18 @@ Attributes are ignored.
.Pp .Pp
.It Ic popup-style Ar style .It Ic popup-style Ar style
Set the popup style. Set the popup style.
For how to specify See the
.Ar style ,
see the
.Sx STYLES .Sx STYLES
section. section on how to specify
.Ar style .
Attributes are ignored. Attributes are ignored.
.Pp .Pp
.It Ic popup-border-style Ar style .It Ic popup-border-style Ar style
Set the popup border style. Set the popup border style.
For how to specify See the
.Ar style ,
see the
.Sx STYLES .Sx STYLES
section. section on how to specify
.Ar style .
Attributes are ignored. Attributes are ignored.
.Pp .Pp
.It Ic popup-border-lines Ar type .It Ic popup-border-lines Ar type
@ -6031,9 +6065,12 @@ the default is
.Tg menu .Tg menu
.It Xo Ic display-menu .It Xo Ic display-menu
.Op Fl O .Op Fl O
.Op Fl b Ar border-lines
.Op Fl c Ar target-client .Op Fl c Ar target-client
.Op Fl s Ar style
.Op Fl S Ar border-style
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
.Op Fl S Ar starting-choice .Op Fl C Ar starting-choice
.Op Fl T Ar title .Op Fl T Ar title
.Op Fl x Ar position .Op Fl x Ar position
.Op Fl y Ar position .Op Fl y Ar position
@ -6060,10 +6097,24 @@ may not be chosen.
The name may be empty for a separator line, in which case both the key and The name may be empty for a separator line, in which case both the key and
command should be omitted. command should be omitted.
.Pp .Pp
.Fl b
sets the type of characters used for drawing menu borders.
See
.Ic popup-border-lines
for possible values for
.Ar border-lines .
.Pp
.Fl s
sets the style for the menu and
.Fl S
sets the style for the menu border (see
.Sx STYLES ) .
.Pp
.Fl T .Fl T
is a format for the menu title (see is a format for the menu title (see
.Sx FORMATS ) . .Sx FORMATS ) .
.Fl S .Pp
.Fl C
sets the menu item selected by default, if the menu is not bound to a mouse key sets the menu item selected by default, if the menu is not bound to a mouse key
binding. binding.
.Pp .Pp
@ -6178,8 +6229,8 @@ forwards any input read from stdin to the empty pane given by
.Op Fl d Ar start-directory .Op Fl d Ar start-directory
.Op Fl e Ar environment .Op Fl e Ar environment
.Op Fl h Ar height .Op Fl h Ar height
.Op Fl s Ar style .Op Fl s Ar border-style
.Op Fl S Ar border-style .Op Fl S Ar style
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
.Op Fl T Ar title .Op Fl T Ar title
.Op Fl w Ar width .Op Fl w Ar width
@ -6222,7 +6273,7 @@ If omitted, half of the terminal size is used.
does not surround the popup by a border. does not surround the popup by a border.
.Pp .Pp
.Fl b .Fl b
sets the type of border line for the popup. sets the type of characters used for drawing popup borders.
When When
.Fl B .Fl B
is specified, the is specified, the
@ -6236,12 +6287,8 @@ for possible values for
.Fl s .Fl s
sets the style for the popup and sets the style for the popup and
.Fl S .Fl S
sets the style for the popup border. sets the style for the popup border (see
For how to specify .Sx STYLES ) .
.Ar style ,
see the
.Sx STYLES
section.
.Pp .Pp
.Fl e .Fl e
takes the form takes the form

11
tmux.h
View File

@ -676,6 +676,7 @@ struct colour_palette {
#define GRID_LINE_EXTENDED 0x2 #define GRID_LINE_EXTENDED 0x2
#define GRID_LINE_DEAD 0x4 #define GRID_LINE_DEAD 0x4
#define GRID_LINE_START_PROMPT 0x8 #define GRID_LINE_START_PROMPT 0x8
#define GRID_LINE_START_OUTPUT 0x10
/* Grid string flags. */ /* Grid string flags. */
#define GRID_STRING_WITH_SEQUENCES 0x1 #define GRID_STRING_WITH_SEQUENCES 0x1
@ -3312,11 +3313,13 @@ void menu_add_item(struct menu *, const struct menu_item *,
struct cmd_find_state *); struct cmd_find_state *);
void menu_free(struct menu *); void menu_free(struct menu *);
struct menu_data *menu_prepare(struct menu *, int, int, struct cmdq_item *, struct menu_data *menu_prepare(struct menu *, int, int, struct cmdq_item *,
u_int, u_int, struct client *, struct cmd_find_state *, u_int, u_int, struct client *, enum box_lines, const char *,
menu_choice_cb, void *); const char *, struct cmd_find_state *, menu_choice_cb,
void *);
int menu_display(struct menu *, int, int, struct cmdq_item *, int menu_display(struct menu *, int, int, struct cmdq_item *,
u_int, u_int, struct client *, struct cmd_find_state *, u_int, u_int, struct client *, enum box_lines, const char *,
menu_choice_cb, void *); const char *, struct cmd_find_state *, menu_choice_cb,
void *);
struct screen *menu_mode_cb(struct client *, void *, u_int *, u_int *); struct screen *menu_mode_cb(struct client *, void *, u_int *, u_int *);
void menu_check_cb(struct client *, void *, u_int, u_int, u_int, void menu_check_cb(struct client *, void *, u_int, u_int, u_int,
struct overlay_ranges *); struct overlay_ranges *);

View File

@ -131,7 +131,8 @@ static void window_copy_cursor_previous_word_pos(struct window_mode_entry *,
const char *, u_int *, u_int *); const char *, u_int *, u_int *);
static void window_copy_cursor_previous_word(struct window_mode_entry *, static void window_copy_cursor_previous_word(struct window_mode_entry *,
const char *, int); const char *, int);
static void window_copy_cursor_prompt(struct window_mode_entry *, int); static void window_copy_cursor_prompt(struct window_mode_entry *, int,
const char *);
static void window_copy_scroll_up(struct window_mode_entry *, u_int); static void window_copy_scroll_up(struct window_mode_entry *, u_int);
static void window_copy_scroll_down(struct window_mode_entry *, u_int); static void window_copy_scroll_down(struct window_mode_entry *, u_int);
static void window_copy_rectangle_set(struct window_mode_entry *, int); static void window_copy_rectangle_set(struct window_mode_entry *, int);
@ -2245,8 +2246,9 @@ static enum window_copy_cmd_action
window_copy_cmd_next_prompt(struct window_copy_cmd_state *cs) window_copy_cmd_next_prompt(struct window_copy_cmd_state *cs)
{ {
struct window_mode_entry *wme = cs->wme; struct window_mode_entry *wme = cs->wme;
const char *arg1 = args_string(cs->args, 1);
window_copy_cursor_prompt(wme, 1); window_copy_cursor_prompt(wme, 1, arg1);
return (WINDOW_COPY_CMD_NOTHING); return (WINDOW_COPY_CMD_NOTHING);
} }
@ -2254,8 +2256,9 @@ static enum window_copy_cmd_action
window_copy_cmd_previous_prompt(struct window_copy_cmd_state *cs) window_copy_cmd_previous_prompt(struct window_copy_cmd_state *cs)
{ {
struct window_mode_entry *wme = cs->wme; struct window_mode_entry *wme = cs->wme;
const char *arg1 = args_string(cs->args, 1);
window_copy_cursor_prompt(wme, 0); window_copy_cursor_prompt(wme, 0, arg1);
return (WINDOW_COPY_CMD_NOTHING); return (WINDOW_COPY_CMD_NOTHING);
} }
@ -2721,7 +2724,7 @@ static const struct {
}, },
{ .command = "previous-prompt", { .command = "previous-prompt",
.minargs = 0, .minargs = 0,
.maxargs = 0, .maxargs = 1,
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
.f = window_copy_cmd_previous_prompt .f = window_copy_cmd_previous_prompt
}, },
@ -5389,14 +5392,20 @@ window_copy_cursor_previous_word(struct window_mode_entry *wme,
} }
static void static void
window_copy_cursor_prompt(struct window_mode_entry *wme, int direction) window_copy_cursor_prompt(struct window_mode_entry *wme, int direction,
const char *args)
{ {
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
struct screen *s = data->backing; struct screen *s = data->backing;
struct grid *gd = s->grid; struct grid *gd = s->grid;
u_int end_line; u_int end_line;
u_int line = gd->hsize - data->oy + data->cy; u_int line = gd->hsize - data->oy + data->cy;
int add; int add, line_flag;
if (args != NULL && strcmp(args, "-o") == 0)
line_flag = GRID_LINE_START_OUTPUT;
else
line_flag = GRID_LINE_START_PROMPT;
if (direction == 0) { /* up */ if (direction == 0) { /* up */
add = -1; add = -1;
@ -5413,7 +5422,7 @@ window_copy_cursor_prompt(struct window_mode_entry *wme, int direction)
return; return;
line += add; line += add;
if (grid_get_line(gd, line)->flags & GRID_LINE_START_PROMPT) if (grid_get_line(gd, line)->flags & line_flag)
break; break;
} }