Add a command queue to standardize and simplify commands that call other

commands and allow a command to block execution of subsequent
commands. This allows run-shell and if-shell to be synchronous which has
been much requested.

Each client has a default command queue and commands are consumed one at
a time from it. A command may suspend execution from the queue by
returning CMD_RETURN_WAIT and then resume it by calling cmd_continue() -
for example run-shell does this from the callback that is fired after
the job is freed.

When the command queue becomes empty, command clients are automatically
exited (unless attaching). A callback is also fired - this is used for
nested commands in, for example, if-shell which can block execution of
the client's cmdq until a new cmdq becomes empty.

Also merge all the old error/info/print functions together and lose the
old curclient/cmdclient distinction - a cmdq is bound to one client (or
none if in the configuration file), this is a command client if
c->session is NULL otherwise an attached client.
This commit is contained in:
Nicholas Marriott
2013-03-24 09:54:10 +00:00
parent 66edb3392b
commit 20636d956d
84 changed files with 1240 additions and 1187 deletions

View File

@ -27,13 +27,13 @@
* List panes on given window.
*/
enum cmd_retval cmd_list_panes_exec(struct cmd *, struct cmd_ctx *);
enum cmd_retval cmd_list_panes_exec(struct cmd *, struct cmd_q *);
void cmd_list_panes_server(struct cmd *, struct cmd_ctx *);
void cmd_list_panes_server(struct cmd *, struct cmd_q *);
void cmd_list_panes_session(
struct cmd *, struct session *, struct cmd_ctx *, int);
struct cmd *, struct session *, struct cmd_q *, int);
void cmd_list_panes_window(struct cmd *,
struct session *, struct winlink *, struct cmd_ctx *, int);
struct session *, struct winlink *, struct cmd_q *, int);
const struct cmd_entry cmd_list_panes_entry = {
"list-panes", "lsp",
@ -46,51 +46,51 @@ const struct cmd_entry cmd_list_panes_entry = {
};
enum cmd_retval
cmd_list_panes_exec(struct cmd *self, struct cmd_ctx *ctx)
cmd_list_panes_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct session *s;
struct winlink *wl;
if (args_has(args, 'a'))
cmd_list_panes_server(self, ctx);
cmd_list_panes_server(self, cmdq);
else if (args_has(args, 's')) {
s = cmd_find_session(ctx, args_get(args, 't'), 0);
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
cmd_list_panes_session(self, s, ctx, 1);
cmd_list_panes_session(self, s, cmdq, 1);
} else {
wl = cmd_find_window(ctx, args_get(args, 't'), &s);
wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
if (wl == NULL)
return (CMD_RETURN_ERROR);
cmd_list_panes_window(self, s, wl, ctx, 0);
cmd_list_panes_window(self, s, wl, cmdq, 0);
}
return (CMD_RETURN_NORMAL);
}
void
cmd_list_panes_server(struct cmd *self, struct cmd_ctx *ctx)
cmd_list_panes_server(struct cmd *self, struct cmd_q *cmdq)
{
struct session *s;
RB_FOREACH(s, sessions, &sessions)
cmd_list_panes_session(self, s, ctx, 2);
cmd_list_panes_session(self, s, cmdq, 2);
}
void
cmd_list_panes_session(
struct cmd *self, struct session *s, struct cmd_ctx *ctx, int type)
struct cmd *self, struct session *s, struct cmd_q *cmdq, int type)
{
struct winlink *wl;
RB_FOREACH(wl, winlinks, &s->windows)
cmd_list_panes_window(self, s, wl, ctx, type);
cmd_list_panes_window(self, s, wl, cmdq, type);
}
void
cmd_list_panes_window(struct cmd *self,
struct session *s, struct winlink *wl, struct cmd_ctx *ctx, int type)
struct session *s, struct winlink *wl, struct cmd_q *cmdq, int type)
{
struct args *args = self->args;
struct window_pane *wp;
@ -135,7 +135,7 @@ cmd_list_panes_window(struct cmd *self,
format_window_pane(ft, wp);
line = format_expand(ft, template);
ctx->print(ctx, "%s", line);
cmdq_print(cmdq, "%s", line);
free(line);
format_free(ft);