summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--cfg.c126
-rw-r--r--client.c3
-rw-r--r--cmd-attach-session.c43
-rw-r--r--cmd-bind-key.c25
-rw-r--r--cmd-break-pane.c12
-rw-r--r--cmd-capture-pane.c19
-rw-r--r--cmd-choose-buffer.c10
-rw-r--r--cmd-choose-client.c12
-rw-r--r--cmd-choose-list.c10
-rw-r--r--cmd-choose-tree.c10
-rw-r--r--cmd-clear-history.c6
-rw-r--r--cmd-clock-mode.c6
-rw-r--r--cmd-command-prompt.c17
-rw-r--r--cmd-confirm-before.c44
-rw-r--r--cmd-copy-mode.c6
-rw-r--r--cmd-delete-buffer.c8
-rw-r--r--cmd-detach-client.c10
-rw-r--r--cmd-display-message.c16
-rw-r--r--cmd-display-panes.c6
-rw-r--r--cmd-find-window.c12
-rw-r--r--cmd-has-session.c6
-rw-r--r--cmd-if-shell.c77
-rw-r--r--cmd-join-pane.c24
-rw-r--r--cmd-kill-pane.c6
-rw-r--r--cmd-kill-server.c4
-rw-r--r--cmd-kill-session.c6
-rw-r--r--cmd-kill-window.c6
-rw-r--r--cmd-link-window.c10
-rw-r--r--cmd-list-buffers.c6
-rw-r--r--cmd-list-clients.c8
-rw-r--r--cmd-list-commands.c8
-rw-r--r--cmd-list-keys.c16
-rw-r--r--cmd-list-panes.c32
-rw-r--r--cmd-list-sessions.c6
-rw-r--r--cmd-list-windows.c22
-rw-r--r--cmd-list.c73
-rw-r--r--cmd-load-buffer.c30
-rw-r--r--cmd-lock-server.c10
-rw-r--r--cmd-move-window.c12
-rw-r--r--cmd-new-session.c148
-rw-r--r--cmd-new-window.c20
-rw-r--r--cmd-paste-buffer.c10
-rw-r--r--cmd-pipe-pane.c12
-rw-r--r--cmd-queue.c258
-rw-r--r--cmd-refresh-client.c14
-rw-r--r--cmd-rename-session.c10
-rw-r--r--cmd-rename-window.c6
-rw-r--r--cmd-resize-pane.c12
-rw-r--r--cmd-respawn-pane.c10
-rw-r--r--cmd-respawn-window.c10
-rw-r--r--cmd-rotate-window.c6
-rw-r--r--cmd-run-shell.c45
-rw-r--r--cmd-save-buffer.c136
-rw-r--r--cmd-select-layout.c14
-rw-r--r--cmd-select-pane.c14
-rw-r--r--cmd-select-window.c16
-rw-r--r--cmd-send-keys.c25
-rw-r--r--cmd-server-info.c54
-rw-r--r--cmd-set-buffer.c8
-rw-r--r--cmd-set-environment.c16
-rw-r--r--cmd-show-environment.c16
-rw-r--r--cmd-show-messages.c8
-rw-r--r--cmd-show-options.c42
-rw-r--r--cmd-source-file.c84
-rw-r--r--cmd-split-window.c16
-rw-r--r--cmd-start-server.c4
-rw-r--r--cmd-string.c5
-rw-r--r--cmd-suspend-client.c6
-rw-r--r--cmd-swap-pane.c8
-rw-r--r--cmd-swap-window.c10
-rw-r--r--cmd-switch-client.c18
-rw-r--r--cmd-unbind-key.c14
-rw-r--r--cmd-unlink-window.c8
-rw-r--r--cmd.c156
-rw-r--r--control.c51
-rw-r--r--format.c6
-rw-r--r--key-bindings.c79
-rw-r--r--server-client.c83
-rw-r--r--server-fn.c4
-rw-r--r--server.c42
-rw-r--r--tmux.c2
-rw-r--r--tmux.h136
-rw-r--r--window-choose.c15
84 files changed, 1238 insertions, 1185 deletions
diff --git a/Makefile b/Makefile
index cebcac8e..f78b1615 100644
--- a/Makefile
+++ b/Makefile
@@ -60,12 +60,10 @@ SRCS= arguments.c \
cmd-select-pane.c \
cmd-select-window.c \
cmd-send-keys.c \
- cmd-send-prefix.c \
cmd-server-info.c \
cmd-set-buffer.c \
cmd-set-environment.c \
cmd-set-option.c \
- cmd-show-buffer.c \
cmd-show-environment.c \
cmd-show-messages.c \
cmd-show-options.c \
@@ -80,6 +78,7 @@ SRCS= arguments.c \
cmd-unbind-key.c \
cmd-unlink-window.c \
cmd.c \
+ cmd-queue.c \
colour.c \
control.c \
control-notify.c \
diff --git a/cfg.c b/cfg.c
index b7b0ec78..e4069d68 100644
--- a/cfg.c
+++ b/cfg.c
@@ -27,80 +27,27 @@
#include "tmux.h"
-/*
- * Config file parser. Pretty quick and simple, each line is parsed into a
- * argv array and executed as a command.
- */
-
-void printflike2 cfg_print(struct cmd_ctx *, const char *, ...);
-void printflike2 cfg_error(struct cmd_ctx *, const char *, ...);
-
-char *cfg_cause;
+struct cmd_q *cfg_cmd_q;
int cfg_finished;
-int cfg_references;
+int cfg_references;
struct causelist cfg_causes;
-void printflike2
-cfg_print(unused struct cmd_ctx *ctx, unused const char *fmt, ...)
-{
-}
-
-void printflike2
-cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- xvasprintf(&cfg_cause, fmt, ap);
- va_end(ap);
-}
-
-void printflike2
-cfg_add_cause(struct causelist *causes, const char *fmt, ...)
-{
- char *cause;
- va_list ap;
-
- va_start(ap, fmt);
- xvasprintf(&cause, fmt, ap);
- va_end(ap);
-
- ARRAY_ADD(causes, cause);
-}
-
-/*
- * Load configuration file. Returns -1 for an error with a list of messages in
- * causes. Note that causes must be initialised by the caller!
- */
-enum cmd_retval
-load_cfg(const char *path, struct cmd_ctx *ctx, struct causelist *causes)
+int
+load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
{
FILE *f;
- u_int n;
- char *buf, *copy, *line, *cause;
+ u_int n, found;
+ char *buf, *copy, *line, *cause1, *msg;
size_t len, oldlen;
struct cmd_list *cmdlist;
- enum cmd_retval retval;
if ((f = fopen(path, "rb")) == NULL) {
- cfg_add_cause(causes, "%s: %s", path, strerror(errno));
- return (CMD_RETURN_ERROR);
- }
-
- cfg_references++;
-
- if (ctx != NULL)
- cmd_ref_ctx(ctx);
- else {
- ctx = cmd_get_ctx(NULL, NULL);
- ctx->error = cfg_error;
- ctx->print = cfg_print;
- ctx->info = cfg_print;
+ xasprintf(cause, "%s: %s", path, strerror(errno));
+ return (-1);
}
- n = 0;
+ n = found = 0;
line = NULL;
- retval = CMD_RETURN_NORMAL;
while ((buf = fgetln(f, &len))) {
/* Trim \n. */
if (buf[len - 1] == '\n')
@@ -142,53 +89,47 @@ load_cfg(const char *path, struct cmd_ctx *ctx, struct causelist *causes)
continue;
}
- if (cmd_string_parse(buf, &cmdlist, &cause) != 0) {
+ /* Parse and run the command. */
+ if (cmd_string_parse(buf, &cmdlist, path, n, &cause1) != 0) {
free(copy);
- if (cause == NULL)
+ if (cause1 == NULL)
continue;
- cfg_add_cause(causes, "%s: %u: %s", path, n, cause);
- free(cause);
+ xasprintf(&msg, "%s:%u: %s", path, n, cause1);
+ ARRAY_ADD(&cfg_causes, msg);
+ free(cause1);
continue;
}
free(copy);
+
if (cmdlist == NULL)
continue;
-
- cfg_cause = NULL;
- switch (cmd_list_exec(cmdlist, ctx)) {
- case CMD_RETURN_YIELD:
- if (retval != CMD_RETURN_ATTACH)
- retval = CMD_RETURN_YIELD;
- break;
- case CMD_RETURN_ATTACH:
- retval = CMD_RETURN_ATTACH;
- break;
- case CMD_RETURN_ERROR:
- case CMD_RETURN_NORMAL:
- break;
- }
+ cmdq_append(cmdq, cmdlist);
cmd_list_free(cmdlist);
- if (cfg_cause != NULL) {
- cfg_add_cause(causes, "%s: %d: %s", path, n, cfg_cause);
- free(cfg_cause);
- }
+ found++;
}
- if (line != NULL) {
- cfg_add_cause(causes,
- "%s: %d: line continuation at end of file", path, n);
+ if (line != NULL)
free(line);
- }
fclose(f);
- cmd_free_ctx(ctx);
+ return (found);
+}
+
+void
+cfg_default_done(unused struct cmd_q *cmdq)
+{
+ if (--cfg_references != 0)
+ return;
+ cfg_finished = 1;
- cfg_references--;
+ if (!RB_EMPTY(&sessions))
+ cfg_show_causes(RB_MIN(sessions, &sessions));
- return (retval);
+ cmdq_free(cfg_cmd_q);
+ cfg_cmd_q = NULL;
}
void
-show_cfg_causes(struct session *s)
+cfg_show_causes(struct session *s)
{
struct window_pane *wp;
char *cause;
@@ -196,7 +137,6 @@ show_cfg_causes(struct session *s)
if (s == NULL || ARRAY_EMPTY(&cfg_causes))
return;
-
wp = s->curw->window->active;
window_pane_set_mode(wp, &window_copy_mode);
diff --git a/client.c b/client.c
index 92c3fca3..8693afeb 100644
--- a/client.c
+++ b/client.c
@@ -188,7 +188,8 @@ client_main(int argc, char **argv, int flags)
* later in server) but it is necessary to get the start server
* flag.
*/
- if ((cmdlist = cmd_list_parse(argc, argv, &cause)) == NULL) {
+ cmdlist = cmd_list_parse(argc, argv, NULL, 0, &cause);
+ if (cmdlist == NULL) {
fprintf(stderr, "%s\n", cause);
return (1);
}
diff --git a/cmd-attach-session.c b/cmd-attach-session.c
index 30451389..0298dda1 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -26,7 +26,7 @@
* Attach existing session to the current terminal.
*/
-enum cmd_retval cmd_attach_session_exec(struct cmd *, struct cmd_ctx *);
+enum cmd_retval cmd_attach_session_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_attach_session_entry = {
"attach-session", "attach",
@@ -39,7 +39,7 @@ const struct cmd_entry cmd_attach_session_entry = {
};
enum cmd_retval
-cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
+cmd_attach_session_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct session *s;
@@ -49,17 +49,17 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
u_int i;
if (RB_EMPTY(&sessions)) {
- ctx->error(ctx, "no sessions");
+ cmdq_error(cmdq, "no sessions");
return (CMD_RETURN_ERROR);
}
- if ((s = cmd_find_session(ctx, args_get(args, 't'), 1)) == NULL)
+ if ((s = cmd_find_session(cmdq, args_get(args, 't'), 1)) == NULL)
return (CMD_RETURN_ERROR);
- if (ctx->cmdclient == NULL && ctx->curclient == NULL)
+ if (cmdq->client == NULL)
return (CMD_RETURN_NORMAL);
- if (ctx->cmdclient == NULL) {
+ if (cmdq->client->session != NULL) {
if (args_has(self->args, 'd')) {
/*
* Can't use server_write_session in case attaching to
@@ -69,43 +69,44 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session != s)
continue;
- if (c == ctx->curclient)
+ if (c == cmdq->client)
continue;
server_write_client(c, MSG_DETACH, NULL, 0);
}
}
- ctx->curclient->session = s;
- notify_attached_session_changed(ctx->curclient);
+ cmdq->client->session = s;
+ notify_attached_session_changed(cmdq->client);
session_update_activity(s);
- server_redraw_client(ctx->curclient);
+ server_redraw_client(cmdq->client);
s->curw->flags &= ~WINLINK_ALERTFLAGS;
} else {
- if (server_client_open(ctx->cmdclient, s, &cause) != 0) {
- ctx->error(ctx, "open terminal failed: %s", cause);
+ if (server_client_open(cmdq->client, s, &cause) != 0) {
+ cmdq_error(cmdq, "open terminal failed: %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
if (args_has(self->args, 'r'))
- ctx->cmdclient->flags |= CLIENT_READONLY;
+ cmdq->client->flags |= CLIENT_READONLY;
if (args_has(self->args, 'd'))
server_write_session(s, MSG_DETACH, NULL, 0);
- ctx->cmdclient->session = s;
- notify_attached_session_changed(ctx->cmdclient);
- session_update_activity(s);
- server_write_ready(ctx->cmdclient);
-
update = options_get_string(&s->options, "update-environment");
- environ_update(update, &ctx->cmdclient->environ, &s->environ);
+ environ_update(update, &cmdq->client->environ, &s->environ);
- server_redraw_client(ctx->cmdclient);
+ cmdq->client->session = s;
+ notify_attached_session_changed(cmdq->client);
+ session_update_activity(s);
+ server_redraw_client(cmdq->client);
s->curw->flags &= ~WINLINK_ALERTFLAGS;
+
+ server_write_ready(cmdq->client);
+ cmdq->client_exit = 0;
}
recalculate_sizes();
server_update_socket();
- return (CMD_RETURN_ATTACH);
+ return (CMD_RETURN_NORMAL);
}
diff --git a/cmd-bind-key.c b/cmd-bind-key.c
index 086ac4ec..d9b65bec 100644
--- a/cmd-bind-key.c
+++ b/cmd-bind-key.c
@@ -28,9 +28,9 @@
*/
enum cmd_retval cmd_bind_key_check(struct args *);
-enum cmd_retval cmd_bind_key_exec(struct cmd *, struct cmd_ctx *);
+enum cmd_retval cmd_bind_key_exec(struct cmd *, struct cmd_q *);
-enum cmd_retval cmd_bind_key_table(struct cmd *, struct cmd_ctx *, int);
+enum cmd_retval cmd_bind_key_table(struct cmd *, struct cmd_q *, int);
const struct cmd_entry cmd_bind_key_entry = {
"bind-key", "bind",
@@ -56,7 +56,7 @@ cmd_bind_key_check(struct args *args)
}
enum cmd_retval
-cmd_bind_key_exec(struct cmd *self, struct cmd_ctx *ctx)
+cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
char *cause;
@@ -65,16 +65,17 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_ctx *ctx)
key = key_string_lookup_string(args->argv[0]);
if (key == KEYC_NONE) {
- ctx->error(ctx, "unknown key: %s", args->argv[0]);
+ cmdq_error(cmdq, "unknown key: %s", args->argv[0]);
return (CMD_RETURN_ERROR);
}
if (args_has(args, 't'))
- return (cmd_bind_key_table(self, ctx, key));
+ return (cmd_bind_key_table(self, cmdq, key));
- cmdlist = cmd_list_parse(args->argc - 1, args->argv + 1, &cause);
+ cmdlist = cmd_list_parse(args->argc - 1, args->argv + 1, NULL, 0,
+ &cause);
if (cmdlist == NULL) {
- ctx->error(ctx, "%s", cause);
+ cmdq_error(cmdq, "%s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
@@ -86,7 +87,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_ctx *ctx)
}
enum cmd_retval
-cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx, int key)
+cmd_bind_key_table(struct cmd *self, struct cmd_q *cmdq, int key)
{
struct args *args = self->args;
const char *tablename;
@@ -97,25 +98,25 @@ cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx, int key)
tablename = args_get(args, 't');
if ((mtab = mode_key_findtable(tablename)) == NULL) {
- ctx->error(ctx, "unknown key table: %s", tablename);
+ cmdq_error(cmdq, "unknown key table: %s", tablename);
return (CMD_RETURN_ERROR);
}
cmd = mode_key_fromstring(mtab->cmdstr, args->argv[1]);
if (cmd == MODEKEY_NONE) {
- ctx->error(ctx, "unknown command: %s", args->argv[1]);
+ cmdq_error(cmdq, "unknown command: %s", args->argv[1]);
return (CMD_RETURN_ERROR);
}
if (cmd != MODEKEYCOPY_COPYPIPE) {
if (args->argc != 2) {
- ctx->error(ctx, "no argument allowed");
+ cmdq_error(cmdq, "no argument allowed");
return (CMD_RETURN_ERROR);
}
arg = NULL;
} else {
if (args->argc != 3) {
- ctx->error(ctx, "no argument given");
+ cmdq_error(cmdq, "no argument given");
return (CMD_RETURN_ERROR);
}
arg = args->argv[2];
diff --git a/cmd-break-pane.c b/cmd-break-pane.c
index a5a78077..27ae1624 100644
--- a/cmd-break-pane.c
+++ b/cmd-break-pane.c
@@ -26,7 +26,7 @@
* Break pane off into a window.
*/
-enum cmd_retval cmd_break_pane_exec(struct cmd *, struct cmd_ctx *);
+enum cmd_retval cmd_break_pane_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_break_pane_entry = {
"break-pane", "breakp",
@@ -39,7 +39,7 @@ const struct cmd_entry cmd_break_pane_entry = {
};
enum cmd_retval
-cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
+cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct winlink *wl;
@@ -54,11 +54,11 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
const char *template;
char *cp;
- if ((wl = cmd_find_pane(ctx, args_get(args, 't'), &s, &wp)) == NULL)
+ if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
if (window_count_panes(wl->window) == 1) {
- ctx->error(ctx, "can't break with only one pane");
+ cmdq_error(cmdq, "can't break with only one pane");
return (CMD_RETURN_ERROR);
}
@@ -97,14 +97,14 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
template = BREAK_PANE_TEMPLATE;
ft = format_create();
- if ((c = cmd_find_client(ctx, NULL, 1)) != NULL)
+ if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
format_client(ft, c);
format_session(ft, s);
format_winlink(ft, s, wl);
format_window_pane(ft, wp);
cp = format_expand(ft, template);
- ctx->print(ctx, "%s", cp);
+ cmdq_print(cmdq, "%s", cp);
free(cp);
format_free(ft);
diff --git a/cmd-capture-pane.c b/cmd-capture-pane.c
index 6a10b7c9..aa032ce8