summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Adam <thomas@xteddy.org>2014-01-31 21:39:56 +0000
committerThomas Adam <thomas@xteddy.org>2014-01-31 21:39:56 +0000
commitd50e47fc4ab5cbbdbe6bbebdc2c36ce3aae6e987 (patch)
tree397f4999444c2eef367f884b815bec2a14697c3c
parentcbf9224c5f7bcf07352f6ea128c90c12cb0af22e (diff)
parent9f02feb9d089b1a4639afb52ab0e8212eeb55a7c (diff)
Merge branch 'obsd-master'
Conflicts: Makefile cmd-server-info.c cmd-start-server.c
-rw-r--r--Makefile138
-rw-r--r--arguments.c18
-rw-r--r--client.c12
-rw-r--r--cmd-attach-session.c26
-rw-r--r--cmd-kill-server.c14
-rw-r--r--cmd-new-session.c17
-rw-r--r--cmd-new-window.c57
-rw-r--r--cmd-queue.c4
-rw-r--r--cmd-set-option.c28
-rw-r--r--cmd-show-messages.c112
-rw-r--r--cmd-split-window.c17
-rw-r--r--cmd-start-server.c42
-rw-r--r--cmd-switch-client.c43
-rw-r--r--cmd.c2
-rw-r--r--format.c7
-rw-r--r--grid.c5
-rw-r--r--input.c57
-rw-r--r--options-table.c231
-rw-r--r--options.c38
-rw-r--r--screen-redraw.c145
-rw-r--r--screen-write.c85
-rw-r--r--screen.c6
-rw-r--r--server-client.c6
-rw-r--r--session.c4
-rw-r--r--status.c120
-rw-r--r--style.c224
-rw-r--r--tmux.1327
-rw-r--r--tmux.c21
-rw-r--r--tmux.h42
-rw-r--r--tty-acs.c64
-rw-r--r--tty.c3
-rw-r--r--window-choose.c7
-rw-r--r--window-copy.c45
-rw-r--r--window.c86
-rw-r--r--xterm-keys.c2
35 files changed, 1385 insertions, 670 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..e566bb2a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,138 @@
+# $OpenBSD$
+
+PROG= tmux
+SRCS= arguments.c \
+ attributes.c \
+ cfg.c \
+ client.c \
+ clock.c \
+ cmd-attach-session.c \
+ cmd-bind-key.c \
+ cmd-break-pane.c \
+ cmd-capture-pane.c \
+ cmd-choose-buffer.c \
+ cmd-choose-client.c \
+ cmd-choose-list.c \
+ cmd-choose-tree.c \
+ cmd-clear-history.c \
+ cmd-clock-mode.c \
+ cmd-command-prompt.c \
+ cmd-confirm-before.c \
+ cmd-copy-mode.c \
+ cmd-delete-buffer.c \
+ cmd-detach-client.c \
+ cmd-display-message.c \
+ cmd-display-panes.c \
+ cmd-find-window.c \
+ cmd-has-session.c \
+ cmd-if-shell.c \
+ cmd-join-pane.c \
+ cmd-kill-pane.c \
+ cmd-kill-server.c \
+ cmd-kill-session.c \
+ cmd-kill-window.c \
+ cmd-link-window.c \
+ cmd-list-buffers.c \
+ cmd-list-clients.c \
+ cmd-list-commands.c \
+ cmd-list-keys.c \
+ cmd-list-panes.c \
+ cmd-list-sessions.c \
+ cmd-list-windows.c \
+ cmd-list.c \
+ cmd-load-buffer.c \
+ cmd-lock-server.c \
+ cmd-move-window.c \
+ cmd-new-session.c \
+ cmd-new-window.c \
+ cmd-paste-buffer.c \
+ cmd-pipe-pane.c \
+ cmd-refresh-client.c \
+ cmd-rename-session.c \
+ cmd-rename-window.c \
+ cmd-resize-pane.c \
+ cmd-respawn-pane.c \
+ cmd-respawn-window.c \
+ cmd-rotate-window.c \
+ cmd-run-shell.c \
+ cmd-save-buffer.c \
+ cmd-select-layout.c \
+ cmd-select-pane.c \
+ cmd-select-window.c \
+ cmd-send-keys.c \
+ cmd-set-buffer.c \
+ cmd-set-environment.c \
+ cmd-set-option.c \
+ cmd-show-environment.c \
+ cmd-show-messages.c \
+ cmd-show-options.c \
+ cmd-source-file.c \
+ cmd-split-window.c \
+ cmd-string.c \
+ cmd-suspend-client.c \
+ cmd-swap-pane.c \
+ cmd-swap-window.c \
+ cmd-switch-client.c \
+ cmd-unbind-key.c \
+ cmd-unlink-window.c \
+ cmd-wait-for.c \
+ cmd.c \
+ cmd-queue.c \
+ colour.c \
+ control.c \
+ control-notify.c \
+ environ.c \
+ format.c \
+ grid-cell.c \
+ grid-view.c \
+ grid.c \
+ input-keys.c \
+ input.c \
+ job.c \
+ key-bindings.c \
+ key-string.c \
+ layout-custom.c \
+ layout-set.c \
+ layout.c \
+ log.c \
+ mode-key.c \
+ names.c \
+ notify.c \
+ options-table.c \
+ options.c \
+ paste.c \
+ procname.c \
+ resize.c \
+ screen-redraw.c \
+ screen-write.c \
+ screen.c \
+ server-client.c \
+ server-fn.c \
+ server-window.c \
+ server.c \
+ session.c \
+ signal.c \
+ status.c \
+ style.c \
+ tmux.c \
+ tty-acs.c \
+ tty-keys.c \
+ tty-term.c \
+ tty.c \
+ utf8.c \
+ window-choose.c \
+ window-clock.c \
+ window-copy.c \
+ window.c \
+ xmalloc.c \
+ xterm-keys.c
+
+CDIAGFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
+CDIAGFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
+CDIAGFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
+CDIAGFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align
+
+LDADD= -lutil -lcurses -levent
+DPADD= ${LIBUTIL} ${LIBCURSES} ${LIBEVENT}
+
+.include <bsd.prog.mk>
diff --git a/arguments.c b/arguments.c
index 2b8ebc85..d4e5e53f 100644
--- a/arguments.c
+++ b/arguments.c
@@ -20,6 +20,7 @@
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include "tmux.h"
@@ -77,7 +78,6 @@ struct args *
args_parse(const char *template, int argc, char **argv)
{
struct args *args;
- char *ptr;
int opt;
args = xcalloc(1, sizeof *args);
@@ -88,7 +88,7 @@ args_parse(const char *template, int argc, char **argv)
while ((opt = getopt(argc, argv, template)) != -1) {
if (opt < 0)
continue;
- if (opt == '?' || (ptr = strchr(template, opt)) == NULL) {
+ if (opt == '?' || strchr(template, opt) == NULL) {
args_free(args);
return (NULL);
}
@@ -204,19 +204,15 @@ args_set(struct args *args, u_char ch, const char *value)
/* Replace existing argument. */
if ((entry = args_find(args, ch)) != NULL) {
free(entry->value);
- if (value != NULL)
- entry->value = xstrdup(value);
- else
- entry->value = NULL;
- return;
+ entry->value = NULL;
+ } else {
+ entry = xcalloc(1, sizeof *entry);
+ entry->flag = ch;
+ RB_INSERT(args_tree, &args->tree, entry);
}
- entry = xcalloc(1, sizeof *entry);
- entry->flag = ch;
if (value != NULL)
entry->value = xstrdup(value);
-
- RB_INSERT(args_tree, &args->tree, entry);
}
/* Get argument value. Will be NULL if it isn't present. */
diff --git a/client.c b/client.c
index 26c095c0..277efb65 100644
--- a/client.c
+++ b/client.c
@@ -118,10 +118,15 @@ retry:
close(fd);
xasprintf(&lockfile, "%s.lock", path);
- if ((lockfd = client_get_lock(lockfile)) == -1)
+ if ((lockfd = client_get_lock(lockfile)) == -1) {
+ free(lockfile);
goto retry;
- if (unlink(path) != 0 && errno != ENOENT)
+ }
+ if (unlink(path) != 0 && errno != ENOENT) {
+ free(lockfile);
+ close(lockfd);
return (-1);
+ }
fd = server_start(lockfd, lockfile);
free(lockfile);
close(lockfd);
@@ -232,7 +237,8 @@ client_main(int argc, char **argv, int flags)
/* Initialise the client socket and start the server. */
fd = client_connect(socket_path, cmdflags & CMD_STARTSERVER);
if (fd == -1) {
- fprintf(stderr, "failed to connect to server\n");
+ fprintf(stderr, "failed to connect to server: %s\n",
+ strerror(errno));
return (1);
}
diff --git a/cmd-attach-session.c b/cmd-attach-session.c
index e4c0b232..8094d78b 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -47,6 +47,9 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
{
struct session *s;
struct client *c;
+ struct winlink *wl = NULL;
+ struct window *w = NULL;
+ struct window_pane *wp = NULL;
const char *update;
char *cause;
u_int i;
@@ -59,12 +62,31 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
return (CMD_RETURN_ERROR);
}
- if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
- return (CMD_RETURN_ERROR);
+ if (tflag == NULL) {
+ if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
+ return (CMD_RETURN_ERROR);
+ } else if (tflag[strcspn(tflag, ":.")] != '\0') {
+ if ((wl = cmd_find_pane(cmdq, tflag, &s, &wp)) == NULL)
+ return (CMD_RETURN_ERROR);
+ } else {
+ if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
+ return (CMD_RETURN_ERROR);
+ w = cmd_lookup_windowid(tflag);
+ if (w == NULL && (wp = cmd_lookup_paneid(tflag)) != NULL)
+ w = wp->window;
+ if (w != NULL)
+ wl = winlink_find_by_window(&s->windows, w);
+ }
if (cmdq->client == NULL)
return (CMD_RETURN_NORMAL);
+ if (wl != NULL) {
+ if (wp != NULL)
+ window_set_active_pane(wp->window, wp);
+ session_set_current(s, wl);
+ }
+
if (cmdq->client->session != NULL) {
if (dflag) {
/*
diff --git a/cmd-kill-server.c b/cmd-kill-server.c
index ba63faa3..03016869 100644
--- a/cmd-kill-server.c
+++ b/cmd-kill-server.c
@@ -38,10 +38,20 @@ const struct cmd_entry cmd_kill_server_entry = {
cmd_kill_server_exec
};
+const struct cmd_entry cmd_start_server_entry = {
+ "start-server", "start",
+ "", 0, 0,
+ "",
+ CMD_STARTSERVER,
+ NULL,
+ cmd_kill_server_exec
+};
+
enum cmd_retval
-cmd_kill_server_exec(unused struct cmd *self, unused struct cmd_q *cmdq)
+cmd_kill_server_exec(struct cmd *self, unused struct cmd_q *cmdq)
{
- kill(getpid(), SIGTERM);
+ if (self->entry == &cmd_kill_server_entry)
+ kill(getpid(), SIGTERM);
return (CMD_RETURN_NORMAL);
}
diff --git a/cmd-new-session.c b/cmd-new-session.c
index ad083a44..15e411d0 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -107,13 +107,16 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
cp = format_expand(ft, args_get(args, 'c'));
format_free(ft);
- fd = open(cp, O_RDONLY|O_DIRECTORY);
- free(cp);
- if (fd == -1) {
- cmdq_error(cmdq, "bad working directory: %s",
- strerror(errno));
- return (CMD_RETURN_ERROR);
- }
+ if (cp != NULL && *cp != '\0') {
+ fd = open(cp, O_RDONLY|O_DIRECTORY);
+ free(cp);
+ if (fd == -1) {
+ cmdq_error(cmdq, "bad working directory: %s",
+ strerror(errno));
+ return (CMD_RETURN_ERROR);
+ }
+ } else if (cp != NULL)
+ free(cp);
cwd = fd;
} else if (c != NULL && c->session == NULL)
cwd = c->cwd;
diff --git a/cmd-new-window.c b/cmd-new-window.c
index 5c2cbe40..58a5eb65 100644
--- a/cmd-new-window.c
+++ b/cmd-new-window.c
@@ -82,26 +82,6 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
}
detached = args_has(args, 'd');
- wl = NULL;
- if (idx != -1)
- wl = winlink_find_by_index(&s->windows, idx);
- if (wl != NULL && args_has(args, 'k')) {
- /*
- * Can't use session_detach as it will destroy session if this
- * makes it empty.
- */
- notify_window_unlinked(s, wl->window);
- wl->flags &= ~WINLINK_ALERTFLAGS;
- winlink_stack_remove(&s->lastw, wl);
- winlink_remove(&s->windows, wl);
-
- /* Force select/redraw if current. */
- if (wl == s->curw) {
- detached = 0;
- s->curw = NULL;
- }
- }
-
if (args->argc == 0)
cmd = options_get_string(&s->options, "default-command");
else
@@ -117,19 +97,42 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
cp = format_expand(ft, args_get(args, 'c'));
format_free(ft);
- fd = open(cp, O_RDONLY|O_DIRECTORY);
- free(cp);
- if (fd == -1) {
- cmdq_error(cmdq, "bad working directory: %s",
- strerror(errno));
- return (CMD_RETURN_ERROR);
- }
+ if (cp != NULL && *cp != '\0') {
+ fd = open(cp, O_RDONLY|O_DIRECTORY);
+ free(cp);
+ if (fd == -1) {
+ cmdq_error(cmdq, "bad working directory: %s",
+ strerror(errno));
+ return (CMD_RETURN_ERROR);
+ }
+ } else if (cp != NULL)
+ free(cp);
cwd = fd;
} else if (cmdq->client != NULL && cmdq->client->session == NULL)
cwd = cmdq->client->cwd;
else
cwd = s->cwd;
+ wl = NULL;
+ if (idx != -1)
+ wl = winlink_find_by_index(&s->windows, idx);
+ if (wl != NULL && args_has(args, 'k')) {
+ /*
+ * Can't use session_detach as it will destroy session if this
+ * makes it empty.
+ */
+ notify_window_unlinked(s, wl->window);
+ wl->flags &= ~WINLINK_ALERTFLAGS;
+ winlink_stack_remove(&s->lastw, wl);
+ winlink_remove(&s->windows, wl);
+
+ /* Force select/redraw if current. */
+ if (wl == s->curw) {
+ detached = 0;
+ s->curw = NULL;
+ }
+ }
+
if (idx == -1)
idx = -1 - options_get_number(&s->options, "base-index");
wl = session_new(s, args_get(args, 'n'), cmd, cwd, idx, &cause);
diff --git a/cmd-queue.c b/cmd-queue.c
index c5905bdb..17955b82 100644
--- a/cmd-queue.c
+++ b/cmd-queue.c
@@ -69,9 +69,7 @@ cmdq_print(struct cmd_q *cmdq, const char *fmt, ...)
if (c == NULL)
/* nothing */;
else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
- va_start(ap, fmt);
evbuffer_add_vprintf(c->stdout_data, fmt, ap);
- va_end(ap);
evbuffer_add(c->stdout_data, "\n", 1);
server_push_stdout(c);
@@ -104,9 +102,7 @@ cmdq_info(struct cmd_q *cmdq, const char *fmt, ...)
if (c == NULL)
/* nothing */;
else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
- va_start(ap, fmt);
evbuffer_add_vprintf(c->stdout_data, fmt, ap);
- va_end(ap);
evbuffer_add(c->stdout_data, "\n", 1);
server_push_stdout(c);
diff --git a/cmd-set-option.c b/cmd-set-option.c
index 3acf125d..b760b045 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -60,6 +60,9 @@ struct options_entry *cmd_set_option_flag(struct cmd *, struct cmd_q *,
struct options_entry *cmd_set_option_choice(struct cmd *, struct cmd_q *,
const struct options_table_entry *, struct options *,
const char *);
+struct options_entry *cmd_set_option_style(struct cmd *, struct cmd_q *,
+ const struct options_table_entry *, struct options *,
+ const char *);
const struct cmd_entry cmd_set_option_entry = {
"set-option", "set",
@@ -304,9 +307,11 @@ cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
break;
case OPTIONS_TABLE_COLOUR:
o = cmd_set_option_colour(self, cmdq, oe, oo, value);
+ style_update_new(oo, o->name, oe->style);
break;
case OPTIONS_TABLE_ATTRIBUTES:
o = cmd_set_option_attributes(self, cmdq, oe, oo, value);
+ style_update_new(oo, o->name, oe->style);
break;
case OPTIONS_TABLE_FLAG:
o = cmd_set_option_flag(self, cmdq, oe, oo, value);
@@ -314,6 +319,9 @@ cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
case OPTIONS_TABLE_CHOICE:
o = cmd_set_option_choice(self, cmdq, oe, oo, value);
break;
+ case OPTIONS_TABLE_STYLE:
+ o = cmd_set_option_style(self, cmdq, oe, oo, value);
+ break;
}
if (o == NULL)
return (-1);
@@ -462,3 +470,23 @@ cmd_set_option_choice(unused struct cmd *self, struct cmd_q *cmdq,
return (options_set_number(oo, oe->name, choice));
}
+
+/* Set a style option. */
+struct options_entry *
+cmd_set_option_style(struct cmd *self, struct cmd_q *cmdq,
+ const struct options_table_entry *oe, struct options *oo,
+ const char *value)
+{
+ struct args *args = self->args;
+ struct options_entry *o;
+ int append;
+
+ append = args_has(args, 'a');
+ if ((o = options_set_style(oo, oe->name, value, append)) == NULL) {
+ cmdq_error(cmdq, "bad style: %s", value);
+ return (NULL);
+ }
+
+ style_update_old(oo, oe->name, &o->style);
+ return (o);
+}
diff --git a/cmd-show-messages.c b/cmd-show-messages.c
index 256570cd..393ed789 100644
--- a/cmd-show-messages.c
+++ b/cmd-show-messages.c
@@ -20,6 +20,8 @@
#include <string.h>
#include <time.h>
+#include <unistd.h>
+#include <vis.h>
#include "tmux.h"
@@ -31,13 +33,98 @@ enum cmd_retval cmd_show_messages_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_show_messages_entry = {
"show-messages", "showmsgs",
- "t:", 0, 0,
- CMD_TARGET_CLIENT_USAGE,
+ "IJTt:", 0, 0,
+ "[-IJT] " CMD_TARGET_CLIENT_USAGE,
0,
NULL,
cmd_show_messages_exec
};
+const struct cmd_entry cmd_server_info_entry = {
+ "server-info", "info",
+ "", 0, 0,
+ "",
+ 0,
+ NULL,
+ cmd_show_messages_exec
+};
+
+void cmd_show_messages_server (struct cmd_q *);
+void cmd_show_messages_terminals (struct cmd_q *);
+void cmd_show_messages_jobs (struct cmd_q *);
+
+void
+cmd_show_messages_server (struct cmd_q *cmdq)
+{
+ char *tim;
+
+ tim = ctime(&start_time);
+ *strchr(tim, '\n') = '\0';
+
+ cmdq_print(cmdq, "started %s", tim);
+ cmdq_print(cmdq, "socket path %s", socket_path);
+ cmdq_print(cmdq, "debug level %d", debug_level);
+ cmdq_print(cmdq, "protocol version %d", PROTOCOL_VERSION);
+}
+
+void
+cmd_show_messages_terminals (struct cmd_q *cmdq)
+{
+ struct tty_term *term;
+ const struct tty_term_code_entry *ent;
+ struct tty_code *code;
+ u_int i, n;
+ char out[80];
+
+ n = 0;
+ LIST_FOREACH(term, &tty_terms, entry) {
+ cmdq_print(cmdq,
+ "Terminal %u: %s [references=%u, flags=0x%x]:",
+ n, term->name, term->references, term->flags);
+ n++;
+ for (i = 0; i < NTTYCODE; i++) {
+ ent = &tty_term_codes[i];
+ code = &term->codes[ent->code];
+ switch (code->type) {
+ case TTYCODE_NONE:
+ cmdq_print(cmdq, "%4u: %s: [missing]",
+ ent->code, ent->name);
+ break;
+ case TTYCODE_STRING:
+ strnvis(out, code->value.string, sizeof out,
+ VIS_OCTAL|VIS_TAB|VIS_NL);
+ cmdq_print(cmdq, "%4u: %s: (string) %s",
+ ent->code, ent->name, out);
+ break;
+ case TTYCODE_NUMBER:
+ cmdq_print(cmdq, "%4u: %s: (number) %d",
+ ent->code, ent->name, code->value.number);
+ break;
+ case TTYCODE_FLAG:
+ cmdq_print(cmdq, "%4u: %s: (flag) %s",
+ ent->code, ent->name,
+ code->value.flag ? "true" : "false");
+ break;
+ }
+ }
+ }
+}
+
+void
+cmd_show_messages_jobs (struct cmd_q *cmdq)
+{
+ struct job *job;
+ u_int n;
+
+ n = 0;
+ LIST_FOREACH(job, &all_jobs, lentry) {
+ cmdq_print(cmdq,
+ "Job %u: %s [fd=%d, pid=%d, status=%d]",
+ n, job->cmd, job->fd, job->pid, job->status);
+ n++;
+ }
+}
+
enum cmd_retval
cmd_show_messages_exec(struct cmd *self, struct cmd_q *cmdq)
{
@@ -46,6 +133,27 @@ cmd_show_messages_exec(struct cmd *self, struct cmd_q *cmdq)
struct message_entry *msg;
char *tim;
u_int i;
+ int done;
+
+ done = 0;
+ if (args_has (args, 'I') || self->entry == &cmd_server_info_entry) {
+ cmd_show_messages_server (cmdq);
+ done = 1;
+ }
+ if (args_has (args, 'T') || self->entry == &cmd_server_info_entry) {
+ if (done)
+ cmdq_print (cmdq, "%s", "");
+ cmd_show_messages_terminals (cmdq);
+ done = 1;
+ }
+ if (args_has (args, 'J') || self->entry == &cmd_server_info_entry) {
+ if (done)
+ cmdq_print (cmdq, "%s", "");
+ cmd_show_messages_jobs (cmdq);
+ done = 1;
+ }
+ if (done)
+ return (CMD_RETURN_NORMAL);
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
return (CMD_RETURN_ERROR);
diff --git a/cmd-split-window.c b/cmd-split-window.c
index 4bb069f0..c43cb96b 100644
--- a/cmd-split-window.c
+++ b/cmd-split-window.c
@@ -94,13 +94,16 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
cp = format_expand(ft, args_get(args, 'c'));
format_free(ft);
- fd = open(cp, O_RDONLY|O_DIRECTORY);
- free(cp);
- if (fd == -1) {
- cmdq_error(cmdq, "bad working directory: %s",
- strerror(errno));
- return (CMD_RETURN_ERROR);
- }
+ if (cp != NULL && *cp != '\0') {
+ fd = open(cp, O_RDONLY|O_DIRECTORY);
+ free(cp);
+ if (fd == -1) {
+ cmdq_error(cmdq, "bad working directory: %s",
+ strerror(errno));
+ return (CMD_RETURN_ERROR);
+ }
+ } else if (cp != NULL)
+ free(cp);
cwd = fd;
} else if (cmdq->client != NULL && cmdq->client->session == NULL)
cwd = cmdq->client->cwd;
diff --git a/cmd-start-server.c b/cmd-start-server.c
deleted file mode 100644
index 33b28b4a..00000000
--- a/cmd-start-server.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* $Id$ */
-
-/*
- * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-
-#include "tmux.h"
-
-/*
- * Start the server and do nothing else.
- */
-
-enum cmd_retval cmd_start_server_exec(struct cmd *, struct cmd_q *);
-
-const struct cmd_entry cmd_start_server_entry = {
- "start-server", "start",
- "", 0, 0,
- "",
- CMD_STARTSERVER,
- NULL,
- cmd_start_server_exec
-};
-
-enum cmd_retval
-cmd_start_server_exec(unused struct cmd *self, unused struct cmd_q *cmdq)
-{
- return (CMD_RETURN_NORMAL);
-}
diff --git a/cmd-switch-client.c b/cmd-switch-client.c
index d101c52b..3d97c5b7 100644
--- a/cmd-switch-client.c
+++ b/cmd-switch-client.c
@@ -59,9 +59,13 @@ cmd_switch_client_key_binding(struct cmd *self, int key)
enum cmd_retval
cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
{
- struct args *args = self->args;
- struct client *c;
- struct session *s;
+ struct args *args = self->args;
+ struct client *c;
+ struct session *s;
+ struct winlink *wl = NULL;
+ struct window *w = NULL;
+ struct window_pane *wp = NULL;
+ const char *tflag;
if ((c = cmd_find_client(cmdq, args_get(args, 'c'), 0)) == NULL)
return (CMD_RETURN_ERROR);
@@ -76,7 +80,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
}
}
- s = NULL;
+ tflag = args_get(args, 't');
if (args_has(args, 'n')) {
if ((s = session_next_session(c->session)) == NULL) {
cmdq_error(cmdq, "can't find next session");
@@ -94,10 +98,33 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
cmdq_error(cmdq, "can't find last session");
return (CMD_RETURN_ERROR);
}
- } else
- s = cmd_find_session(cmdq, args_get(args, 't'), 0);
- if (s == NULL)
- return (CMD_RETURN_ERROR);
+ } else {
+ if (tflag == NULL) {
+ if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
+ return (CMD_RETURN_ERROR);
+ } else if (tflag[strcspn(tflag, ":.")] != '\0') {
+ if ((wl = cmd_find_pane(cmdq, tflag, &s, &wp)) == NULL)
+ return (CMD_RETURN_ERROR);
+ } else {
+ if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
+ return (CMD_RETURN_ERROR);
+ w = cmd_lookup_windowid(tflag);
+ if (w == NULL &&
+ (wp = cmd_lookup_paneid(tflag)) != NULL)
+ w = wp->window;
+ if (w != NULL)
+ wl = winlink_find_by_window(&s->windows, w);
+ }
+
+ if (cmdq->client == NULL)
+ return (CMD_RETURN_NORMAL);
+
+ if (wl != NULL) {
+ if (wp != NULL)
+ window_set_active_pane(wp->window, wp);
+ session_set_current(s, wl);
+ }
+ }
if (c->session != NULL)
c->last_session = c->session;
diff --git a/cmd.c b/cmd.c
index 414c9067..5e6b93aa 100644
--- a/cmd.c
+++ b/cmd.c
@@ -125,9 +125,7 @@ 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_q *, struct window *,
struct winlink **);
struct winlink *cmd_find_window_offset(const char *, struct session *, int *);
diff --git a/format.c b/format.c
index de6d8c84..10ac613e 100644
--- a/format.c
+++ b/format.c
@@ -321,6 +321,13 @@ format_expand(struct format_tree *ft, const char *fmt)
break;
fmt += n + 1;
continue;
+ case '#':
+ while (len - off < 2) {
+ buf = xrealloc(buf, 2, len);
+ len *= 2;
+ }
+ buf[off++] = '#';
+ continue;
default:
s = NULL;
if (ch >= 'A' && ch <= 'Z')
diff --git a/grid.c b/grid.c
index 9e800243..07bd1a7e 100644
--- a/grid.c
+++ b/grid.c
@@ -37,7 +37,6 @@
/* Default grid cell data. */
const struct grid_cell grid_default_cell = { 0, 0, 8, 8, (1 << 4) | 1, " " };
-const struct grid_cell grid_marker_cell = { 0, 0, 8, 8, (1 << 4) | 1, "_" };
#define grid_put_cell(gd, px, py, gc) do { \
memcpy(&gd->linedata[py].celldata[px], \
@@ -124,7 +123,7 @@ grid_compare(struct grid *ga, struct grid *gb)
struct grid_cell *gca, *gcb;
u_int xx, yy;
- if (ga->sx != gb->sx || ga->sy != ga->sy)
+ if (ga->sx != gb->sx || ga->sy != gb->sy)
return (1);
for (yy = 0; yy < ga->sy; yy++) {
@@ -644,7 +643,7 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx,
if (trim) {
while (off > 0 && buf[off - 1] == ' ')
off--;
- }
+ }
buf[off] = '\0';
return (buf);
diff --git a/input.c b/input.c
index 259fad16..ce103bd2 100644
--- a/input.c
+++ b/input.c
@@ -74,6 +74,7 @@ void input_csi_dispatch_rm(struct input_ctx *);
void input_csi_dispatch_rm_private(struct input_ctx *);
void input_csi_dispatch_sm(struct input_ctx *);
void input_csi_dispatch_sm_private(struct input_ctx *);
+void input_csi_dispatch_winops(struct input_ctx *);
void input_csi_dispatch_sgr(struct input_ctx *);
int input_dcs_dispatch(struct input_ctx *);
int input_utf8_open(struct input_ctx *);
@@ -154,6 +155,7 @@ enum input_csi_type {
INPUT_CSI_SM_PRIVATE,
INPUT_CSI_TBC,
INPUT_CSI_VPA,
+ INPUT_CSI_WINOPS,
};
/* Control (CSI) command table. */
@@ -188,6 +190,7 @@ const struct input_table_entry input_csi_table[] = {
{ 'q', " ", INPUT_CSI_DECSCUSR },
{ 'r', "", INPUT_CSI_DECSTBM },
{ 's', "", INPUT_CSI_SCP },
+ { 't', "", INPUT_CSI_WINOPS },
{ 'u', "", INPUT_CSI_RCP },
};
@@ -1077,7 +1080,7 @@ input_csi_dispatch(struct input_ctx *ictx)
struct screen_write_ctx *sctx = &