Skip to content

Instantly share code, notes, and snippets.

@staticfloat
Created July 15, 2014 07:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save staticfloat/9e58c9a479a9f541cc6c to your computer and use it in GitHub Desktop.
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.
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