Merge branch 'obsd-master'

pull/2151/head
Thomas Adam 2020-03-31 20:01:34 +01:00
commit dfd29977e0
16 changed files with 246 additions and 81 deletions

View File

@ -81,7 +81,7 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
add = args_first_value(args, 'e', &value);
while (add != NULL) {
environ_put(sc.environ, add);
environ_put(sc.environ, add, 0);
add = args_next_value(&value);
}

View File

@ -99,6 +99,7 @@ static void cmd_parse_print_commands(struct cmd_parse_input *, u_int,
}
%token ERROR
%token HIDDEN
%token IF
%token ELSE
%token ELIF
@ -134,6 +135,11 @@ statements : statement '\n'
}
statement : /* empty */
{
$$ = xmalloc (sizeof *$$);
TAILQ_INIT($$);
}
| hidden_assignment
{
$$ = xmalloc (sizeof *$$);
TAILQ_INIT($$);
@ -204,10 +210,21 @@ assignment : EQUALS
if ((~flags & CMD_PARSE_PARSEONLY) &&
(ps->scope == NULL || ps->scope->flag))
environ_put(global_environ, $1);
environ_put(global_environ, $1, 0);
free($1);
}
hidden_assignment : HIDDEN EQUALS
{
struct cmd_parse_state *ps = &parse_state;
int flags = ps->input->flags;
if ((~flags & CMD_PARSE_PARSEONLY) &&
(ps->scope == NULL || ps->scope->flag))
environ_put(global_environ, $2, ENVIRON_HIDDEN);
free($2);
}
if_open : IF expanded
{
struct cmd_parse_state *ps = &parse_state;
@ -1079,6 +1096,10 @@ yylex(void)
if (*cp == '\0')
return (TOKEN);
ps->condition = 1;
if (strcmp(yylval.token, "%hidden") == 0) {
free(yylval.token);
return (HIDDEN);
}
if (strcmp(yylval.token, "%if") == 0) {
free(yylval.token);
return (IF);

View File

@ -36,8 +36,8 @@ const struct cmd_entry cmd_resize_pane_entry = {
.name = "resize-pane",
.alias = "resizep",
.args = { "DLMRt:Ux:y:Z", 0, 1 },
.usage = "[-DLMRUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE " "
.args = { "DLMRTt:Ux:y:Z", 0, 1 },
.usage = "[-DLMRTUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE " "
"[adjustment]",
.target = { 't', CMD_FIND_PANE, 0 },
@ -60,6 +60,19 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
char *cause;
u_int adjust;
int x, y;
struct grid *gd = wp->base.grid;
if (args_has(args, 'T')) {
if (!TAILQ_EMPTY(&wp->modes))
return (CMD_RETURN_NORMAL);
adjust = screen_size_y(&wp->base) - 1 - wp->base.cy;
if (adjust > gd->hsize)
adjust = gd->hsize;
grid_remove_history(gd, adjust);
wp->base.cy += adjust;
wp->flags |= PANE_REDRAW;
return (CMD_RETURN_NORMAL);
}
if (args_has(args, 'M')) {
if (cmd_mouse_window(&shared->mouse, &s) == NULL)

View File

@ -71,7 +71,7 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmdq_item *item)
add = args_first_value(args, 'e', &value);
while (add != NULL) {
environ_put(sc.environ, add);
environ_put(sc.environ, add, 0);
add = args_next_value(&value);
}

View File

@ -68,7 +68,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmdq_item *item)
add = args_first_value(args, 'e', &value);
while (add != NULL) {
environ_put(sc.environ, add);
environ_put(sc.environ, add, 0);
add = args_next_value(&value);
}

View File

@ -34,8 +34,8 @@ const struct cmd_entry cmd_set_environment_entry = {
.name = "set-environment",
.alias = "setenv",
.args = { "grt:u", 1, 2 },
.usage = "[-gru] " CMD_TARGET_SESSION_USAGE " name [value]",
.args = { "hgrt:u", 1, 2 },
.usage = "[-hgru] " CMD_TARGET_SESSION_USAGE " name [value]",
.target = { 't', CMD_FIND_SESSION, CMD_FIND_CANFAIL },
@ -96,7 +96,10 @@ cmd_set_environment_exec(struct cmd *self, struct cmdq_item *item)
cmdq_error(item, "no value specified");
return (CMD_RETURN_ERROR);
}
environ_set(env, name, "%s", value);
if (args_has(args, 'h'))
environ_set(env, name, ENVIRON_HIDDEN, "%s", value);
else
environ_set(env, name, 0, "%s", value);
}
return (CMD_RETURN_NORMAL);

View File

@ -38,8 +38,8 @@ const struct cmd_entry cmd_show_environment_entry = {
.name = "show-environment",
.alias = "showenv",
.args = { "gst:", 0, 1 },
.usage = "[-gs] " CMD_TARGET_SESSION_USAGE " [name]",
.args = { "hgst:", 0, 1 },
.usage = "[-hgs] " CMD_TARGET_SESSION_USAGE " [name]",
.target = { 't', CMD_FIND_SESSION, CMD_FIND_CANFAIL },
@ -69,7 +69,13 @@ static void
cmd_show_environment_print(struct cmd *self, struct cmdq_item *item,
struct environ_entry *envent)
{
char *escaped;
struct args *args = self->args;
char *escaped;
if (!args_has(args, 'h') && (envent->flags & ENVIRON_HIDDEN))
return;
if (args_has(args, 'h') && (~envent->flags & ENVIRON_HIDDEN))
return;
if (!args_has(self->args, 's')) {
if (envent->value != NULL)

View File

@ -141,7 +141,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
add = args_first_value(args, 'e', &value);
while (add != NULL) {
environ_put(sc.environ, add);
environ_put(sc.environ, add, 0);
add = args_next_value(&value);
}

View File

@ -86,8 +86,10 @@ environ_copy(struct environ *srcenv, struct environ *dstenv)
RB_FOREACH(envent, environ, srcenv) {
if (envent->value == NULL)
environ_clear(dstenv, envent->name);
else
environ_set(dstenv, envent->name, "%s", envent->value);
else {
environ_set(dstenv, envent->name, envent->flags,
"%s", envent->value);
}
}
}
@ -103,18 +105,21 @@ environ_find(struct environ *env, const char *name)
/* Set an environment variable. */
void
environ_set(struct environ *env, const char *name, const char *fmt, ...)
environ_set(struct environ *env, const char *name, int flags, const char *fmt,
...)
{
struct environ_entry *envent;
va_list ap;
va_start(ap, fmt);
if ((envent = environ_find(env, name)) != NULL) {
envent->flags = flags;
free(envent->value);
xvasprintf(&envent->value, fmt, ap);
} else {
envent = xmalloc(sizeof *envent);
envent->name = xstrdup(name);
envent->flags = flags;
xvasprintf(&envent->value, fmt, ap);
RB_INSERT(environ, env, envent);
}
@ -133,6 +138,7 @@ environ_clear(struct environ *env, const char *name)
} else {
envent = xmalloc(sizeof *envent);
envent->name = xstrdup(name);
envent->flags = 0;
envent->value = NULL;
RB_INSERT(environ, env, envent);
}
@ -140,7 +146,7 @@ environ_clear(struct environ *env, const char *name)
/* Set an environment variable from a NAME=VALUE string. */
void
environ_put(struct environ *env, const char *var)
environ_put(struct environ *env, const char *var, int flags)
{
char *name, *value;
@ -152,7 +158,7 @@ environ_put(struct environ *env, const char *var)
name = xstrdup(var);
name[strcspn(name, "=")] = '\0';
environ_set(env, name, "%s", value);
environ_set(env, name, flags, "%s", value);
free(name);
}
@ -170,7 +176,7 @@ environ_unset(struct environ *env, const char *name)
free(envent);
}
/* Copy variables from a destination into a source * environment. */
/* Copy variables from a destination into a source environment. */
void
environ_update(struct options *oo, struct environ *src, struct environ *dst)
{
@ -188,7 +194,7 @@ environ_update(struct options *oo, struct environ *src, struct environ *dst)
if ((envent = environ_find(src, ov->string)) == NULL)
environ_clear(dst, ov->string);
else
environ_set(dst, envent->name, "%s", envent->value);
environ_set(dst, envent->name, 0, "%s", envent->value);
a = options_array_next(a);
}
}
@ -201,7 +207,9 @@ environ_push(struct environ *env)
environ = xcalloc(1, sizeof *environ);
RB_FOREACH(envent, environ, env) {
if (envent->value != NULL && *envent->name != '\0')
if (envent->value != NULL &&
*envent->name != '\0' &&
(~envent->flags & ENVIRON_HIDDEN))
setenv(envent->name, envent->value, 1);
}
}
@ -243,14 +251,15 @@ environ_for_session(struct session *s, int no_TERM)
if (!no_TERM) {
value = options_get_string(global_options, "default-terminal");
environ_set(env, "TERM", "%s", value);
environ_set(env, "TERM", 0, "%s", value);
}
if (s != NULL)
idx = s->id;
else
idx = -1;
environ_set(env, "TMUX", "%s,%ld,%d", socket_path, (long)getpid(), idx);
environ_set(env, "TMUX", 0, "%s,%ld,%d", socket_path, (long)getpid(),
idx);
return (env);
}

13
grid.c
View File

@ -351,6 +351,19 @@ grid_collect_history(struct grid *gd)
gd->hscrolled = gd->hsize;
}
/* Remove lines from the bottom of the history. */
void
grid_remove_history(struct grid *gd, u_int ny)
{
u_int yy;
if (ny > gd->hsize)
return;
for (yy = 0; yy < ny; yy++)
grid_free_line(gd, gd->hsize + gd->sy - 1 - yy);
gd->hsize -= ny;
}
/*
* Scroll the entire visible screen, moving one line into the history. Just
* allocate a new line at the bottom and move the history size indicator.

View File

@ -518,6 +518,7 @@ server_client_check_mouse(struct client *c, struct key_event *event)
memcpy(&c->click_event, m, sizeof c->click_event);
c->click_button = m->b;
log_debug("click timer started");
tv.tv_sec = KEYC_CLICK_TIMEOUT / 1000;
tv.tv_usec = (KEYC_CLICK_TIMEOUT % 1000) * 1000L;
evtimer_del(&c->click_timer);
@ -2018,7 +2019,7 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
if (datalen == 0 || data[datalen - 1] != '\0')
fatalx("bad MSG_IDENTIFY_ENVIRON string");
if (strchr(data, '=') != NULL)
environ_put(c->environ, data);
environ_put(c->environ, data, 0);
log_debug("client %p IDENTIFY_ENVIRON %s", c, data);
break;
case MSG_IDENTIFY_CLIENTPID:

View File

@ -301,7 +301,7 @@ spawn_pane(struct spawn_context *sc, char **cause)
child = environ_for_session(s, 0);
if (sc->environ != NULL)
environ_copy(sc->environ, child);
environ_set(child, "TMUX_PANE", "%%%u", new_wp->id);
environ_set(child, "TMUX_PANE", 0, "%%%u", new_wp->id);
/*
* Then the PATH environment variable. The session one is replaced from
@ -311,10 +311,10 @@ spawn_pane(struct spawn_context *sc, char **cause)
if (c != NULL && c->session == NULL) { /* only unattached clients */
ee = environ_find(c->environ, "PATH");
if (ee != NULL)
environ_set(child, "PATH", "%s", ee->value);
environ_set(child, "PATH", 0, "%s", ee->value);
}
if (environ_find(child, "PATH") == NULL)
environ_set(child, "%s", _PATH_DEFPATH);
environ_set(child, "PATH", 0, "%s", _PATH_DEFPATH);
/* Then the shell. If respawning, use the old one. */
if (~sc->flags & SPAWN_RESPAWN) {
@ -324,7 +324,7 @@ spawn_pane(struct spawn_context *sc, char **cause)
free(new_wp->shell);
new_wp->shell = xstrdup(tmp);
}
environ_set(child, "SHELL", "%s", new_wp->shell);
environ_set(child, "SHELL", 0, "%s", new_wp->shell);
/* Log the arguments we are going to use. */
log_debug("%s: shell=%s", __func__, new_wp->shell);

55
tmux.1
View File

@ -565,6 +565,18 @@ Environment variables may be set by using the syntax
for example
.Ql HOME=/home/user .
Variables set during parsing are added to the global environment.
A hidden variable may be set with
.Ql %hidden ,
for example:
.Bd -literal -offset indent
%hidden MYVAR=42
.Ed
.Pp
Hidden variables are not passed to the environment of processes created
by tmux.
See the
.Sx GLOBAL AND SESSION ENVIRONMENT
section.
.Pp
Commands may be parsed conditionally by surrounding them with
.Ql %if ,
@ -1503,9 +1515,11 @@ The following commands are supported in copy mode:
.It Li "scroll-up" Ta "C-y" Ta "C-Up"
.It Li "search-again" Ta "n" Ta "n"
.It Li "search-backward <for>" Ta "?" Ta ""
.It Li "search-forward <for>" Ta "/" Ta ""
.It Li "search-backward-incremental <for>" Ta "" Ta "C-r"
.It Li "search-backward-text <for>" Ta "" Ta ""
.It Li "search-forward <for>" Ta "/" Ta ""
.It Li "search-forward-incremental <for>" Ta "" Ta "C-s"
.It Li "search-forward-text <for>" Ta "" Ta ""
.It Li "search-reverse" Ta "N" Ta "N"
.It Li "select-line" Ta "V" Ta ""
.It Li "select-word" Ta "" Ta ""
@ -1514,6 +1528,26 @@ The following commands are supported in copy mode:
.It Li "top-line" Ta "H" Ta "M-R"
.El
.Pp
The search commands come in several varieties:
.Ql search-forward
and
.Ql search-backward
search for a regular expression;
the
.Ql -text
variants search for a plain text string rather than a regular expression;
.Ql -incremental
perform an incremental search and expect to be used with the
.Fl i
flag to the
.Ic command-prompt
command.
.Ql search-again
repeats the last search and
.Ql search-reverse
does the same but reverses the direction (forward becomes backward and backward
becomes forward).
.Pp
Copy commands may take an optional buffer prefix argument which is used
to generate the buffer name (the default is
.Ql buffer
@ -2239,7 +2273,7 @@ Rename the current window, or the window at
if specified, to
.Ar new-name .
.It Xo Ic resize-pane
.Op Fl DLMRUZ
.Op Fl DLMRTUZ
.Op Fl t Ar target-pane
.Op Fl x Ar width
.Op Fl y Ar height
@ -2278,6 +2312,9 @@ and unzoomed (its normal position in the layout).
.Fl M
begins mouse resizing (only valid if bound to a mouse key binding, see
.Sx MOUSE SUPPORT ) .
.Pp T
trims all lines below the current cursor position and moves lines out of the
history to replace them.
.It Xo Ic resize-window
.Op Fl aADLRU
.Op Fl t Ar target-window
@ -4687,10 +4724,16 @@ from inside, and the
variable with the correct terminal setting of
.Ql screen .
.Pp
Variables in both session and global environments may be marked as hidden.
Hidden variables are not passed into the environment of new processes and
instead can only be used by tmux itself (for example in formats, see the
.Sx FORMATS
section).
.Pp
Commands to alter and view the environment are:
.Bl -tag -width Ds
.It Xo Ic set-environment
.Op Fl gru
.Op Fl hgru
.Op Fl t Ar target-session
.Ar name Op Ar value
.Xc
@ -4707,8 +4750,10 @@ flag unsets a variable.
.Fl r
indicates the variable is to be removed from the environment before starting a
new process.
.Fl h
marks the variable as hidden.
.It Xo Ic show-environment
.Op Fl gs
.Op Fl hgs
.Op Fl t Ar target-session
.Op Ar variable
.Xc
@ -4725,6 +4770,8 @@ Variables removed from the environment are prefixed with
If
.Fl s
is used, the output is formatted as a set of Bourne shell commands.
.Fl h
shows hidden variables (omitted by default).
.El
.Sh STATUS LINE
.Nm

4
tmux.c
View File

@ -321,9 +321,9 @@ main(int argc, char **argv)
global_environ = environ_create();
for (var = environ; *var != NULL; var++)
environ_put(global_environ, *var);
environ_put(global_environ, *var, 0);
if ((cwd = find_cwd()) != NULL)
environ_set(global_environ, "PWD", "%s", cwd);
environ_set(global_environ, "PWD", 0, "%s", cwd);
global_options = options_create(NULL);
global_s_options = options_create(NULL);

11
tmux.h
View File

@ -929,7 +929,9 @@ struct window_pane {
TAILQ_HEAD (, window_mode_entry) modes;
struct event modetimer;
time_t modelast;
char *searchstr;
int searchregex;
TAILQ_ENTRY(window_pane) entry;
RB_ENTRY(window_pane) tree_entry;
@ -1048,6 +1050,9 @@ struct environ_entry {
char *name;
char *value;
int flags;
#define ENVIRON_HIDDEN 0x1
RB_ENTRY(environ_entry) entry;
};
@ -1957,10 +1962,10 @@ struct environ_entry *environ_first(struct environ *);
struct environ_entry *environ_next(struct environ_entry *);
void environ_copy(struct environ *, struct environ *);
struct environ_entry *environ_find(struct environ *, const char *);
void printflike(3, 4) environ_set(struct environ *, const char *, const char *,
...);
void printflike(4, 5) environ_set(struct environ *, const char *, int,
const char *, ...);
void environ_clear(struct environ *, const char *);
void environ_put(struct environ *, const char *);
void environ_put(struct environ *, const char *, int);
void environ_unset(struct environ *, const char *);
void environ_update(struct options *, struct environ *, struct environ *);
void environ_push(struct environ *);

View File

@ -256,6 +256,7 @@ struct window_copy_mode_data {
u_int lastsx; /* size of last line w/ content */
int searchtype;
int searchregex;
char *searchstr;
bitstr_t *searchmark;
u_int searchcount;
@ -310,9 +311,11 @@ window_copy_common_init(struct window_mode_entry *wme)
if (wp->searchstr != NULL) {
data->searchtype = WINDOW_COPY_SEARCHUP;
data->searchregex = wp->searchregex;
data->searchstr = xstrdup(wp->searchstr);
} else {
data->searchtype = WINDOW_COPY_OFF;
data->searchregex = 0;
data->searchstr = NULL;
}
data->searchmark = NULL;
@ -700,6 +703,35 @@ window_copy_key_table(struct window_mode_entry *wme)
return ("copy-mode");
}
static int
window_copy_expand_search_string(struct window_copy_cmd_state *cs)
{
struct window_mode_entry *wme = cs->wme;
struct window_copy_mode_data *data = wme->data;
const char *argument;
char *expanded;
if (cs->args->argc == 2) {
argument = cs->args->argv[1];
if (*argument != '\0') {
if (args_has(cs->args, 'F')) {
expanded = format_single(NULL, argument, NULL,
NULL, NULL, wme->wp);
if (*expanded == '\0') {
free(expanded);
return (0);
}
free(data->searchstr);
data->searchstr = expanded;
} else {
free(data->searchstr);
data->searchstr = xstrdup(argument);
}
}
}
return (1);
}
static enum window_copy_cmd_action
window_copy_cmd_append_selection(struct window_copy_cmd_state *cs)
{
@ -1525,10 +1557,10 @@ window_copy_cmd_search_again(struct window_copy_cmd_state *cs)
if (data->searchtype == WINDOW_COPY_SEARCHUP) {
for (; np != 0; np--)
window_copy_search_up(wme, 1);
window_copy_search_up(wme, data->searchregex);
} else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) {
for (; np != 0; np--)
window_copy_search_down(wme, 1);
window_copy_search_down(wme, data->searchregex);
}
return (WINDOW_COPY_CMD_NOTHING);
}
@ -1542,10 +1574,10 @@ window_copy_cmd_search_reverse(struct window_copy_cmd_state *cs)
if (data->searchtype == WINDOW_COPY_SEARCHUP) {
for (; np != 0; np--)
window_copy_search_down(wme, 1);
window_copy_search_down(wme, data->searchregex);
} else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) {
for (; np != 0; np--)
window_copy_search_up(wme, 1);
window_copy_search_up(wme, data->searchregex);
}
return (WINDOW_COPY_CMD_NOTHING);
}
@ -1765,70 +1797,76 @@ window_copy_cmd_search_backward(struct window_copy_cmd_state *cs)
struct window_mode_entry *wme = cs->wme;
struct window_copy_mode_data *data = wme->data;
u_int np = wme->prefix;
const char *argument;
char *expanded;
if (cs->args->argc == 2) {
argument = cs->args->argv[1];
if (*argument != '\0') {
if (args_has(cs->args, 'F')) {
expanded = format_single(NULL, argument, NULL,
NULL, NULL, wme->wp);
if (*expanded == '\0') {
free(expanded);
return (WINDOW_COPY_CMD_NOTHING);
}
free(data->searchstr);
data->searchstr = expanded;
} else {
free(data->searchstr);
data->searchstr = xstrdup(argument);
}
}
}
if (!window_copy_expand_search_string(cs))
return (WINDOW_COPY_CMD_NOTHING);
if (data->searchstr != NULL) {
data->searchtype = WINDOW_COPY_SEARCHUP;
data->searchregex = 1;
for (; np != 0; np--)
window_copy_search_up(wme, 1);
}
return (WINDOW_COPY_CMD_NOTHING);
}
static enum window_copy_cmd_action
window_copy_cmd_search_backward_text(struct window_copy_cmd_state *cs)
{
struct window_mode_entry *wme = cs->wme;
struct window_copy_mode_data *data = wme->data;
u_int np = wme->prefix;
if (!window_copy_expand_search_string(cs))
return (WINDOW_COPY_CMD_NOTHING);
if (data->searchstr != NULL) {
data->searchtype = WINDOW_COPY_SEARCHUP;
data->searchregex = 0;
for (; np != 0; np--)
window_copy_search_up(wme, 0);
}
return (WINDOW_COPY_CMD_NOTHING);
}
static enum window_copy_cmd_action
window_copy_cmd_search_forward(struct window_copy_cmd_state *cs)
{
struct window_mode_entry *wme = cs->wme;
struct window_copy_mode_data *data = wme->data;
u_int np = wme->prefix;
const char *argument;
char *expanded;
if (cs->args->argc == 2) {
argument = cs->args->argv[1];
if (*argument != '\0') {
if (args_has(cs->args, 'F')) {
expanded = format_single(NULL, argument, NULL,
NULL, NULL, wme->wp);
if (*expanded == '\0') {
free(expanded);
return (WINDOW_COPY_CMD_NOTHING);
}
free(data->searchstr);
data->searchstr = expanded;
} else {
free(data->searchstr);
data->searchstr = xstrdup(argument);
}
}
}
if (!window_copy_expand_search_string(cs))
return (WINDOW_COPY_CMD_NOTHING);
if (data->searchstr != NULL) {
data->searchtype = WINDOW_COPY_SEARCHDOWN;
data->searchregex = 1;
for (; np != 0; np--)
window_copy_search_down(wme, 1);
}
return (WINDOW_COPY_CMD_NOTHING);
}
static enum window_copy_cmd_action
window_copy_cmd_search_forward_text(struct window_copy_cmd_state *cs)
{
struct window_mode_entry *wme = cs->wme;
struct window_copy_mode_data *data = wme->data;
u_int np = wme->prefix;
if (!window_copy_expand_search_string(cs))
return (WINDOW_COPY_CMD_NOTHING);
if (data->searchstr != NULL) {
data->searchtype = WINDOW_COPY_SEARCHDOWN;
data->searchregex = 0;
for (; np != 0; np--)
window_copy_search_down(wme, 0);
}
return (WINDOW_COPY_CMD_NOTHING);
}
static enum window_copy_cmd_action
window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs)
{
@ -1858,6 +1896,7 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs)
case '=':
case '-':
data->searchtype = WINDOW_COPY_SEARCHUP;
data->searchregex = 0;
free(data->searchstr);
data->searchstr = xstrdup(argument);
if (!window_copy_search_up(wme, 0)) {
@ -1867,6 +1906,7 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs)
break;
case '+':
data->searchtype = WINDOW_COPY_SEARCHDOWN;
data->searchregex = 0;
free(data->searchstr);
data->searchstr = xstrdup(argument);
if (!window_copy_search_down(wme, 0)) {
@ -1907,6 +1947,7 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs)
case '=':
case '+':
data->searchtype = WINDOW_COPY_SEARCHDOWN;
data->searchregex = 0;
free(data->searchstr);
data->searchstr = xstrdup(argument);
if (!window_copy_search_down(wme, 0)) {
@ -1916,6 +1957,7 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs)
break;
case '-':
data->searchtype = WINDOW_COPY_SEARCHUP;
data->searchregex = 0;
free(data->searchstr);
data->searchstr = xstrdup(argument);
if (!window_copy_search_up(wme, 0)) {
@ -2041,10 +2083,14 @@ static const struct {
window_copy_cmd_search_again },
{ "search-backward", 0, 1, 0,
window_copy_cmd_search_backward },
{ "search-backward-text", 0, 1, 0,
window_copy_cmd_search_backward_text },
{ "search-backward-incremental", 1, 1, 0,
window_copy_cmd_search_backward_incremental },
{ "search-forward", 0, 1, 0,
window_copy_cmd_search_forward },
{ "search-forward-text", 0, 1, 0,
window_copy_cmd_search_forward_text },
{ "search-forward-incremental", 1, 1, 0,
window_copy_cmd_search_forward_incremental },
{ "search-reverse", 0, 0, 0,
@ -2653,6 +2699,7 @@ window_copy_search(struct window_mode_entry *wme, int direction, int regex)
free(wp->searchstr);
wp->searchstr = xstrdup(data->searchstr);
wp->searchregex = regex;
fx = data->cx;
fy = screen_hsize(data->backing) - data->oy + data->cy;