Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam
2025-05-12 14:01:10 +01:00
7 changed files with 93 additions and 52 deletions

View File

@@ -44,8 +44,8 @@ const struct cmd_entry cmd_run_shell_entry = {
.name = "run-shell",
.alias = "run",
.args = { "bd:Ct:c:", 0, 1, cmd_run_shell_args_parse },
.usage = "[-bC] [-c start-directory] [-d delay] " CMD_TARGET_PANE_USAGE
.args = { "bd:Ct:Es:c:", 0, 1, cmd_run_shell_args_parse },
.usage = "[-bCE] [-c start-directory] [-d delay] " CMD_TARGET_PANE_USAGE
" [shell-command]",
.target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL },
@@ -158,6 +158,9 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item)
else
cdata->cwd = xstrdup(server_client_get_cwd(c, s));
if (args_has(args, 'E'))
cdata->flags |= JOB_SHOWSTDERR;
cdata->s = s;
if (s != NULL)
session_add_ref(s, __func__);

View File

@@ -106,6 +106,7 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2)
#define FORMAT_CLIENTS 0x40000
#define FORMAT_NOT 0x80000
#define FORMAT_NOT_NOT 0x100000
#define FORMAT_REPEAT 0x200000
/* Limit on recursion. */
#define FORMAT_LOOP_LIMIT 100
@@ -205,7 +206,7 @@ static const char *format_upper[] = {
"window_name", /* W */
NULL, /* X */
NULL, /* Y */
NULL /* Z */
NULL /* Z */
};
/* Single-character lowercase aliases. */
@@ -865,7 +866,7 @@ format_cb_history_bytes(struct format_tree *ft)
struct window_pane *wp = ft->wp;
struct grid *gd;
struct grid_line *gl;
size_t size = 0;
size_t size = 0;
u_int i;
char *value;
@@ -1623,11 +1624,11 @@ format_cb_cursor_shape(struct format_tree *ft)
switch (ft->wp->screen->cstyle) {
case SCREEN_CURSOR_BLOCK:
return (xstrdup("block"));
case SCREEN_CURSOR_UNDERLINE:
case SCREEN_CURSOR_UNDERLINE:
return (xstrdup("underline"));
case SCREEN_CURSOR_BAR:
case SCREEN_CURSOR_BAR:
return (xstrdup("bar"));
default:
default:
return (xstrdup("default"));
}
}
@@ -3672,7 +3673,7 @@ format_quote_style(const char *s)
char *
format_pretty_time(time_t t, int seconds)
{
struct tm now_tm, tm;
struct tm now_tm, tm;
time_t now, age;
char s[9];
@@ -3850,7 +3851,7 @@ format_unescape(const char *s)
*s == '#' &&
strchr(",#{}:", s[1]) != NULL) {
*cp++ = *++s;
continue;
continue;
}
if (*s == '}')
brackets--;
@@ -3992,10 +3993,10 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
/*
* Modifiers are a ; separated list of the forms:
* l,m,C,a,b,c,d,n,t,w,q,E,T,S,W,P,<,>
* l,m,C,a,b,c,d,n,t,w,q,E,T,S,W,P,R,<,>
* =a
* =/a
* =/a/
* =/a/
* s/a/b/
* s/a/b
* ||,&&,!=,==,<=,>=
@@ -4031,7 +4032,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
}
/* Now try single character with arguments. */
if (strchr("mCNst=peq", cp[0]) == NULL)
if (strchr("mCNst=pReq", cp[0]) == NULL)
break;
c = cp[0];
@@ -4586,7 +4587,7 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
struct format_modifier *list, *cmp = NULL, *search = NULL;
struct format_modifier **sub = NULL, *mexp = NULL, *fm;
struct format_modifier *bool_op_n = NULL;
u_int i, count, nsub = 0;
u_int i, count, nsub = 0, nrep;
struct format_expand_state next;
/* Make a copy of the key. */
@@ -4708,6 +4709,9 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
case 'L':
modifiers |= FORMAT_CLIENTS;
break;
case 'R':
modifiers |= FORMAT_REPEAT;
break;
}
} else if (fm->size == 2) {
if (strcmp(fm->modifier, "||") == 0 ||
@@ -4790,7 +4794,26 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
value = format_search(search, wp, new);
}
free(new);
} else if (modifiers & FORMAT_NOT) {
} else if (modifiers & FORMAT_REPEAT) {
/* Repeat multiple times. */
if (format_choose(es, copy, &left, &right, 1) != 0) {
format_log(es, "repeat syntax error: %s", copy);
goto fail;
}
nrep = strtonum(right, 1, 10000, &errstr);
if (errstr != NULL)
value = xstrdup("");
else {
value = xstrdup("");
for (i = 0; i < nrep; i++) {
xasprintf(&new, "%s%s", value, left);
free(value);
value = new;
}
}
free(right);
free(left);
} else if (modifiers & FORMAT_NOT) {
value = format_bool_op_1(es, copy, 1);
} else if (modifiers & FORMAT_NOT_NOT) {
value = format_bool_op_1(es, copy, 0);
@@ -5050,7 +5073,7 @@ format_expand1(struct format_expand_state *es, const char *fmt)
char *buf, *out, *name;
const char *ptr, *s, *style_end = NULL;
size_t off, len, n, outlen;
int ch, brackets;
int ch, brackets;
char expanded[8192];
if (fmt == NULL || *fmt == '\0')

27
job.c
View File

@@ -77,7 +77,7 @@ job_run(const char *cmd, int argc, char **argv, struct environ *e,
struct job *job;
struct environ *env;
pid_t pid;
int nullfd, out[2], master;
int nullfd, out[2], master, do_close = 1;
const char *home, *shell;
sigset_t set, oldset;
struct winsize ws;
@@ -150,19 +150,26 @@ job_run(const char *cmd, int argc, char **argv, struct environ *e,
if (~flags & JOB_PTY) {
if (dup2(out[1], STDIN_FILENO) == -1)
fatal("dup2 failed");
do_close = do_close && out[1] != STDIN_FILENO;
if (dup2(out[1], STDOUT_FILENO) == -1)
fatal("dup2 failed");
if (out[1] != STDIN_FILENO && out[1] != STDOUT_FILENO)
do_close = do_close && out[1] != STDOUT_FILENO;
if (flags & JOB_SHOWSTDERR) {
if (dup2(out[1], STDERR_FILENO) == -1)
fatal("dup2 failed");
do_close = do_close && out[1] != STDERR_FILENO;
} else {
nullfd = open(_PATH_DEVNULL, O_RDWR);
if (nullfd == -1)
fatal("open failed");
if (dup2(nullfd, STDERR_FILENO) == -1)
fatal("dup2 failed");
if (nullfd != STDERR_FILENO)
close(nullfd);
}
if (do_close)
close(out[1]);
close(out[0]);
nullfd = open(_PATH_DEVNULL, O_RDWR);
if (nullfd == -1)
fatal("open failed");
if (dup2(nullfd, STDERR_FILENO) == -1)
fatal("dup2 failed");
if (nullfd != STDERR_FILENO)
close(nullfd);
}
closefrom(STDERR_FILENO + 1);

View File

@@ -631,17 +631,18 @@ status_prompt_set(struct client *c, struct cmd_find_state *fs,
if (input == NULL)
input = "";
if (flags & PROMPT_NOFORMAT)
tmp = xstrdup(input);
else
tmp = format_expand_time(ft, input);
status_message_clear(c);
status_prompt_clear(c);
status_push_screen(c);
c->prompt_string = format_expand_time(ft, msg);
c->prompt_formats = ft;
c->prompt_string = xstrdup (msg);
if (flags & PROMPT_NOFORMAT)
tmp = xstrdup(input);
else
tmp = format_expand_time(ft, input);
if (flags & PROMPT_INCREMENTAL) {
c->prompt_last = xstrdup(tmp);
c->prompt_buffer = utf8_fromcstr("");
@@ -650,6 +651,7 @@ status_prompt_set(struct client *c, struct cmd_find_state *fs,
c->prompt_buffer = utf8_fromcstr(tmp);
}
c->prompt_index = utf8_strlen(c->prompt_buffer);
free(tmp);
c->prompt_inputcb = inputcb;
c->prompt_freecb = freecb;
@@ -668,9 +670,6 @@ status_prompt_set(struct client *c, struct cmd_find_state *fs,
if (flags & PROMPT_INCREMENTAL)
c->prompt_inputcb(c, c->prompt_data, "=", 0);
free(tmp);
format_free(ft);
if ((flags & PROMPT_SINGLE) && (flags & PROMPT_ACCEPT))
cmdq_append(c, cmdq_get_callback(status_prompt_accept, c));
}
@@ -688,6 +687,9 @@ status_prompt_clear(struct client *c)
free(c->prompt_last);
c->prompt_last = NULL;
format_free(c->prompt_formats);
c->prompt_formats = NULL;
free(c->prompt_string);
c->prompt_string = NULL;
@@ -707,27 +709,20 @@ status_prompt_clear(struct client *c)
void
status_prompt_update(struct client *c, const char *msg, const char *input)
{
struct format_tree *ft;
char *tmp;
ft = format_create(c, NULL, FORMAT_NONE, 0);
format_defaults(ft, c, NULL, NULL, NULL);
tmp = format_expand_time(ft, input);
char *tmp;
free(c->prompt_string);
c->prompt_string = format_expand_time(ft, msg);
c->prompt_string = xstrdup(msg);
free(c->prompt_buffer);
tmp = format_expand_time(c->prompt_formats, input);
c->prompt_buffer = utf8_fromcstr(tmp);
c->prompt_index = utf8_strlen(c->prompt_buffer);
free(tmp);
memset(c->prompt_hindex, 0, sizeof c->prompt_hindex);
c->flags |= CLIENT_REDRAWSTATUS;
free(tmp);
format_free(ft);
}
/* Redraw character. Return 1 if can continue redrawing, 0 otherwise. */
@@ -790,7 +785,8 @@ status_prompt_redraw(struct client *c)
u_int i, lines, offset, left, start, width, n;
u_int pcursor, pwidth, promptline;
struct grid_cell gc;
struct format_tree *ft;
struct format_tree *ft = c->prompt_formats;
char *prompt, *tmp;
if (c->tty.sx == 0 || c->tty.sy == 0)
return (0);
@@ -811,14 +807,17 @@ status_prompt_redraw(struct client *c)
if (promptline > lines - 1)
promptline = lines - 1;
ft = format_create_defaults(NULL, c, NULL, NULL, NULL);
if (c->prompt_mode == PROMPT_COMMAND)
style_apply(&gc, s->options, "message-command-style", ft);
else
style_apply(&gc, s->options, "message-style", ft);
format_free(ft);
start = format_width(c->prompt_string);
tmp = utf8_tocstr(c->prompt_buffer);
format_add(c->prompt_formats, "prompt-input", "%s", tmp);
prompt = format_expand_time(c->prompt_formats, c->prompt_string);
free (tmp);
start = format_width(prompt);
if (start > c->tty.sx)
start = c->tty.sx;
@@ -828,7 +827,7 @@ status_prompt_redraw(struct client *c)
for (offset = 0; offset < c->tty.sx; offset++)
screen_write_putc(&ctx, &gc, ' ');
screen_write_cursormove(&ctx, 0, promptline, 0);
format_draw(&ctx, &gc, start, c->prompt_string, NULL, 0);
format_draw(&ctx, &gc, start, prompt, NULL, 0);
screen_write_cursormove(&ctx, start, promptline, 0);
left = c->tty.sx - start;

10
tmux.1
View File

@@ -5835,6 +5835,12 @@ expands to the length of the variable and
.Ql w
to its width when displayed, for example
.Ql #{n:window_name} .
.Ql R
repeats the first argument by a number of times given by the second argument,
so
.Ql #{R:a,3}
will result in
.Ql aaa .
.Pp
Prefixing a time variable with
.Ql t:\&
@@ -7283,7 +7289,7 @@ Lock each client individually by running the command specified by the
option.
.Tg run
.It Xo Ic run-shell
.Op Fl bC
.Op Fl bCE
.Op Fl c Ar start-directory
.Op Fl d Ar delay
.Op Fl t Ar target-pane
@@ -7311,6 +7317,8 @@ the command is run in the background.
waits for
.Ar delay
seconds before starting the command.
.Fl E
redirects the command's stderr to stdout instead of ignoring it.
If
.Fl c
is given, the current working directory is set to

2
tmux.h
View File

@@ -2024,6 +2024,7 @@ struct client {
struct event message_timer;
char *prompt_string;
struct format_tree *prompt_formats;
struct utf8_data *prompt_buffer;
char *prompt_last;
size_t prompt_index;
@@ -2428,6 +2429,7 @@ typedef void (*job_free_cb) (void *);
#define JOB_KEEPWRITE 0x2
#define JOB_PTY 0x4
#define JOB_DEFAULTSHELL 0x8
#define JOB_SHOWSTDERR 0x10
struct job *job_run(const char *, int, char **, struct environ *,
struct session *, const char *, job_update_cb,
job_complete_cb, job_free_cb, void *, int, int, int);

3
tty.c
View File

@@ -2756,8 +2756,7 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc,
if (changed & GRID_ATTR_ITALICS)
tty_set_italics(tty);
if (changed & GRID_ATTR_ALL_UNDERSCORE) {
if ((changed & GRID_ATTR_UNDERSCORE) ||
!tty_term_has(tty->term, TTYC_SMULX))
if (changed & GRID_ATTR_UNDERSCORE)
tty_putcode(tty, TTYC_SMUL);
else if (changed & GRID_ATTR_UNDERSCORE_2)
tty_putcode_i(tty, TTYC_SMULX, 2);