Created
July 15, 2014 07:31
-
-
Save staticfloat/9e58c9a479a9f541cc6c to your computer and use it in GitHub Desktop.
Enable tmux to expand special format codes like '#S' inside of shell command special sequences. E.g. let something like `#(echo #S)` work.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/status.c b/status.c | |
index deb1b60..175623d 100644 | |
--- a/status.c | |
+++ b/status.c | |
@@ -38,7 +38,7 @@ void status_job_free(void *); | |
void status_job_callback(struct job *); | |
char *status_print( | |
struct client *, struct winlink *, time_t, struct grid_cell *); | |
-void status_replace1(struct client *, char **, char **, char *, size_t, int); | |
+void status_replace1(struct client *, struct format_tree *, char **, char **, char *, size_t, int); | |
void status_message_callback(int, short, void *); | |
const char *status_prompt_up_history(u_int *); | |
@@ -360,13 +360,15 @@ out: | |
/* Replace a single special sequence (prefixed by #). */ | |
void | |
-status_replace1(struct client *c, char **iptr, char **optr, char *out, | |
+status_replace1(struct client *c, struct format_tree *ft, char **iptr, char **optr, char *out, | |
size_t outsize, int jobsflag) | |
{ | |
char ch, tmp[256], *ptr, *endptr; | |
size_t ptrlen; | |
long limit; | |
+ int lastesc; | |
+ lastesc = 0; | |
errno = 0; | |
limit = strtol(*iptr, &endptr, 10); | |
if ((limit == 0 && errno != EINVAL) || | |
@@ -383,8 +385,38 @@ status_replace1(struct client *c, char **iptr, char **optr, char *out, | |
ch = ')'; | |
goto skip_to; | |
} | |
- if ((ptr = status_find_job(c, iptr)) == NULL) | |
+ /* | |
+ * Before running the job, replace any special squences within it | |
+ * To do so, first search for closing brace: | |
+ */ | |
+ endptr = *iptr; | |
+ for (; *endptr != '\0'; endptr++) { | |
+ if (!lastesc && *endptr == ')') { | |
+ break; /* unescaped ) is the end */ | |
+ } | |
+ if (!lastesc && *endptr == '\\') { | |
+ lastesc = 1; | |
+ continue; /* skip \ if not escaped */ | |
+ } | |
+ lastesc = 0; | |
+ } | |
+ | |
+ /* Now that we have the end of this special sequence, zero it out */ | |
+ *endptr = '\0'; | |
+ | |
+ /* We now use format_expand to do the expansion pass over iptr */ | |
+ ptr = format_expand(ft, *iptr); | |
+ sprintf(tmp, "%s)", ptr); | |
+ free(ptr); | |
+ | |
+ /* We finally restore the closing parenthesis, and run the job */ | |
+ //*endptr = ')'; | |
+ ptr = &tmp[0]; | |
+ log_debug("Launching job: %s", ptr); | |
+ if ((ptr = status_find_job(c, &ptr)) == NULL) | |
return; | |
+ *iptr = endptr; | |
+ log_debug("Result: %s", ptr); | |
goto do_replace; | |
case '[': | |
/* | |
@@ -455,6 +487,16 @@ status_replace(struct client *c, struct session *s, struct winlink *wl, | |
iptr = in; | |
optr = out; | |
+ ft = format_create(); | |
+ if (c != NULL) | |
+ format_client(ft, c); | |
+ if (s != NULL) | |
+ format_session(ft, s); | |
+ if (s != NULL && wl != NULL) | |
+ format_winlink(ft, s, wl); | |
+ if (wp != NULL) | |
+ format_window_pane(ft, wp); | |
+ | |
while (*iptr != '\0') { | |
if (optr >= out + (sizeof out) - 1) | |
break; | |
@@ -464,19 +506,10 @@ status_replace(struct client *c, struct session *s, struct winlink *wl, | |
*optr++ = ch; | |
continue; | |
} | |
- status_replace1(c, &iptr, &optr, out, sizeof out, jobsflag); | |
+ status_replace1(c, ft, &iptr, &optr, out, sizeof out, jobsflag); | |
} | |
*optr = '\0'; | |
- ft = format_create(); | |
- if (c != NULL) | |
- format_client(ft, c); | |
- if (s != NULL) | |
- format_session(ft, s); | |
- if (s != NULL && wl != NULL) | |
- format_winlink(ft, s, wl); | |
- if (wp != NULL) | |
- format_window_pane(ft, wp); | |
expanded = format_expand(ft, out); | |
format_free(ft); | |
return (expanded); | |
@@ -529,7 +562,7 @@ status_find_job(struct client *c, char **iptr) | |
/* If not found at all, start the job and add to the tree. */ | |
if (so == NULL) { | |
- job_run(cmd, NULL, status_job_callback, status_job_free, c); | |
+ job_run(cmd, c->session, status_job_callback, status_job_free, c); | |
c->references++; | |
so = xmalloc(sizeof *so); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment