From 30275bc61081023b4e0a56452e90fac23c6f6b60 Mon Sep 17 00:00:00 2001 From: okan Date: Sun, 17 Nov 2013 20:19:36 +0000 Subject: Include unistd.h as it is the standard location for getopt(). OK millert@ --- arguments.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arguments.c b/arguments.c index ca828f00..e699834c 100644 --- a/arguments.c +++ b/arguments.c @@ -20,6 +20,7 @@ #include #include +#include #include "tmux.h" -- cgit From 72a4602b880357776d3a2ea7657cf88f3393c288 Mon Sep 17 00:00:00 2001 From: deraadt Date: Wed, 20 Nov 2013 17:01:23 +0000 Subject: missing unsigned char casts areound tolower() ok nicm --- window-copy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/window-copy.c b/window-copy.c index 0c122cda..dd4f23fa 100644 --- a/window-copy.c +++ b/window-copy.c @@ -1030,7 +1030,7 @@ window_copy_search_up(struct window_pane *wp, const char *searchstr) cis = 1; for (ptr = searchstr; *ptr != '\0'; ptr++) { - if (*ptr != tolower(*ptr)) { + if (*ptr != tolower((u_char)*ptr)) { cis = 0; break; } @@ -1097,7 +1097,7 @@ window_copy_search_down(struct window_pane *wp, const char *searchstr) cis = 1; for (ptr = searchstr; *ptr != '\0'; ptr++) { - if (*ptr != tolower(*ptr)) { + if (*ptr != tolower((u_char)*ptr)) { cis = 0; break; } -- cgit From 7aeb4473add76e11dd595919f81ff5d9cad28718 Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 22 Nov 2013 20:58:36 +0000 Subject: Handle empty current directory more gracefully. --- cmd-new-session.c | 17 ++++++++++------- cmd-new-window.c | 17 ++++++++++------- cmd-split-window.c | 17 ++++++++++------- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/cmd-new-session.c b/cmd-new-session.c index 49ece8b4..bf843cad 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 e2a01190..354d0ae5 100644 --- a/cmd-new-window.c +++ b/cmd-new-window.c @@ -117,13 +117,16 @@ 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; diff --git a/cmd-split-window.c b/cmd-split-window.c index 92e6121f..a431e000 100644 --- a/cmd-split-window.c +++ b/cmd-split-window.c @@ -95,13 +95,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; -- cgit From 40982a01fb39b7be749bc807a06ba352dd6c2e5e Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 23 Nov 2013 09:18:29 +0000 Subject: With -k, kill window after using it to work out -c path. Reported by jmacristovao at gmail dot com. --- cmd-new-window.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/cmd-new-window.c b/cmd-new-window.c index 354d0ae5..e205e6bc 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 @@ -133,6 +113,26 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq) 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); -- cgit From 1286c56188502e217c49f712faba66ee4178f964 Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 24 Nov 2013 11:29:09 +0000 Subject: Replace ## by # in format. --- format.c | 7 +++++++ tmux.1 | 3 +++ 2 files changed, 10 insertions(+) diff --git a/format.c b/format.c index bfc40906..bcb897d6 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/tmux.1 b/tmux.1 index e815fc4e..a2404b4f 100644 --- a/tmux.1 +++ b/tmux.1 @@ -3011,6 +3011,9 @@ for example .Ql #{session_name} . Some variables also have an shorter alias such as .Ql #S . +.Ql ## +is replaced by a single +.Ql # . Conditionals are also accepted by prefixing with .Ql \&? and separating two alternatives with a comma; -- cgit From d459314517151dd5a7ffcb3eb93d44f481ca8626 Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 24 Nov 2013 19:38:32 +0000 Subject: Add comments to ACS table matching terminfo(5). --- tty-acs.c | 64 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/tty-acs.c b/tty-acs.c index 297c51ac..13dbbc72 100644 --- a/tty-acs.c +++ b/tty-acs.c @@ -30,38 +30,38 @@ struct tty_acs_entry { const char *string; }; const struct tty_acs_entry tty_acs_table[] = { - { '+', "\342\206\222" }, - { ',', "\342\206\220" }, - { '-', "\342\206\221" }, - { '.', "\342\206\223" }, - { '0', "\342\226\256" }, - { '`', "\342\227\206" }, - { 'a', "\342\226\222" }, - { 'f', "\302\260" }, - { 'g', "\302\261" }, - { 'h', "\342\226\222" }, - { 'i', "\342\230\203" }, - { 'j', "\342\224\230" }, - { 'k', "\342\224\220" }, - { 'l', "\342\224\214" }, - { 'm', "\342\224\224" }, - { 'n', "\342\224\274" }, - { 'o', "\342\216\272" }, - { 'p', "\342\216\273" }, - { 'q', "\342\224\200" }, - { 'r', "\342\216\274" }, - { 's', "\342\216\275" }, - { 't', "\342\224\234" }, - { 'u', "\342\224\244" }, - { 'v', "\342\224\264" }, - { 'w', "\342\224\254" }, - { 'x', "\342\224\202" }, - { 'y', "\342\211\244" }, - { 'z', "\342\211\245" }, - { '{', "\317\200" }, - { '|', "\342\211\240" }, - { '}', "\302\243" }, - { '~', "\302\267" } + { '+', "\342\206\222" }, /* arrow pointing right */ + { ',', "\342\206\220" }, /* arrow pointing left */ + { '-', "\342\206\221" }, /* arrow pointing up */ + { '.', "\342\206\223" }, /* arrow pointing down */ + { '0', "\342\226\256" }, /* solid square block */ + { '`', "\342\227\206" }, /* diamond */ + { 'a', "\342\226\222" }, /* checker board (stipple) */ + { 'f', "\302\260" }, /* degree symbol */ + { 'g', "\302\261" }, /* plus/minus */ + { 'h', "\342\226\222" }, /* board of squares */ + { 'i', "\342\230\203" }, /* lantern symbol */ + { 'j', "\342\224\230" }, /* lower right corner */ + { 'k', "\342\224\220" }, /* upper right corner */ + { 'l', "\342\224\214" }, /* upper left corner */ + { 'm', "\342\224\224" }, /* lower left corner */ + { 'n', "\342\224\274" }, /* large plus or crossover */ + { 'o', "\342\216\272" }, /* scan line 1 */ + { 'p', "\342\216\273" }, /* scan line 3 */ + { 'q', "\342\224\200" }, /* horizontal line */ + { 'r', "\342\216\274" }, /* scan line 7 */ + { 's', "\342\216\275" }, /* scan line 9 */ + { 't', "\342\224\234" }, /* tee pointing right */ + { 'u', "\342\224\244" }, /* tee pointing left */ + { 'v', "\342\224\264" }, /* tee pointing up */ + { 'w', "\342\224\254" }, /* tee pointing down */ + { 'x', "\342\224\202" }, /* vertical line */ + { 'y', "\342\211\244" }, /* less-than-or-equal-to */ + { 'z', "\342\211\245" }, /* greater-than-or-equal-to */ + { '{', "\317\200" }, /* greek pi */ + { '|', "\342\211\240" }, /* not-equal */ + { '}', "\302\243" }, /* UK pound sign */ + { '~', "\302\267" } /* bullet */ }; int -- cgit From 1751da76d5fed929636633905be5f5cfa204844b Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 9 Jan 2014 13:46:12 +0000 Subject: Remove unnecessary calls to va_start/va_end, from Tiago Cunha. --- cmd-queue.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cmd-queue.c b/cmd-queue.c index bb3a09ec..caa80afe 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); -- cgit From 66829ee12e45656fccfe8879b7ac2f983d138b42 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 9 Jan 2014 13:51:57 +0000 Subject: Simplify args_set, from Tiago Cunha. --- arguments.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/arguments.c b/arguments.c index e699834c..4a3f4579 100644 --- a/arguments.c +++ b/arguments.c @@ -205,19 +205,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. */ -- cgit From 994cb872cfb5ef49a08a714d093d92bfee79b0e8 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 9 Jan 2014 13:58:06 +0000 Subject: Style and comment fixes from Tiago Cunha. --- grid.c | 2 +- options.c | 2 +- window-choose.c | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/grid.c b/grid.c index d06e7154..d9b3c716 100644 --- a/grid.c +++ b/grid.c @@ -644,7 +644,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/options.c b/options.c index ec036741..51a6608e 100644 --- a/options.c +++ b/options.c @@ -26,7 +26,7 @@ /* * Option handling; each option has a name, type and value and is stored in - * a splay tree. + * a red-black tree. */ RB_GENERATE(options_tree, options_entry, entry, options_cmp); diff --git a/window-choose.c b/window-choose.c index 70c20085..77add5e4 100644 --- a/window-choose.c +++ b/window-choose.c @@ -345,8 +345,7 @@ window_choose_collapse(struct window_pane *wp, struct session *s) * assign the actual result we want to render and copy the new one over * the top of it. */ - for (i = 0; i < ARRAY_LENGTH(&data->list); i++) - { + for (i = 0; i < ARRAY_LENGTH(&data->list); i++) { item = &ARRAY_ITEM(&data->list, i); wcd = item->wcd; -- cgit From adc1f21eaee899b8ecfdb6ef3676d9a25019e4fa Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 9 Jan 2014 14:05:55 +0000 Subject: Three small changes from Tiago Cunha: - Check for truncation when copying path. - Don't need to use a temporary buffer in screen_set_title. - Include strerror in output when connecting to server fails. --- client.c | 3 ++- screen.c | 6 +----- tmux.c | 6 +++++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/client.c b/client.c index 82ef9cf0..1458963c 100644 --- a/client.c +++ b/client.c @@ -232,7 +232,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/screen.c b/screen.c index 76aa91c6..2b0e9fba 100644 --- a/screen.c +++ b/screen.c @@ -110,12 +110,8 @@ screen_set_cursor_colour(struct screen *s, const char *colour_string) void screen_set_title(struct screen *s, const char *title) { - char tmp[BUFSIZ]; - - strlcpy(tmp, title, sizeof tmp); - free(s->title); - s->title = xstrdup(tmp); + s->title = xstrdup(title); } /* Resize screen. */ diff --git a/tmux.c b/tmux.c index 74d827a5..c8f9e059 100644 --- a/tmux.c +++ b/tmux.c @@ -361,7 +361,11 @@ main(int argc, char **argv) } } free(label); - strlcpy(socket_path, path, sizeof socket_path); + + if (strlcpy(socket_path, path, sizeof socket_path) >= sizeof socket_path) { + fprintf(stderr, "socket path too long: %s\n", path); + exit(1); + } free(path); /* Set process title. */ -- cgit From 1a0d3cd5d3bfcf15be80b5c9739b039fc7e0f575 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 9 Jan 2014 14:20:55 +0000 Subject: Allow attach-session -t to accept a window and pane to select them on attach. Based on a diff from J Raynor. --- cmd-attach-session.c | 26 ++++++++++++++++++++++++-- cmd.c | 2 -- tmux.h | 2 ++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/cmd-attach-session.c b/cmd-attach-session.c index c71e6f1f..6fb83d20 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.c b/cmd.c index 2edda633..fe55109b 100644 --- a/cmd.c +++ b/cmd.c @@ -126,9 +126,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/tmux.h b/tmux.h index 81c99f9b..0a4f8fb5 100644 --- a/tmux.h +++ b/tmux.h @@ -1739,6 +1739,8 @@ int cmd_find_index(struct cmd_q *, const char *, struct winlink *cmd_find_pane(struct cmd_q *, const char *, struct session **, struct window_pane **); char *cmd_template_replace(const char *, const char *, int); +struct window *cmd_lookup_windowid(const char *); +struct window_pane *cmd_lookup_paneid(const char *); extern const struct cmd_entry *cmd_table[]; extern const struct cmd_entry cmd_attach_session_entry; extern const struct cmd_entry cmd_bind_key_entry; -- cgit From c2cac69a22f70cb690ccc97425623f8405013dcf Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 9 Jan 2014 14:28:14 +0000 Subject: Similar to attach-session, make switch-client -t accept a window and pane. From Johannes Jakobsson. --- cmd-switch-client.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/cmd-switch-client.c b/cmd-switch-client.c index 9db35365..d0544013 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; -- cgit From b185449d073b376eb305ff2a68d87fd82ed56377 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 9 Jan 2014 21:20:45 +0000 Subject: Fix a memory/fd leak reported by Tiago Cunha. --- client.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/client.c b/client.c index 1458963c..4cf73fb9 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); -- cgit From 3368b602a868eb6570c4ee92f45c2e0ee78631cb Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 15 Jan 2014 11:44:18 +0000 Subject: Couple of fixes from cppcheck via Tiago Cunha. --- arguments.c | 3 +-- grid.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/arguments.c b/arguments.c index 4a3f4579..5ff7ed2c 100644 --- a/arguments.c +++ b/arguments.c @@ -78,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); @@ -89,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); } diff --git a/grid.c b/grid.c index d9b3c716..852423b5 100644 --- a/grid.c +++ b/grid.c @@ -124,7 +124,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++) { -- cgit From 938768ed3de3e38cb96344b8ec7b794b5e828acf Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 15 Jan 2014 11:46:28 +0000 Subject: Do not attempt to read .tmux.conf if we can't figure out a home directory, from Tiago Cunha. --- tmux.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tmux.c b/tmux.c index c8f9e059..d4848396 100644 --- a/tmux.c +++ b/tmux.c @@ -202,8 +202,9 @@ int main(int argc, char **argv) { struct passwd *pw; - char *s, *path, *label, *home, **var, tmp[MAXPATHLEN]; + char *s, *path, *label, **var, tmp[MAXPATHLEN]; char in[256]; + const char *home; long long pid; int opt, flags, quiet, keys, session; @@ -325,11 +326,15 @@ main(int argc, char **argv) pw = getpwuid(getuid()); if (pw != NULL) home = pw->pw_dir; + else + home = NULL; } - xasprintf(&cfg_file, "%s/.tmux.conf", home); - if (access(cfg_file, R_OK) != 0 && errno == ENOENT) { - free(cfg_file); - cfg_file = NULL; + if (home != NULL) { + xasprintf(&cfg_file, "%s/.tmux.conf", home); + if (access(cfg_file, R_OK) != 0 && errno == ENOENT) { + free(cfg_file); + cfg_file = NULL; + } } } -- cgit From df680d725751e0fe9eca4403c732ec1332d91d97 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 22 Jan 2014 13:57:49 +0000 Subject: Only exit copy mode at the bottom if no selection in progress, from Benoit Pierre. --- window-copy.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/window-copy.c b/window-copy.c index dd4f23fa..ddd5bf41 100644 --- a/window-copy.c +++ b/window-copy.c @@ -853,8 +853,12 @@ window_copy_mouse( } else if (m->wheel == MOUSE_WHEEL_DOWN) { for (i = 0; i < 5; i++) window_copy_cursor_down(wp, 1); - if (data->oy == 0) - goto reset_mode; + /* + * We reached the bottom, leave copy mode, + * but only if no selection is in progress. + */ + if (data->oy == 0 && !s->sel.flag) + goto reset_mode; } return; } -- cgit From 9ee93b3ea30cfa8e67a62b3c6cf522a9e677ca84 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 22 Jan 2014 14:00:08 +0000 Subject: Do not permit periods in session names (colons are already banned). From J Raynor. --- session.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/session.c b/session.c index 4f6ebed6..11ae2d35 100644 --- a/session.c +++ b/session.c @@ -175,11 +175,11 @@ session_destroy(struct session *s) RB_INSERT(sessions, &dead_sessions, s); } -/* Check a session name is valid: not empty and no colons. */ +/* Check a session name is valid: not empty and no colons or periods. */ int session_check_name(const char *name) { - return (*name != '\0' && strchr(name, ':') == NULL); + return (*name != '\0' && name[strcspn(name, ":.")] == '\0'); } /* Update session active time. */ -- cgit From d23561f38172d1fd3766bf55390ba750a5bd1b64 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 22 Jan 2014 14:43:42 +0000 Subject: Merge server-info into show-messages and remove some not useful output. --- Makefile | 1 - cmd-server-info.c | 173 ---------------------------------------------------- cmd-show-messages.c | 112 +++++++++++++++++++++++++++++++++- tmux.1 | 14 +++-- 4 files changed, 120 insertions(+), 180 deletions(-) delete mode 100644 cmd-server-info.c diff --git a/Makefile b/Makefile index 9fa55d9b..96972944 100644 --- a/Makefile +++ b/Makefile @@ -60,7 +60,6 @@ SRCS= arguments.c \ cmd-select-pane.c \ cmd-select-window.c \ cmd-send-keys.c \ - cmd-server-info.c \ cmd-set-buffer.c \ cmd-set-environment.c \ cmd-set-option.c \ diff --git a/cmd-server-info.c b/cmd-server-info.c deleted file mode 100644 index 6cbabe2b..00000000 --- a/cmd-server-info.c +++ /dev/null @@ -1,173 +0,0 @@ -/* $OpenBSD$ */ - -/* - * Copyright (c) 2008 Nicholas Marriott - * - * 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 -#include - -#include -#include -#include -#include -#include - -#include "tmux.h" - -/* - * Show various information about server. - */ - -enum cmd_retval cmd_server_info_exec(struct cmd *, struct cmd_q *); - -const struct cmd_entry cmd_server_info_entry = { - "server-info", "info", - "", 0, 0, - "", - 0, - NULL, - cmd_server_info_exec -}; - -enum cmd_retval -cmd_server_info_exec(unused struct cmd *self, struct cmd_q *cmdq) -{ - struct tty_term *term; - struct client *c; - struct session *s; - struct winlink *wl; - struct window *w; - struct window_pane *wp; - struct tty_code *code; - const struct tty_term_code_entry *ent; - struct utsname un; - struct job *job; - struct grid *gd; - struct grid_line *gl; - u_int i, j, k, lines; - size_t size; - char out[80]; - char *tim; - time_t t; - - tim = ctime(&start_time); - *strchr(tim, '\n') = '\0'; - cmdq_print(cmdq, "pid %ld, started %s", (long) getpid(), tim); - cmdq_print(cmdq, "socket path %s, debug level %d", socket_path, - debug_level); - if (uname(&un) >= 0) { - cmdq_print(cmdq, "system is %s %s %s %s", - un.sysname, un.release, un.version, un.machine); - } - if (cfg_file != NULL) - cmdq_print(cmdq, "configuration file is %s", cfg_file); - else - cmdq_print(cmdq, "configuration file not specified"); - cmdq_print(cmdq, "protocol version is %d", PROTOCOL_VERSION); - cmdq_print(cmdq, "%s", ""); - - cmdq_print(cmdq, "Clients:"); - for (i = 0; i < ARRAY_LENGTH(&clients); i++) { - c = ARRAY_ITEM(&clients, i); - if (c == NULL || c->session == NULL) - continue; - - cmdq_print(cmdq,"%2d: %s (%d, %d): %s [%ux%u %s bs=%hho " - "class=%u] [flags=0x%x/0x%x, references=%u]", i, - c->tty.path, c->ibuf.fd, c->tty.fd, c->session->name, - c->tty.sx, c->tty.sy, c->tty.termname, - c->tty.tio.c_cc[VERASE], c->tty.class, - c->flags, c->tty.flags, c->references); - } - cmdq_print(cmdq, "%s", ""); - - cmdq_print(cmdq, "Sessions: [%zu]", sizeof (struct grid_cell)); - RB_FOREACH(s, sessions, &sessions) { - t = s->creation_time.tv_sec; - tim = ctime(&t); - *strchr(tim, '\n') = '\0'; - - cmdq_print(cmdq, "%2u: %s: %u windows (created %s) [%ux%u] " - "[flags=0x%x]", s->id, s->name, - winlink_count(&s->windows), tim, s->sx, s->sy, s->flags); - RB_FOREACH(wl, winlinks, &s->windows) { - w = wl->window; - cmdq_print(cmdq, "%4u: %s [%ux%u] [flags=0x%x, " - "references=%u, last layout=%d]", wl->idx, w->name, - w->sx, w->sy, w->flags, w->references, - w->lastlayout); - j = 0; - TAILQ_FOREACH(wp, &w->panes, entry) { - lines = size = 0; - gd = wp->base.grid; - for (k = 0; k < gd->hsize + gd->sy; k++) { - gl = &gd->linedata[k]; - if (gl->celldata == NULL) - continue; - lines++; - size += gl->cellsize * - sizeof *gl->celldata; - } - cmdq_print(cmdq, - "%6u: %s %lu %d %u/%u, %zu bytes", j, - wp->tty, (u_long) wp->pid, wp->fd, lines, - gd->hsize + gd->sy, size); - j++; - } - } - } - cmdq_print(cmdq, "%s", ""); - - cmdq_print(cmdq, "Terminals:"); - LIST_FOREACH(term, &tty_terms, entry) { - cmdq_print(cmdq, "%s [references=%u, flags=0x%x]:", - term->name, term->references, term->flags); - 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, "%2u: %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, "%2u: %s: (string) %s", - ent->code, ent->name, out); - break; - case TTYCODE_NUMBER: - cmdq_print(cmdq, "%2u: %s: (number) %d", - ent->code, ent->name, code->value.number); - break; - case TTYCODE_FLAG: - cmdq_print(cmdq, "%2u: %s: (flag) %s", - ent->code, ent->name, - code->value.flag ? "true" : "false"); - break; - } - } - } - cmdq_print(cmdq, "%s", ""); - - cmdq_print(cmdq, "Jobs:"); - LIST_FOREACH(job, &all_jobs, lentry) { - cmdq_print(cmdq, "%s [fd=%d, pid=%d, status=%d]", - job->cmd, job->fd, job->pid, job->status); - } - - return (CMD_RETURN_NORMAL); -} diff --git a/cmd-show-messages.c b/cmd-show-messages.c index f43607aa..a3938e0a 100644 --- a/cmd-show-messages.c +++ b/cmd-show-messages.c @@ -20,6 +20,8 @@ #include #include +#include +#include #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/tmux.1 b/tmux.1 index a2404b4f..e44a44a6 100644 --- a/tmux.1 +++ b/tmux.1 @@ -770,15 +770,24 @@ is specified, only update the client's status bar. Rename the session to .Ar new-name . .It Xo Ic show-messages +.Op Fl IJT .Op Fl t Ar target-client .Xc .D1 (alias: Ic showmsgs ) +Show client messages or server information. Any messages displayed on the status line are saved in a per-client message log, up to a maximum of the limit set by the .Ar message-limit session option for the session attached to that client. -This command displays the log for +With +.Fl t , +display the log for .Ar target-client . +.Fl I, +.Fl J +and +.Fl T +show debugging information about the running server, jobs and terminals. .It Ic source-file Ar path .D1 (alias: Ic source ) Execute commands from @@ -3566,9 +3575,6 @@ specified by .Fl t or the current pane if omitted). If the command doesn't return success, the exit status is also displayed. -.It Ic server-info -.D1 (alias: Ic info ) -Show server information and terminal details. .It Xo Ic wait-for .Op Fl L | S | U .Ar channel -- cgit From 7d3d9963839e92e56cfd484918c16ef58c0be687 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 22 Jan 2014 22:32:15 +0000 Subject: Support paste key in copy mode input (for search etc). Also clamp length to screen width. --- window-copy.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/window-copy.c b/window-copy.c index ddd5bf41..48cd4b33 100644 --- a/window-copy.c +++ b/window-copy.c @@ -750,8 +750,10 @@ window_copy_key_input(struct window_pane *wp, int key) { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; - size_t inputlen; + size_t inputlen, n; int np; + struct paste_buffer *pb; + u_char ch; switch (mode_key_lookup(&data->mdata, key, NULL)) { case MODEKEYEDIT_CANCEL: @@ -765,6 +767,20 @@ window_copy_key_input(struct window_pane *wp, int key) case MODEKEYEDIT_DELETELINE: *data->inputstr = '\0'; break; + case MODEKEYEDIT_PASTE: + if ((pb = paste_get_top(&global_buffers)) == NULL) + break; + for (n = 0; n < pb->size; n++) { + ch = (u_char) pb->data[n]; + if (ch < 32 || ch == 127) + break; + } + inputlen = strlen(data->inputstr); + + data->inputstr = xrealloc(data->inputstr, 1, inputlen + n + 1); + memcpy(data->inputstr + inputlen, pb->data, n); + data->inputstr[inputlen + n] = '\0'; + break; case MODEKEYEDIT_ENTER: np = data->numprefix; if (np <= 0) @@ -1154,8 +1170,8 @@ window_copy_write_line( struct screen *s = &data->screen; struct options *oo = &wp->window->options; struct grid_cell gc; - char hdr[32]; - size_t last, xoff = 0, size = 0; + char hdr[512]; + size_t last, xoff = 0, size = 0, limit; window_mode_attrs(&gc, oo); @@ -1168,11 +1184,14 @@ window_copy_write_line( screen_write_cursormove(ctx, screen_size_x(s) - size, 0); screen_write_puts(ctx, &gc, "%s", hdr); } else if (py == last && data->inputtype != WINDOW_COPY_OFF) { + limit = sizeof hdr; + if (limit > screen_size_x(s)) + limit = screen_size_x(s); if (data->inputtype == WINDOW_COPY_NUMERICPREFIX) { - xoff = size = xsnprintf(hdr, sizeof hdr, + xoff = size = xsnprintf(hdr, limit, "Repeat: %u", data->numprefix); } else { - xoff = size = xsnprintf(hdr, sizeof hdr, + xoff = size = xsnprintf(hdr, limit, "%s: %s", data->inputprompt, data->inputstr); } screen_write_cursormove(ctx, 0, last); -- cgit From dda70d4ef1ce155906c123c6880352c4979e4b57 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 27 Jan 2014 23:57:35 +0000 Subject: Merge start-server into kill-server. --- Makefile | 1 - cmd-kill-server.c | 14 ++++++++++++-- cmd-start-server.c | 42 ------------------------------------------ 3 files changed, 12 insertions(+), 45 deletions(-) delete mode 100644 cmd-start-server.c diff --git a/Makefile b/Makefile index 96972944..a0736bdf 100644 --- a/Makefile +++ b/Makefile @@ -68,7 +68,6 @@ SRCS= arguments.c \ cmd-show-options.c \ cmd-source-file.c \ cmd-split-window.c \ - cmd-start-server.c \ cmd-string.c \ cmd-suspend-client.c \ cmd-swap-pane.c \ diff --git a/cmd-kill-server.c b/cmd-kill-server.c index ef4a3946..6f0b7494 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-start-server.c b/cmd-start-server.c deleted file mode 100644 index d98f9506..00000000 --- a/cmd-start-server.c +++ /dev/null @@ -1,42 +0,0 @@ -/* $OpenBSD$ */ - -/* - * Copyright (c) 2007 Nicholas Marriott - * - * 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 - -#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); -} -- cgit From c930fd5ff696f5a60e93ed503f0ff57e0bbf6e4d Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 28 Jan 2014 22:19:17 +0000 Subject: Remember the last active pane in the top-bottom or left-right cell so that it can be restored when moving back to that cell with selectp -L/-R/etc. From Suraj N Kurapati. --- tmux.h | 2 ++ window.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/tmux.h b/tmux.h index 0a4f8fb5..b28f10a0 100644 --- a/tmux.h +++ b/tmux.h @@ -1028,6 +1028,8 @@ struct layout_cell { u_int yoff; struct window_pane *wp; + struct window_pane *lastwp; + struct layout_cells cells; TAILQ_ENTRY(layout_cell) entry; diff --git a/window.c b/window.c index 83e14db6..dcb2a5f1 100644 --- a/window.c +++ b/window.c @@ -61,6 +61,10 @@ struct window_pane_tree all_window_panes; u_int next_window_pane_id; u_int next_window_id; +struct window_pane *window_pane_active_set(struct window_pane *, + struct window_pane *); +void window_pane_active_lost(struct window_pane *, struct window_pane *); + void window_pane_timer_callback(int, short, void *); void window_pane_read_callback(struct bufferevent *, void *); void window_pane_error_callback(struct bufferevent *, short, void *); @@ -386,6 +390,59 @@ window_resize(struct window *w, u_int sx, u_int sy) w->sy = sy; } +/* + * Restore previously active pane when changing from wp to nextwp. The intended + * pane is in nextwp and it returns the previously focused pane. + */ +struct window_pane * +window_pane_active_set(struct window_pane *wp, struct window_pane *nextwp) +{ + struct layout_cell *lc; + struct window_pane *lastwp; + + /* Target pane's parent must not be an ancestor of source pane. */ + for (lc = wp->layout_cell->parent; lc != NULL; lc = lc->parent) { + if (lc == nextwp->layout_cell->parent) + return (nextwp); + } + + /* + * Previously active pane, if any, must not be the same as the source + * pane. + */ + if (nextwp->layout_cell->parent != NULL) { + lastwp = nextwp->layout_cell->parent->lastwp; + if (lastwp != wp && window_pane_visible(lastwp)) + return (lastwp); + } + return (nextwp); +} + +/* Remember previously active pane when changing from wp to nextwp. */ +void +window_pane_active_lost(struct window_pane *wp, struct window_pane *nextwp) +{ + struct layout_cell *lc, *lc2; + + /* Save the target pane in its parent. */ + nextwp->layout_cell->parent->lastwp = nextwp; + + /* + * Save the source pane in all of its parents up to, but not including, + * the common ancestor of itself and the target panes. + */ + if (wp == NULL) + return; + for (lc = wp->layout_cell->parent; lc != NULL; lc = lc->parent) { + lc2 = nextwp->layout_cell->parent; + for (; lc2 != NULL; lc2 = lc2->parent) { + if (lc == lc2) + return; + } + lc->lastwp = wp; + } +} + void window_set_active_pane(struct window *w, struct window_pane *wp) { @@ -393,6 +450,7 @@ window_set_active_pane(struct window *w, struct window_pane *wp) return; w->last = w->active; w->active = wp; + window_pane_active_lost(w->last, wp); while (!window_pane_visible(w->active)) { w->active = TAILQ_PREV(w->active, window_panes, entry); if (w->active == NULL) @@ -707,6 +765,16 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit) void window_pane_destroy(struct window_pane *wp) { + struct window_pane *wp2; + + /* Forget removed pane in all layout cells that remember it. */ + RB_FOREACH(wp2, window_pane_tree, &all_window_panes) { + if (wp2->layout_cell != NULL && + wp2->layout_cell->parent != NULL && + wp2->layout_cell->parent->lastwp == wp) + wp2->layout_cell->parent->lastwp = NULL; + } + window_pane_reset_mode(wp); if (event_initialized(&wp->changes_timer)) @@ -1130,7 +1198,7 @@ window_pane_find_up(struct window_pane *wp) if (wp2->yoff + wp2->sy + 1 != top) continue; if (left >= wp2->xoff && left <= wp2->xoff + wp2->sx) - return (wp2); + return (window_pane_active_set(wp, wp2)); } return (NULL); } @@ -1156,7 +1224,7 @@ window_pane_find_down(struct window_pane *wp) if (wp2->yoff != bottom) continue; if (left >= wp2->xoff && left <= wp2->xoff + wp2->sx) - return (wp2); + return (window_pane_active_set(wp, wp2)); } return (NULL); } @@ -1185,7 +1253,7 @@ window_pane_find_left(struct window_pane *wp) if (wp2->xoff + wp2->sx + 1 != left) continue; if (top >= wp2->yoff && top <= wp2->yoff + wp2->sy) - return (wp2); + return (window_pane_active_set(wp, wp2)); } return (NULL); } @@ -1214,7 +1282,7 @@ window_pane_find_right(struct window_pane *wp) if (wp2->xoff != right) continue; if (top >= wp2->yoff && top <= wp2->yoff + wp2->sy) - return (wp2); + return (window_pane_active_set(wp, wp2)); } return (NULL); } -- cgit From 945339b443affdaaca260605e15b5a3b9a3c6e16 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 28 Jan 2014 23:07:09 +0000 Subject: Allow replacing each of the many sets of separate foo-{fg,bg,attr} options with a single foo-style option. For example: set -g status-fg yellow set -g status-bg red set -g status-attr blink Becomes: set -g status-style fg=yellow,bg=red,blink The -a flag to set can be used to add to rather than replace a style. So: set -g status-bg red Becomes: set -ag status-style bg=red Currently this is fully backwards compatible (all *-{fg,bg,attr} options remain) but the plan is to deprecate them over time. From Tiago Cunha. --- Makefile | 1 + cmd-set-option.c | 28 +++++ grid.c | 1 - options-table.c | 231 +++++++++++++++++++++++++++++++---------- options.c | 36 +++++++ screen-redraw.c | 20 ++-- screen-write.c | 85 +-------------- status.c | 120 ++++----------------- style.c | 224 ++++++++++++++++++++++++++++++++++++++++ tmux.1 | 310 ++++++++++++++++++++++++++++++------------------------- tmux.h | 36 +++++-- tty.c | 3 +- window-choose.c | 4 +- window-copy.c | 4 +- window.c | 10 -- 15 files changed, 692 insertions(+), 421 deletions(-) create mode 100644 style.c diff --git a/Makefile b/Makefile index a0736bdf..e566bb2a 100644 --- a/Makefile +++ b/Makefile @@ -113,6 +113,7 @@ SRCS= arguments.c \ session.c \ signal.c \ status.c \ + style.c \ tmux.c \ tty-acs.c \ tty-keys.c \ diff --git a/cmd-set-option.c b/cmd-set-option.c index 1b25fac0..b661913f 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/grid.c b/grid.c index 852423b5..fb838adf 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], \ diff --git a/options-table.c b/options-table.c index 97ca90be..4480b344 100644 --- a/options-table.c +++ b/options-table.c @@ -196,32 +196,43 @@ const struct options_table_entry session_options_table[] = { { .name = "message-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 + .default_num = 0, + .style = "message-style" }, { .name = "message-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 3 + .default_num = 3, + .style = "message-style" }, { .name = "message-command-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 + .default_num = 0, + .style = "message-command-style" }, { .name = "message-command-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 0 + .default_num = 0, + .style = "message-command-style" }, { .name = "message-command-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 3 + .default_num = 3, + .style = "message-command-style" + }, + + { .name = "message-command-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "bg=black,fg=yellow" }, { .name = "message-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 0 + .default_num = 0, + .style = "message-style" }, { .name = "message-limit", @@ -231,6 +242,11 @@ const struct options_table_entry session_options_table[] = { .default_num = 20 }, + { .name = "message-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "bg=yellow,fg=black" + }, + { .name = "mouse-resize-pane", .type = OPTIONS_TABLE_FLAG, .default_num = 0 @@ -253,22 +269,36 @@ const struct options_table_entry session_options_table[] = { { .name = "pane-active-border-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "pane-active-border-style" }, { .name = "pane-active-border-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 2 + .default_num = 2, + .style = "pane-active-border-style" + }, + + { .name = "pane-active-border-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "fg=green" }, { .name = "pane-border-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "pane-border-style" }, { .name = "pane-border-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "pane-border-style" + }, + + { .name = "pane-border-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "default" }, { .name = "prefix", @@ -315,17 +345,20 @@ const struct options_table_entry session_options_table[] = { { .name = "status-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 + .default_num = 0, + .style = "status-style" }, { .name = "status-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 2 + .default_num = 2, + .style = "status-style" }, { .name = "status-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 0 + .default_num = 0, + .style = "status-style" }, { .name = "status-interval", @@ -354,17 +387,20 @@ const struct options_table_entry session_options_table[] = { { .name = "status-left-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 + .default_num = 0, + .style = "status-left-style" }, { .name = "status-left-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "status-left-style" }, { .name = "status-left-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "status-left-style" }, { .name = "status-left-length", @@ -374,6 +410,11 @@ const struct options_table_entry session_options_table[] = { .default_num = 10 }, + { .name = "status-left-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "default" + }, + { .name = "status-position", .type = OPTIONS_TABLE_CHOICE, .choices = options_table_status_position_list, @@ -387,17 +428,20 @@ const struct options_table_entry session_options_table[] = { { .name = "status-right-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 + .default_num = 0, + .style = "status-right-style" }, { .name = "status-right-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "status-right-style" }, { .name = "status-right-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "status-right-style" }, { .name = "status-right-length", @@ -407,6 +451,16 @@ const struct options_table_entry session_options_table[] = { .default_num = 40 }, + { .name = "status-right-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "default" + }, + + { .name = "status-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "bg=green,fg=black" + }, + { .name = "status-utf8", .type = OPTIONS_TABLE_FLAG, .default_num = 0 /* overridden in main() */ @@ -537,17 +591,20 @@ const struct options_table_entry window_options_table[] = { { .name = "mode-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 + .default_num = 0, + .style = "mode-style" }, { .name = "mode-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 3 + .default_num = 3, + .style = "mode-style" }, { .name = "mode-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 0 + .default_num = 0, + .style = "mode-style" }, { .name = "mode-keys", @@ -562,6 +619,11 @@ const struct options_table_entry window_options_table[] = { .default_num = 0 }, + { .name = "mode-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "bg=yellow,fg=black" + }, + { .name = "monitor-activity", .type = OPTIONS_TABLE_FLAG, .default_num = 0 @@ -617,72 +679,101 @@ const struct options_table_entry window_options_table[] = { { .name = "window-status-activity-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = GRID_ATTR_REVERSE + .default_num = GRID_ATTR_REVERSE, + .style = "window-status-activity-style" }, { .name = "window-status-activity-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "window-status-activity-style" }, { .name = "window-status-activity-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "window-status-activity-style" + }, + + { .name = "window-status-activity-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "reverse" + }, + + { .name = "window-status-attr", + .type = OPTIONS_TABLE_ATTRIBUTES, + .default_num = 0, + .style = "window-status-style" }, { .name = "window-status-bell-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = GRID_ATTR_REVERSE + .default_num = GRID_ATTR_REVERSE, + .style = "window-status-bell-style" }, { .name = "window-status-bell-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "window-status-bell-style" }, { .name = "window-status-bell-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "window-status-bell-style" + }, + + { .name = "window-status-bell-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "reverse" + }, + + { .name = "window-status-bg", + .type = OPTIONS_TABLE_COLOUR, + .default_num = 8, + .style = "window-status-style" }, { .name = "window-status-content-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = GRID_ATTR_REVERSE + .default_num = GRID_ATTR_REVERSE, + .style = "window-status-content-style" }, { .name = "window-status-content-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "window-status-content-style" }, { .name = "window-status-content-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "window-status-content-style" }, - { .name = "window-status-attr", - .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 - }, - - { .name = "window-status-bg", - .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + { .name = "window-status-content-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "reverse" }, { .name = "window-status-current-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 + .default_num = 0, + .style = "window-status-current-style" }, { .name = "window-status-current-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "window-status-current-style" }, { .name = "window-status-current-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "window-status-current-style" }, { .name = "window-status-current-format", @@ -690,29 +781,43 @@ const struct options_table_entry window_options_table[] = { .default_str = "#I:#W#F" }, + { .name = "window-status-current-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "default" + }, + + { .name = "window-status-fg", + .type = OPTIONS_TABLE_COLOUR, + .default_num = 8, + .style = "window-status-style" + }, + + { .name = "window-status-format", + .type = OPTIONS_TABLE_STRING, + .default_str = "#I:#W#F" + }, + { .name = "window-status-last-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 + .default_num = 0, + .style = "window-status-last-style" }, { .name = "window-status-last-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "window-status-last-style" }, { .name = "window-status-last-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "window-status-last-style" }, - { .name = "window-status-fg", - .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 - }, - - { .name = "window-status-format", - .type = OPTIONS_TABLE_STRING, - .default_str = "#I:#W#F" + { .name = "window-status-last-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "default" }, { .name = "window-status-separator", @@ -720,6 +825,11 @@ const struct options_table_entry window_options_table[] = { .default_str = " " }, + { .name = "window-status-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "default" + }, + { .name = "wrap-search", .type = OPTIONS_TABLE_FLAG, .default_num = 1 @@ -741,10 +851,17 @@ options_table_populate_tree( const struct options_table_entry *oe; for (oe = table; oe->name != NULL; oe++) { - if (oe->default_str != NULL) + switch (oe->type) { + case OPTIONS_TABLE_STRING: options_set_string(oo, oe->name, "%s", oe->default_str); - else + break; + case OPTIONS_TABLE_STYLE: + options_set_style(oo, oe->name, oe->default_str); + break; + default: options_set_number(oo, oe->name, oe->default_num); + break; + } } } @@ -789,6 +906,10 @@ options_table_print_entry(const struct options_table_entry *oe, s = oe->choices[o->num]; xsnprintf(out, sizeof out, "%s", s); break; + case OPTIONS_TABLE_STYLE: + s = style_tostring(&o->style); + xsnprintf(out, sizeof out, "%s", s); + break; } return (out); } diff --git a/options.c b/options.c index 51a6608e..699dd9b0 100644 --- a/options.c +++ b/options.c @@ -109,6 +109,7 @@ options_set_string(struct options *oo, const char *name, const char *fmt, ...) o = xmalloc(sizeof *o); o->name = xstrdup(name); RB_INSERT(options_tree, &oo->tree, o); + memcpy(&o->style, &grid_default_cell, sizeof o->style); } else if (o->type == OPTIONS_STRING) free(o->str); @@ -140,6 +141,7 @@ options_set_number(struct options *oo, const char *name, long long value) o = xmalloc(sizeof *o); o->name = xstrdup(name); RB_INSERT(options_tree, &oo->tree, o); + memcpy(&o->style, &grid_default_cell, sizeof o->style); } else if (o->type == OPTIONS_STRING) free(o->str); @@ -159,3 +161,37 @@ options_get_number(struct options *oo, const char *name) fatalx("option not a number"); return (o->num); } + +struct options_entry * +options_set_style(struct options *oo, const char *name, const char *value, + int append) +{ + struct options_entry *o; + + if ((o = options_find1(oo, name)) == NULL) { + o = xmalloc(sizeof *o); + o->name = xstrdup(name); + RB_INSERT(options_tree, &oo->tree, o); + } else if (o->type == OPTIONS_STRING) + free(o->str); + + if (!append) + memcpy(&o->style, &grid_default_cell, sizeof o->style); + + o->type = OPTIONS_STYLE; + if (style_parse(&grid_default_cell, &o->style, value) == -1) + return (NULL); + return (o); +} + +struct grid_cell * +options_get_style(struct options *oo, const char *name) +{ + struct options_entry *o; + + if ((o = options_find(oo, name)) == NULL) + fatalx("missing option"); + if (o->type != OPTIONS_STYLE) + fatalx("option not a style"); + return (&o->style); +} diff --git a/screen-redraw.c b/screen-redraw.c index 4601c6f3..a67cb952 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -224,7 +224,7 @@ screen_redraw_screen(struct client *c, int status_only, int borders_only) struct window_pane *wp; struct grid_cell active_gc, other_gc; u_int i, j, type, top; - int status, spos, fg, bg; + int status, spos; /* Suspended clients should not be updated. */ if (c->flags & CLIENT_SUSPENDED) @@ -251,17 +251,9 @@ screen_redraw_screen(struct client *c, int status_only, int borders_only) } /* Set up pane border attributes. */ - memcpy(&other_gc, &grid_marker_cell, sizeof other_gc); - memcpy(&active_gc, &grid_marker_cell, sizeof active_gc); - active_gc.attr = other_gc.attr = GRID_ATTR_CHARSET; - fg = options_get_number(oo, "pane-border-fg"); - colour_set_fg(&other_gc, fg); - bg = options_get_number(oo, "pane-border-bg"); - colour_set_bg(&other_gc, bg); - fg = options_get_number(oo, "pane-active-border-fg"); - colour_set_fg(&active_gc, fg); - bg = options_get_number(oo, "pane-active-border-bg"); - colour_set_bg(&active_gc, bg); + style_apply(&other_gc, oo, "pane-border-style"); + style_apply(&active_gc, oo, "pane-active-border-style"); + active_gc.attr = other_gc.attr = GRID_ATTR_CHARSET; /* nuke existing */ /* Draw background and borders. */ for (j = 0; j < tty->sy - status; j++) { @@ -368,7 +360,7 @@ screen_redraw_draw_number(struct client *c, struct window_pane *wp) px -= len * 3; py -= 2; - memcpy(&gc, &grid_marker_cell, sizeof gc); + memcpy(&gc, &grid_default_cell, sizeof gc); if (w->active == w