aboutsummaryrefslogtreecommitdiff
path: root/cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'cmd.c')
-rw-r--r--cmd.c186
1 files changed, 103 insertions, 83 deletions
diff --git a/cmd.c b/cmd.c
index 6869c12c..16a9eb98 100644
--- a/cmd.c
+++ b/cmd.c
@@ -112,6 +112,7 @@ const struct cmd_entry *cmd_table[] = {
&cmd_switch_client_entry,
&cmd_unbind_key_entry,
&cmd_unlink_window_entry,
+ &cmd_wait_for_entry,
NULL
};
@@ -121,13 +122,14 @@ struct session *cmd_choose_session(int);
struct client *cmd_choose_client(struct clients *);
struct client *cmd_lookup_client(const char *);
struct session *cmd_lookup_session(const char *, int *);
+struct session *cmd_lookup_session_id(const char *);
struct winlink *cmd_lookup_window(struct session *, const char *, int *);
int cmd_lookup_index(struct session *, const char *, int *);
struct window_pane *cmd_lookup_paneid(const char *);
struct winlink *cmd_lookup_winlink_windowid(struct session *, const char *);
struct window *cmd_lookup_windowid(const char *);
-struct session *cmd_window_session(struct cmd_ctx *,
- struct window *, struct winlink **);
+struct session *cmd_window_session(struct cmd_q *, struct window *,
+ struct winlink **);
struct winlink *cmd_find_window_offset(const char *, struct session *, int *);
int cmd_find_index_offset(const char *, struct session *, int *);
struct window_pane *cmd_find_pane_offset(const char *, struct winlink *);
@@ -205,7 +207,7 @@ cmd_free_argv(int argc, char **argv)
}
struct cmd *
-cmd_parse(int argc, char **argv, char **cause)
+cmd_parse(int argc, char **argv, const char *file, u_int line, char **cause)
{
const struct cmd_entry **entryp, *entry;
struct cmd *cmd;
@@ -255,9 +257,14 @@ cmd_parse(int argc, char **argv, char **cause)
if (entry->check != NULL && entry->check(args) != 0)
goto usage;
- cmd = xmalloc(sizeof *cmd);
+ cmd = xcalloc(1, sizeof *cmd);
cmd->entry = entry;
cmd->args = args;
+
+ if (file != NULL)
+ cmd->file = xstrdup(file);
+ cmd->line = line;
+
return (cmd);
ambiguous:
@@ -281,19 +288,6 @@ usage:
return (NULL);
}
-enum cmd_retval
-cmd_exec(struct cmd *cmd, struct cmd_ctx *ctx)
-{
- return (cmd->entry->exec(cmd, ctx));
-}
-
-void
-cmd_free(struct cmd *cmd)
-{
- args_free(cmd->args);
- free(cmd);
-}
-
size_t
cmd_print(struct cmd *cmd, char *buf, size_t len)
{
@@ -319,31 +313,33 @@ cmd_print(struct cmd *cmd, char *buf, size_t len)
* session from all sessions.
*/
struct session *
-cmd_current_session(struct cmd_ctx *ctx, int prefer_unattached)
+cmd_current_session(struct cmd_q *cmdq, int prefer_unattached)
{
- struct msg_command_data *data = ctx->msgdata;
- struct client *c = ctx->cmdclient;
+ struct msg_command_data *data = cmdq->msgdata;
+ struct client *c = cmdq->client;
struct session *s;
struct sessionslist ss;
struct winlink *wl;
struct window_pane *wp;
+ const char *path;
int found;
- if (ctx->curclient != NULL && ctx->curclient->session != NULL)
- return (ctx->curclient->session);
+ if (c != NULL && c->session != NULL)
+ return (c->session);
/*
- * If the name of the calling client's pty is know, build a list of the
- * sessions that contain it and if any choose either the first or the
- * newest.
+ * If the name of the calling client's pty is known, build a list of
+ * the sessions that contain it and if any choose either the first or
+ * the newest.
*/
- if (c != NULL && c->tty.path != NULL) {
+ path = c == NULL ? NULL : c->tty.path;
+ if (path != NULL) {
ARRAY_INIT(&ss);
RB_FOREACH(s, sessions, &sessions) {
found = 0;
RB_FOREACH(wl, winlinks, &s->windows) {
TAILQ_FOREACH(wp, &wl->window->panes, entry) {
- if (strcmp(wp->tty, c->tty.path) == 0) {
+ if (strcmp(wp->tty, path) == 0) {
found = 1;
break;
}
@@ -362,8 +358,8 @@ cmd_current_session(struct cmd_ctx *ctx, int prefer_unattached)
}
/* Use the session from the TMUX environment variable. */
- if (data != NULL && data->pid == getpid() && data->idx != -1) {
- s = session_find_by_index(data->idx);
+ if (data != NULL && data->pid == getpid() && data->session_id != -1) {
+ s = session_find_by_id(data->session_id);
if (s != NULL)
return (s);
}
@@ -434,21 +430,21 @@ cmd_choose_session_list(struct sessionslist *ss)
* then of all clients.
*/
struct client *
-cmd_current_client(struct cmd_ctx *ctx)
+cmd_current_client(struct cmd_q *cmdq)
{
struct session *s;
struct client *c;
struct clients cc;
u_int i;
- if (ctx->curclient != NULL)
- return (ctx->curclient);
+ if (cmdq->client != NULL && cmdq->client->session != NULL)
+ return (cmdq->client);
/*
* No current client set. Find the current session and return the
* newest of its clients.
*/
- s = cmd_current_session(ctx, 0);
+ s = cmd_current_session(cmdq, 0);
if (s != NULL && !(s->flags & SESSION_UNATTACHED)) {
ARRAY_INIT(&cc);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
@@ -493,15 +489,19 @@ cmd_choose_client(struct clients *cc)
/* Find the target client or report an error and return NULL. */
struct client *
-cmd_find_client(struct cmd_ctx *ctx, const char *arg)
+cmd_find_client(struct cmd_q *cmdq, const char *arg, int quiet)
{
struct client *c;
char *tmparg;
size_t arglen;
/* A NULL argument means the current client. */
- if (arg == NULL)
- return (cmd_current_client(ctx));
+ if (arg == NULL) {
+ c = cmd_current_client(cmdq);
+ if (c == NULL && !quiet)
+ cmdq_error(cmdq, "no clients");
+ return (c);
+ }
tmparg = xstrdup(arg);
/* Trim a single trailing colon if any. */
@@ -513,8 +513,8 @@ cmd_find_client(struct cmd_ctx *ctx, const char *arg)
c = cmd_lookup_client(tmparg);
/* If no client found, report an error. */
- if (c == NULL)
- ctx->error(ctx, "client not found: %s", tmparg);
+ if (c == NULL && !quiet)
+ cmdq_error(cmdq, "client not found: %s", tmparg);
free(tmparg);
return (c);
@@ -533,7 +533,7 @@ cmd_lookup_client(const char *name)
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
- if (c == NULL || c->session == NULL)
+ if (c == NULL || c->session == NULL || c->tty.path == NULL)
continue;
path = c->tty.path;
@@ -551,6 +551,21 @@ cmd_lookup_client(const char *name)
return (NULL);
}
+/* Find the target session or report an error and return NULL. */
+struct session *
+cmd_lookup_session_id(const char *arg)
+{
+ char *endptr;
+ long id;
+
+ if (arg[0] != '$')
+ return (NULL);
+ id = strtol(arg + 1, &endptr, 10);
+ if (arg[1] != '\0' && *endptr == '\0')
+ return (session_find_by_id(id));
+ return (NULL);
+}
+
/* Lookup a session by name. If no session is found, NULL is returned. */
struct session *
cmd_lookup_session(const char *name, int *ambiguous)
@@ -559,6 +574,10 @@ cmd_lookup_session(const char *name, int *ambiguous)
*ambiguous = 0;
+ /* Look for $id first. */
+ if ((s = cmd_lookup_session_id(name)) != NULL)
+ return (s);
+
/*
* Look for matches. First look for exact matches - session names must
* be unique so an exact match can't be ambigious and can just be
@@ -716,14 +735,14 @@ cmd_lookup_windowid(const char *arg)
/* Find session and winlink for window. */
struct session *
-cmd_window_session(struct cmd_ctx *ctx, struct window *w, struct winlink **wlp)
+cmd_window_session(struct cmd_q *cmdq, struct window *w, struct winlink **wlp)
{
struct session *s;
struct sessionslist ss;
struct winlink *wl;
/* If this window is in the current session, return that winlink. */
- s = cmd_current_session(ctx, 0);
+ s = cmd_current_session(cmdq, 0);
if (s != NULL) {
wl = winlink_find_by_window(&s->windows, w);
if (wl != NULL) {
@@ -748,7 +767,7 @@ cmd_window_session(struct cmd_ctx *ctx, struct window *w, struct winlink **wlp)
/* Find the target session or report an error and return NULL. */
struct session *
-cmd_find_session(struct cmd_ctx *ctx, const char *arg, int prefer_unattached)
+cmd_find_session(struct cmd_q *cmdq, const char *arg, int prefer_unattached)
{
struct session *s;
struct window_pane *wp;
@@ -760,13 +779,13 @@ cmd_find_session(struct cmd_ctx *ctx, const char *arg, int prefer_unattached)
/* A NULL argument means the current session. */
if (arg == NULL)
- return (cmd_current_session(ctx, prefer_unattached));
+ return (cmd_current_session(cmdq, prefer_unattached));
/* Lookup as pane id or window id. */
if ((wp = cmd_lookup_paneid(arg)) != NULL)
- return (cmd_window_session(ctx, wp->window, NULL));
+ return (cmd_window_session(cmdq, wp->window, NULL));
if ((w = cmd_lookup_windowid(arg)) != NULL)
- return (cmd_window_session(ctx, w, NULL));
+ return (cmd_window_session(cmdq, w, NULL));
/* Trim a single trailing colon if any. */
tmparg = xstrdup(arg);
@@ -777,7 +796,7 @@ cmd_find_session(struct cmd_ctx *ctx, const char *arg, int prefer_unattached)
/* An empty session name is the current session. */
if (*tmparg == '\0') {
free(tmparg);
- return (cmd_current_session(ctx, prefer_unattached));
+ return (cmd_current_session(cmdq, prefer_unattached));
}
/* Find the session, if any. */
@@ -790,9 +809,9 @@ cmd_find_session(struct cmd_ctx *ctx, const char *arg, int prefer_unattached)
/* If no session found, report an error. */
if (s == NULL) {
if (ambiguous)
- ctx->error(ctx, "more than one session: %s", tmparg);
+ cmdq_error(cmdq, "more than one session: %s", tmparg);
else
- ctx->error(ctx, "session not found: %s", tmparg);
+ cmdq_error(cmdq, "session not found: %s", tmparg);
}
free(tmparg);
@@ -801,7 +820,7 @@ cmd_find_session(struct cmd_ctx *ctx, const char *arg, int prefer_unattached)
/* Find the target session and window or report an error and return NULL. */
struct winlink *
-cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp)
+cmd_find_window(struct cmd_q *cmdq, const char *arg, struct session **sp)
{
struct session *s;
struct winlink *wl;
@@ -814,8 +833,8 @@ cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp)
* Find the current session. There must always be a current session, if
* it can't be found, report an error.
*/
- if ((s = cmd_current_session(ctx, 0)) == NULL) {
- ctx->error(ctx, "can't establish current session");
+ if ((s = cmd_current_session(cmdq, 0)) == NULL) {
+ cmdq_error(cmdq, "can't establish current session");
return (NULL);
}
@@ -828,7 +847,7 @@ cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp)
/* Lookup as pane id. */
if ((wp = cmd_lookup_paneid(arg)) != NULL) {
- s = cmd_window_session(ctx, wp->window, &wl);
+ s = cmd_window_session(cmdq, wp->window, &wl);
if (sp != NULL)
*sp = s;
return (wl);
@@ -909,17 +928,17 @@ lookup_session:
no_session:
if (ambiguous)
- ctx->error(ctx, "multiple sessions: %s", arg);
+ cmdq_error(cmdq, "multiple sessions: %s", arg);
else
- ctx->error(ctx, "session not found: %s", arg);
+ cmdq_error(cmdq, "session not found: %s", arg);
free(sessptr);
return (NULL);
not_found:
if (ambiguous)
- ctx->error(ctx, "multiple windows: %s", arg);
+ cmdq_error(cmdq, "multiple windows: %s", arg);
else
- ctx->error(ctx, "window not found: %s", arg);
+ cmdq_error(cmdq, "window not found: %s", arg);
free(sessptr);
return (NULL);
}
@@ -951,7 +970,7 @@ cmd_find_window_offset(const char *winptr, struct session *s, int *ambiguous)
* example if it is going to be created).
*/
int
-cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp)
+cmd_find_index(struct cmd_q *cmdq, const char *arg, struct session **sp)
{
struct session *s;
struct winlink *wl;
@@ -963,8 +982,8 @@ cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp)
* Find the current session. There must always be a current session, if
* it can't be found, report an error.
*/
- if ((s = cmd_current_session(ctx, 0)) == NULL) {
- ctx->error(ctx, "can't establish current session");
+ if ((s = cmd_current_session(cmdq, 0)) == NULL) {
+ cmdq_error(cmdq, "can't establish current session");
return (-2);
}
@@ -1047,25 +1066,25 @@ lookup_session:
no_session:
if (ambiguous)
- ctx->error(ctx, "multiple sessions: %s", arg);
+ cmdq_error(cmdq, "multiple sessions: %s", arg);
else
- ctx->error(ctx, "session not found: %s", arg);
+ cmdq_error(cmdq, "session not found: %s", arg);
free(sessptr);
return (-2);
invalid_index:
if (ambiguous)
goto not_found;
- ctx->error(ctx, "invalid index: %s", arg);
+ cmdq_error(cmdq, "invalid index: %s", arg);
free(sessptr);
return (-2);
not_found:
if (ambiguous)
- ctx->error(ctx, "multiple windows: %s", arg);
+ cmdq_error(cmdq, "multiple windows: %s", arg);
else
- ctx->error(ctx, "window not found: %s", arg);
+ cmdq_error(cmdq, "window not found: %s", arg);
free(sessptr);
return (-2);
}
@@ -1102,7 +1121,7 @@ cmd_find_index_offset(const char *winptr, struct session *s, int *ambiguous)
* such as mysession:mywindow.0.
*/
struct winlink *
-cmd_find_pane(struct cmd_ctx *ctx,
+cmd_find_pane(struct cmd_q *cmdq,
const char *arg, struct session **sp, struct window_pane **wpp)
{
struct session *s;
@@ -1112,8 +1131,8 @@ cmd_find_pane(struct cmd_ctx *ctx,
u_int idx;
/* Get the current session. */
- if ((s = cmd_current_session(ctx, 0)) == NULL) {
- ctx->error(ctx, "can't establish current session");
+ if ((s = cmd_current_session(cmdq, 0)) == NULL) {
+ cmdq_error(cmdq, "can't establish current session");
return (NULL);
}
if (sp != NULL)
@@ -1127,7 +1146,7 @@ cmd_find_pane(struct cmd_ctx *ctx,
/* Lookup as pane id. */
if ((*wpp = cmd_lookup_paneid(arg)) != NULL) {
- s = cmd_window_session(ctx, (*wpp)->window, &wl);
+ s = cmd_window_session(cmdq, (*wpp)->window, &wl);
if (sp != NULL)
*sp = s;
return (wl);
@@ -1142,7 +1161,7 @@ cmd_find_pane(struct cmd_ctx *ctx,
winptr[period - arg] = '\0';
if (*winptr == '\0')
wl = s->curw;
- else if ((wl = cmd_find_window(ctx, winptr, sp)) == NULL)
+ else if ((wl = cmd_find_window(cmdq, winptr, sp)) == NULL)
goto error;
/* Find the pane section and look it up. */
@@ -1166,7 +1185,7 @@ cmd_find_pane(struct cmd_ctx *ctx,
lookup_string:
/* Try pane string description. */
if ((*wpp = window_find_string(wl->window, paneptr)) == NULL) {
- ctx->error(ctx, "can't find pane: %s", paneptr);
+ cmdq_error(cmdq, "can't find pane: %s", paneptr);
goto error;
}
@@ -1191,7 +1210,7 @@ lookup_window:
return (s->curw);
/* Try as a window and use the active pane. */
- if ((wl = cmd_find_window(ctx, arg, sp)) != NULL)
+ if ((wl = cmd_find_window(cmdq, arg, sp)) != NULL)
*wpp = wl->window->active;
return (wl);
@@ -1221,14 +1240,14 @@ cmd_find_pane_offset(const char *paneptr, struct winlink *wl)
/* Replace the first %% or %idx in template by s. */
char *
-cmd_template_replace(char *template, const char *s, int idx)
+cmd_template_replace(const char *template, const char *s, int idx)
{
- char ch;
- char *buf, *ptr;
- int replaced;
- size_t len;
+ char ch, *buf;
+ const char *ptr;
+ int replaced;
+ size_t len;
- if (strstr(template, "%") == NULL)
+ if (strchr(template, '%') == NULL)
return (xstrdup(template));
buf = xmalloc(1);
@@ -1269,8 +1288,9 @@ cmd_template_replace(char *template, const char *s, int idx)
* directory.
*/
const char *
-cmd_get_default_path(struct cmd_ctx *ctx, const char *cwd)
+cmd_get_default_path(struct cmd_q *cmdq, const char *cwd)
{
+ struct client *c = cmdq->client;
struct session *s;
struct environ_entry *envent;
const char *root;
@@ -1280,7 +1300,7 @@ cmd_get_default_path(struct cmd_ctx *ctx, const char *cwd)
size_t skip;
static char path[MAXPATHLEN];
- if ((s = cmd_current_session(ctx, 0)) == NULL)
+ if ((s = cmd_current_session(cmdq, 0)) == NULL)
return (NULL);
if (cwd == NULL)
@@ -1310,10 +1330,10 @@ cmd_get_default_path(struct cmd_ctx *ctx, const char *cwd)
return (cwd);
} else {
/* Empty or relative path. */
- if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL)
- root = ctx->cmdclient->cwd;
- else if (ctx->curclient != NULL && s->curw != NULL)
- root = osdep_get_cwd(s->curw->window->active->fd);
+ if (c != NULL && c->session == NULL && c->cwd != NULL)
+ root = c->cwd;
+ else if (s->curw != NULL)
+ root = get_proc_cwd(s->curw->window->active->fd);
else
return (s->cwd);
skip = 0;