version 1.45, 2009/11/19 10:22:07 |
version 1.46, 2009/11/19 11:38:54 |
|
|
void status_job_callback(struct job *); |
void status_job_callback(struct job *); |
size_t status_width(struct winlink *); |
size_t status_width(struct winlink *); |
char *status_print(struct session *, struct winlink *, struct grid_cell *); |
char *status_print(struct session *, struct winlink *, struct grid_cell *); |
|
void status_replace1( |
|
struct client *, char **, char **, char *, size_t, int); |
void status_message_callback(int, short, void *); |
void status_message_callback(int, short, void *); |
|
|
void status_prompt_add_history(struct client *); |
void status_prompt_add_history(struct client *); |
|
|
return (1); |
return (1); |
} |
} |
|
|
char * |
/* Replace a single special sequence (prefixed by #). */ |
status_replace(struct client *c, const char *fmt, time_t t, int run_jobs) |
void |
|
status_replace1(struct client *c, |
|
char **iptr, char **optr, char *out, size_t outsize, int jobsflag) |
{ |
{ |
struct session *s = c->session; |
struct session *s = c->session; |
struct winlink *wl = s->curw; |
struct winlink *wl = s->curw; |
|
char ch, tmp[256], *ptr, *endptr, *freeptr; |
|
size_t ptrlen; |
|
long limit; |
|
|
|
errno = 0; |
|
limit = strtol(*iptr, &endptr, 10); |
|
if ((limit == 0 && errno != EINVAL) || |
|
(limit == LONG_MIN && errno != ERANGE) || |
|
(limit == LONG_MAX && errno != ERANGE) || |
|
limit != 0) |
|
*iptr = endptr; |
|
if (limit <= 0) |
|
limit = LONG_MAX; |
|
|
|
freeptr = NULL; |
|
|
|
switch (*(*iptr)++) { |
|
case '(': |
|
if (!jobsflag) { |
|
ch = ')'; |
|
goto skip_to; |
|
} |
|
if ((ptr = status_job(c, iptr)) == NULL) |
|
return; |
|
freeptr = ptr; |
|
goto do_replace; |
|
case 'H': |
|
if (gethostname(tmp, sizeof tmp) != 0) |
|
fatal("gethostname failed"); |
|
ptr = tmp; |
|
goto do_replace; |
|
case 'I': |
|
xsnprintf(tmp, sizeof tmp, "%d", wl->idx); |
|
ptr = tmp; |
|
goto do_replace; |
|
case 'P': |
|
xsnprintf(tmp, sizeof tmp, "%u", |
|
window_pane_index(wl->window, wl->window->active)); |
|
ptr = tmp; |
|
goto do_replace; |
|
case 'S': |
|
ptr = s->name; |
|
goto do_replace; |
|
case 'T': |
|
ptr = wl->window->active->base.title; |
|
goto do_replace; |
|
case 'W': |
|
ptr = wl->window->name; |
|
goto do_replace; |
|
case '[': |
|
/* |
|
* Embedded style, handled at display time. Leave present and |
|
* skip input until ]. |
|
*/ |
|
ch = ']'; |
|
goto skip_to; |
|
case '#': |
|
*(*optr++) = '#'; |
|
break; |
|
} |
|
|
|
return; |
|
|
|
do_replace: |
|
ptrlen = strlen(ptr); |
|
if ((size_t) limit < ptrlen) |
|
ptrlen = limit; |
|
|
|
if (*optr + ptrlen >= out + outsize - 1) |
|
return; |
|
while (ptrlen > 0 && *ptr != '\0') { |
|
*(*optr)++ = *ptr++; |
|
ptrlen--; |
|
} |
|
|
|
if (freeptr != NULL) |
|
xfree(freeptr); |
|
return; |
|
|
|
skip_to: |
|
*(*optr)++ = '#'; |
|
|
|
(*iptr)--; /* include ch */ |
|
while (**iptr != ch && **iptr != '\0') { |
|
if (*optr >= out + outsize - 1) |
|
break; |
|
*(*optr)++ = *(*iptr)++; |
|
} |
|
} |
|
|
|
/* Replace special sequences in fmt. */ |
|
char * |
|
status_replace(struct client *c, const char *fmt, time_t t, int jobsflag) |
|
{ |
static char out[BUFSIZ]; |
static char out[BUFSIZ]; |
char in[BUFSIZ], tmp[256], ch, *iptr, *optr, *ptr, *endptr; |
char in[BUFSIZ], ch, *iptr, *optr; |
char *savedptr; /* freed at end of each loop */ |
|
size_t len; |
|
long n; |
|
|
|
|
|
strftime(in, sizeof in, fmt, localtime(&t)); |
strftime(in, sizeof in, fmt, localtime(&t)); |
in[(sizeof in) - 1] = '\0'; |
in[(sizeof in) - 1] = '\0'; |
|
|
iptr = in; |
iptr = in; |
optr = out; |
optr = out; |
savedptr = NULL; |
|
|
|
while (*iptr != '\0') { |
while (*iptr != '\0') { |
if (optr >= out + (sizeof out) - 1) |
if (optr >= out + (sizeof out) - 1) |
break; |
break; |
switch (ch = *iptr++) { |
ch = *iptr++; |
case '#': |
|
errno = 0; |
|
n = strtol(iptr, &endptr, 10); |
|
if ((n == 0 && errno != EINVAL) || |
|
(n == LONG_MIN && errno != ERANGE) || |
|
(n == LONG_MAX && errno != ERANGE) || |
|
n != 0) |
|
iptr = endptr; |
|
if (n <= 0) |
|
n = LONG_MAX; |
|
|
|
ptr = NULL; |
if (ch != '#') { |
switch (*iptr++) { |
|
case '(': |
|
if (run_jobs) { |
|
if (ptr == NULL) { |
|
ptr = status_job(c, &iptr); |
|
if (ptr == NULL) |
|
break; |
|
savedptr = ptr; |
|
} |
|
} else { |
|
/* Don't run jobs. Copy to ). */ |
|
*optr++ = '#'; |
|
|
|
iptr--; /* include [ */ |
|
while (*iptr != ')' && *iptr != '\0') { |
|
if (optr >= |
|
out + (sizeof out) - 1) |
|
break; |
|
*optr++ = *iptr++; |
|
} |
|
break; |
|
} |
|
/* FALLTHROUGH */ |
|
case 'H': |
|
if (ptr == NULL) { |
|
if (gethostname(tmp, sizeof tmp) != 0) |
|
fatal("gethostname failed"); |
|
ptr = tmp; |
|
} |
|
/* FALLTHROUGH */ |
|
case 'I': |
|
if (ptr == NULL) { |
|
xsnprintf(tmp, sizeof tmp, "%d", wl->idx); |
|
ptr = tmp; |
|
} |
|
/* FALLTHROUGH */ |
|
case 'P': |
|
if (ptr == NULL) { |
|
xsnprintf(tmp, sizeof tmp, "%u", |
|
window_pane_index(wl->window, |
|
wl->window->active)); |
|
ptr = tmp; |
|
} |
|
/* FALLTHROUGH */ |
|
case 'S': |
|
if (ptr == NULL) |
|
ptr = s->name; |
|
/* FALLTHROUGH */ |
|
case 'T': |
|
if (ptr == NULL) |
|
ptr = wl->window->active->base.title; |
|
/* FALLTHROUGH */ |
|
case 'W': |
|
if (ptr == NULL) |
|
ptr = wl->window->name; |
|
len = strlen(ptr); |
|
if ((size_t) n < len) |
|
len = n; |
|
if (optr + len >= out + (sizeof out) - 1) |
|
break; |
|
while (len > 0 && *ptr != '\0') { |
|
*optr++ = *ptr++; |
|
len--; |
|
} |
|
break; |
|
case '[': |
|
/* |
|
* Embedded style, handled at display time. |
|
* Leave present and skip input until ]. |
|
*/ |
|
*optr++ = '#'; |
|
|
|
iptr--; /* include [ */ |
|
while (*iptr != ']' && *iptr != '\0') { |
|
if (optr >= out + (sizeof out) - 1) |
|
break; |
|
*optr++ = *iptr++; |
|
} |
|
break; |
|
case '#': |
|
*optr++ = '#'; |
|
break; |
|
} |
|
if (savedptr != NULL) { |
|
xfree(savedptr); |
|
savedptr = NULL; |
|
} |
|
break; |
|
default: |
|
*optr++ = ch; |
*optr++ = ch; |
break; |
continue; |
} |
} |
|
status_replace1(c, &iptr, &optr, out, sizeof out, jobsflag); |
} |
} |
*optr = '\0'; |
*optr = '\0'; |
|
|
return (xstrdup(out)); |
return (xstrdup(out)); |
} |
} |
|
|
|
/* Figure out job name and get its result, starting it off if necessary. */ |
char * |
char * |
status_job(struct client *c, char **iptr) |
status_job(struct client *c, char **iptr) |
{ |
{ |
|
|
return (xstrdup(job->data)); |
return (xstrdup(job->data)); |
} |
} |
|
|
|
/* Job has finished: save its result. */ |
void |
void |
status_job_callback(struct job *job) |
status_job_callback(struct job *job) |
{ |
{ |
|
|
xfree(buf); |
xfree(buf); |
} |
} |
|
|
|
/* Calculate winlink status line entry width. */ |
size_t |
size_t |
status_width(struct winlink *wl) |
status_width(struct winlink *wl) |
{ |
{ |
return (xsnprintf(NULL, 0, "%d:%s ", wl->idx, wl->window->name)); |
return (xsnprintf(NULL, 0, "%d:%s ", wl->idx, wl->window->name)); |
} |
} |
|
|
|
/* Return winlink status line entry and adjust gc as necessary. */ |
char * |
char * |
status_print(struct session *s, struct winlink *wl, struct grid_cell *gc) |
status_print(struct session *s, struct winlink *wl, struct grid_cell *gc) |
{ |
{ |
|
|
return (text); |
return (text); |
} |
} |
|
|
|
/* Set a status line message. */ |
void printflike2 |
void printflike2 |
status_message_set(struct client *c, const char *fmt, ...) |
status_message_set(struct client *c, const char *fmt, ...) |
{ |
{ |
|
|
c->flags |= CLIENT_STATUS; |
c->flags |= CLIENT_STATUS; |
} |
} |
|
|
|
/* Clear status line message. */ |
void |
void |
status_message_clear(struct client *c) |
status_message_clear(struct client *c) |
{ |
{ |
|
|
screen_reinit(&c->status); |
screen_reinit(&c->status); |
} |
} |
|
|
|
/* Clear status line message after timer expires. */ |
void |
void |
status_message_callback(unused int fd, unused short event, void *data) |
status_message_callback(unused int fd, unused short event, void *data) |
{ |
{ |
|
|
return (1); |
return (1); |
} |
} |
|
|
|
/* Enable status line prompt. */ |
void |
void |
status_prompt_set(struct client *c, const char *msg, |
status_prompt_set(struct client *c, const char *msg, |
int (*callbackfn)(void *, const char *), void (*freefn)(void *), |
int (*callbackfn)(void *, const char *), void (*freefn)(void *), |
|
|
c->flags |= CLIENT_STATUS; |
c->flags |= CLIENT_STATUS; |
} |
} |
|
|
|
/* Remove status line prompt. */ |
void |
void |
status_prompt_clear(struct client *c) |
status_prompt_clear(struct client *c) |
{ |
{ |
|
|
screen_reinit(&c->status); |
screen_reinit(&c->status); |
} |
} |
|
|
|
/* Update status line prompt with a new prompt string. */ |
void |
void |
status_prompt_update(struct client *c, const char *msg) |
status_prompt_update(struct client *c, const char *msg) |
{ |
{ |