mirror of
https://github.com/tmux/tmux.git
synced 2025-04-09 10:28:49 +00:00
Merge branch 'obsd-master'
This commit is contained in:
commit
dfd29977e0
@ -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);
|
||||
}
|
||||
|
||||
|
23
cmd-parse.y
23
cmd-parse.y
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
29
environ.c
29
environ.c
@ -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
13
grid.c
@ -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.
|
||||
|
@ -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:
|
||||
|
8
spawn.c
8
spawn.c
@ -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
55
tmux.1
@ -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
4
tmux.c
@ -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
11
tmux.h
@ -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 *);
|
||||
|
135
window-copy.c
135
window-copy.c
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user