mirror of
https://github.com/tmux/tmux.git
synced 2024-12-04 19:58:48 +00:00
Key running commands for #() by the unexpanded command, and run them
again if the expanded form changes (otherwise at most once per second as usual). Fixes issues reported by Gregory Pakosz.
This commit is contained in:
parent
ddf7ac5ae4
commit
3cf19d6dd0
34
format.c
34
format.c
@ -78,6 +78,7 @@ static void format_defaults_winlink(struct format_tree *, struct session *,
|
||||
/* Entry in format job tree. */
|
||||
struct format_job {
|
||||
const char *cmd;
|
||||
const char *expanded;
|
||||
|
||||
time_t last;
|
||||
char *out;
|
||||
@ -232,22 +233,33 @@ format_job_callback(struct job *job)
|
||||
static char *
|
||||
format_job_get(struct format_tree *ft, const char *cmd)
|
||||
{
|
||||
struct format_job fj0, *fj;
|
||||
time_t t;
|
||||
struct format_job fj0, *fj;
|
||||
time_t t;
|
||||
char *expanded;
|
||||
int force;
|
||||
|
||||
fj0.cmd = cmd;
|
||||
if ((fj = RB_FIND(format_job_tree, &format_jobs, &fj0)) == NULL) {
|
||||
fj = xcalloc(1, sizeof *fj);
|
||||
fj->cmd = xstrdup(cmd);
|
||||
fj->expanded = NULL;
|
||||
|
||||
xasprintf(&fj->out, "<'%s' not ready>", fj->cmd);
|
||||
|
||||
RB_INSERT(format_job_tree, &format_jobs, fj);
|
||||
}
|
||||
|
||||
expanded = format_expand(ft, cmd);
|
||||
if (fj->expanded == NULL || strcmp(expanded, fj->expanded) != 0) {
|
||||
free((void *)fj->expanded);
|
||||
fj->expanded = xstrdup(expanded);
|
||||
force = 1;
|
||||
} else
|
||||
force = (ft->flags & FORMAT_FORCE);
|
||||
|
||||
t = time(NULL);
|
||||
if (fj->job == NULL && ((ft->flags & FORMAT_FORCE) || fj->last != t)) {
|
||||
fj->job = job_run(fj->cmd, NULL, NULL, format_job_callback,
|
||||
if (fj->job == NULL && (force || fj->last != t)) {
|
||||
fj->job = job_run(expanded, NULL, NULL, format_job_callback,
|
||||
NULL, fj);
|
||||
if (fj->job == NULL) {
|
||||
free(fj->out);
|
||||
@ -259,6 +271,7 @@ format_job_get(struct format_tree *ft, const char *cmd)
|
||||
if (ft->flags & FORMAT_STATUS)
|
||||
fj->status = 1;
|
||||
|
||||
free(expanded);
|
||||
return (format_expand(ft, fj->out));
|
||||
}
|
||||
|
||||
@ -281,6 +294,7 @@ format_job_timer(__unused int fd, __unused short events, __unused void *arg)
|
||||
if (fj->job != NULL)
|
||||
job_free(fj->job);
|
||||
|
||||
free((void *)fj->expanded);
|
||||
free((void *)fj->cmd);
|
||||
free(fj->out);
|
||||
|
||||
@ -883,7 +897,7 @@ format_expand_time(struct format_tree *ft, const char *fmt, time_t t)
|
||||
char *
|
||||
format_expand(struct format_tree *ft, const char *fmt)
|
||||
{
|
||||
char *buf, *tmp, *cmd, *out;
|
||||
char *buf, *out;
|
||||
const char *ptr, *s, *saved = fmt;
|
||||
size_t off, len, n, outlen;
|
||||
int ch, brackets;
|
||||
@ -920,17 +934,9 @@ format_expand(struct format_tree *ft, const char *fmt)
|
||||
break;
|
||||
n = ptr - fmt;
|
||||
|
||||
tmp = xmalloc(n + 1);
|
||||
memcpy(tmp, fmt, n);
|
||||
tmp[n] = '\0';
|
||||
cmd = format_expand(ft, tmp);
|
||||
|
||||
out = format_job_get(ft, cmd);
|
||||
out = format_job_get(ft, xstrndup(fmt, n));
|
||||
outlen = strlen(out);
|
||||
|
||||
free(cmd);
|
||||
free(tmp);
|
||||
|
||||
while (len - off < outlen + 1) {
|
||||
buf = xreallocarray(buf, 2, len);
|
||||
len *= 2;
|
||||
|
10
xmalloc.c
10
xmalloc.c
@ -81,6 +81,16 @@ xstrdup(const char *str)
|
||||
return cp;
|
||||
}
|
||||
|
||||
char *
|
||||
xstrndup(const char *str, size_t maxlen)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if ((cp = strndup(str, maxlen)) == NULL)
|
||||
fatalx("xstrndup: %s", strerror(errno));
|
||||
return cp;
|
||||
}
|
||||
|
||||
int
|
||||
xasprintf(char **ret, const char *fmt, ...)
|
||||
{
|
||||
|
@ -24,6 +24,7 @@ void *xcalloc(size_t, size_t);
|
||||
void *xrealloc(void *, size_t);
|
||||
void *xreallocarray(void *, size_t, size_t);
|
||||
char *xstrdup(const char *);
|
||||
char *xstrndup(const char *, size_t);
|
||||
int xasprintf(char **, const char *, ...)
|
||||
__attribute__((__format__ (printf, 2, 3)))
|
||||
__attribute__((__nonnull__ (2)));
|
||||
|
Loading…
Reference in New Issue
Block a user