From 73c5a487c1b0f10bbc36479f425fb9cea512be7b Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 7 Apr 2014 10:32:16 +0000 Subject: [PATCH 01/20] save-buffer needs to use O_TRUNC. --- cmd-save-buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd-save-buffer.c b/cmd-save-buffer.c index 1b0a4e7b..6c15fb42 100644 --- a/cmd-save-buffer.c +++ b/cmd-save-buffer.c @@ -112,7 +112,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq) if (fd != -1) f = fdopen(fd, "ab"); } else { - fd = openat(cwd, path, O_CREAT|O_RDWR, 0600); + fd = openat(cwd, path, O_CREAT|O_RDWR|O_TRUNC, 0600); if (fd != -1) f = fdopen(fd, "wb"); } From b8bda67f304b7c70dee891b7ca660036793c2a4b Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 11 Apr 2014 19:35:54 +0000 Subject: [PATCH 02/20] Don't blindly increase offsets by the return value of snprintf, if there wasn't enough space this will go off the end. Instead clamp to the available space. Fixes crash reported by Julien Rebetez. --- arguments.c | 12 +++++++++--- cmd-list.c | 10 +++++++--- window-copy.c | 14 ++++++++------ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/arguments.c b/arguments.c index 5ff7ed2c..ca6cc760 100644 --- a/arguments.c +++ b/arguments.c @@ -125,7 +125,7 @@ args_free(struct args *args) size_t args_print(struct args *args, char *buf, size_t len) { - size_t off; + size_t off, used; int i; const char *quotes; struct args_entry *entry; @@ -165,9 +165,12 @@ args_print(struct args *args, char *buf, size_t len) quotes = "\""; else quotes = ""; - off += xsnprintf(buf + off, len - off, "%s-%c %s%s%s", + used = xsnprintf(buf + off, len - off, "%s-%c %s%s%s", off != 0 ? " " : "", entry->flag, quotes, entry->value, quotes); + if (used > len - off) + used = len - off; + off += used; } /* And finally the argument vector. */ @@ -181,8 +184,11 @@ args_print(struct args *args, char *buf, size_t len) quotes = "\""; else quotes = ""; - off += xsnprintf(buf + off, len - off, "%s%s%s%s", + used = xsnprintf(buf + off, len - off, "%s%s%s%s", off != 0 ? " " : "", quotes, args->argv[i], quotes); + if (used > len - off) + used = len - off; + off += used; } return (off); diff --git a/cmd-list.c b/cmd-list.c index 82ae7480..6dc4493a 100644 --- a/cmd-list.c +++ b/cmd-list.c @@ -103,7 +103,7 @@ size_t cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len) { struct cmd *cmd; - size_t off; + size_t off, used; off = 0; TAILQ_FOREACH(cmd, &cmdlist->list, qentry) { @@ -112,8 +112,12 @@ cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len) off += cmd_print(cmd, buf + off, len - off); if (off >= len) break; - if (TAILQ_NEXT(cmd, qentry) != NULL) - off += xsnprintf(buf + off, len - off, " ; "); + if (TAILQ_NEXT(cmd, qentry) != NULL) { + used = xsnprintf(buf + off, len - off, " ; "); + if (used > len - off) + used = len - off; + off += used; + } } return (off); } diff --git a/window-copy.c b/window-copy.c index 6e4d6704..c33a4c3b 100644 --- a/window-copy.c +++ b/window-copy.c @@ -1194,8 +1194,8 @@ window_copy_write_line( 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 (limit > screen_size_x(s) + 1) + limit = screen_size_x(s) + 1; if (data->inputtype == WINDOW_COPY_NUMERICPREFIX) { xoff = size = xsnprintf(hdr, limit, "Repeat: %u", data->numprefix); @@ -1208,10 +1208,12 @@ window_copy_write_line( } else size = 0; - screen_write_cursormove(ctx, xoff, py); - screen_write_copy(ctx, data->backing, xoff, - (screen_hsize(data->backing) - data->oy) + py, - screen_size_x(s) - size, 1); + if (size < screen_size_x(s)) { + screen_write_cursormove(ctx, xoff, py); + screen_write_copy(ctx, data->backing, xoff, + (screen_hsize(data->backing) - data->oy) + py, + screen_size_x(s) - size, 1); + } if (py == data->cy && data->cx == screen_size_x(s)) { memcpy(&gc, &grid_default_cell, sizeof gc); From a47d2397dfccfdebc26cfaca924cca8cff904235 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 14 Apr 2014 22:27:30 +0000 Subject: [PATCH 03/20] Don't leak socketpair file descriptors if fork fails. Spotted by Balazs Kezes. --- job.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/job.c b/job.c index e8006308..a8e6d33a 100644 --- a/job.c +++ b/job.c @@ -60,6 +60,8 @@ job_run(const char *cmd, struct session *s, switch (pid = fork()) { case -1: environ_free(&env); + close(out[0]); + close(out[1]); return (NULL); case 0: /* child */ clear_signals(1); From e5d85c6c3c7f81ad9744b7306fd0cb1f7d12ebad Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 16 Apr 2014 08:02:31 +0000 Subject: [PATCH 04/20] Because we pass the file descriptor from client to server, tmux can't usefully work if stdin is /dev/tty. Complain about it more clearly. --- server-client.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server-client.c b/server-client.c index 35df7531..0f4d39d6 100644 --- a/server-client.c +++ b/server-client.c @@ -119,6 +119,11 @@ server_client_open(struct client *c, char **cause) if (c->flags & CLIENT_CONTROL) return (0); + if (strcmp(c->ttyname, "/dev/tty") == 0) { + *cause = xstrdup("can't use /dev/tty"); + return (-1); + } + if (!(c->flags & CLIENT_TERMINAL)) { *cause = xstrdup("not a terminal"); return (-1); From 14a96df9ee288b24354c3ac2e57eca21b6ad8151 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 16 Apr 2014 21:02:41 +0000 Subject: [PATCH 05/20] Remove the choose-list command to prepare for some later choose-* work. --- Makefile | 1 - cmd-choose-list.c | 97 ----------------------------------------------- cmd.c | 1 - tmux.1 | 26 ------------- tmux.h | 1 - 5 files changed, 126 deletions(-) delete mode 100644 cmd-choose-list.c diff --git a/Makefile b/Makefile index 63363f51..d8d75053 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,6 @@ SRCS= arguments.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 \ diff --git a/cmd-choose-list.c b/cmd-choose-list.c deleted file mode 100644 index c3caabba..00000000 --- a/cmd-choose-list.c +++ /dev/null @@ -1,97 +0,0 @@ -/* $Id$ */ - -/* - * Copyright (c) 2012 Thomas Adam - * - * 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 "tmux.h" - -#define CMD_CHOOSE_LIST_DEFAULT_TEMPLATE "run-shell '%%'" - -/* - * Enter choose mode to choose a custom list. - */ - -enum cmd_retval cmd_choose_list_exec(struct cmd *, struct cmd_q *); - -const struct cmd_entry cmd_choose_list_entry = { - "choose-list", NULL, - "l:t:", 0, 1, - "[-l items] " CMD_TARGET_WINDOW_USAGE "[template]", - 0, - NULL, - cmd_choose_list_exec -}; - -enum cmd_retval -cmd_choose_list_exec(struct cmd *self, struct cmd_q *cmdq) -{ - struct args *args = self->args; - struct client *c; - struct winlink *wl; - const char *list1; - char *template, *item, *copy, *list; - u_int idx; - - if ((c = cmd_current_client(cmdq)) == NULL) { - cmdq_error(cmdq, "no client available"); - return (CMD_RETURN_ERROR); - } - - if ((list1 = args_get(args, 'l')) == NULL) - return (CMD_RETURN_ERROR); - - if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL) - return (CMD_RETURN_ERROR); - - if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) - return (CMD_RETURN_NORMAL); - - if (args->argc != 0) - template = xstrdup(args->argv[0]); - else - template = xstrdup(CMD_CHOOSE_LIST_DEFAULT_TEMPLATE); - - copy = list = xstrdup(list1); - idx = 0; - while ((item = strsep(&list, ",")) != NULL) - { - if (*item == '\0') /* no empty entries */ - continue; - window_choose_add_item(wl->window->active, c, wl, item, - template, idx); - idx++; - } - free(copy); - - if (idx == 0) { - free(template); - window_pane_reset_mode(wl->window->active); - return (CMD_RETURN_ERROR); - } - - window_choose_ready(wl->window->active, 0, NULL); - - free(template); - - return (CMD_RETURN_NORMAL); -} diff --git a/cmd.c b/cmd.c index 62f4c73d..726799a8 100644 --- a/cmd.c +++ b/cmd.c @@ -35,7 +35,6 @@ const struct cmd_entry *cmd_table[] = { &cmd_capture_pane_entry, &cmd_choose_buffer_entry, &cmd_choose_client_entry, - &cmd_choose_list_entry, &cmd_choose_session_entry, &cmd_choose_tree_entry, &cmd_choose_window_entry, diff --git a/tmux.1 b/tmux.1 index 8205e026..da4efcdc 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1155,32 +1155,6 @@ flag, see the section. This command works only if at least one client is attached. .It Xo -.Ic choose-list -.Op Fl l Ar items -.Op Fl t Ar target-window -.Op Ar template -.Xc -Put a window into list choice mode, allowing -.Ar items -to be selected. -.Ar items -can be a comma-separated list to display more than one item. -If an item has spaces, that entry must be quoted. -After an item is chosen, -.Ql %% -is replaced by the chosen item in the -.Ar template -and the result is executed as a command. -If -.Ar template -is not given, "run-shell '%%'" is used. -.Ar items -also accepts format specifiers. -For the meaning of this see the -.Sx FORMATS -section. -This command works only if at least one client is attached. -.It Xo .Ic choose-session .Op Fl F Ar format .Op Fl t Ar target-window diff --git a/tmux.h b/tmux.h index a9edf8ff..0b3a2ea4 100644 --- a/tmux.h +++ b/tmux.h @@ -1759,7 +1759,6 @@ extern const struct cmd_entry cmd_break_pane_entry; extern const struct cmd_entry cmd_capture_pane_entry; extern const struct cmd_entry cmd_choose_buffer_entry; extern const struct cmd_entry cmd_choose_client_entry; -extern const struct cmd_entry cmd_choose_list_entry; extern const struct cmd_entry cmd_choose_session_entry; extern const struct cmd_entry cmd_choose_tree_entry; extern const struct cmd_entry cmd_choose_window_entry; From 871b83cbab3a490827760540f2c36fd1edfe1875 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 16 Apr 2014 21:16:19 +0000 Subject: [PATCH 06/20] Remove a leftover prototype and fix some spacing. --- tmux.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tmux.h b/tmux.h index 0b3a2ea4..61fa4a39 100644 --- a/tmux.h +++ b/tmux.h @@ -2335,7 +2335,6 @@ char *get_proc_name(int, char *); void log_open(const char *); void log_close(void); void printflike1 log_debug(const char *, ...); -void printflike1 log_debug2(const char *, ...); __dead void printflike1 log_fatal(const char *, ...); __dead void printflike1 log_fatalx(const char *, ...); @@ -2356,7 +2355,9 @@ const char *style_tostring(struct grid_cell *); void style_update_new(struct options *, const char *, const char *); void style_update_old(struct options *, const char *, struct grid_cell *); -void style_apply(struct grid_cell *, struct options *, const char *); -void style_apply_update(struct grid_cell *, struct options *, const char *); +void style_apply(struct grid_cell *, struct options *, + const char *); +void style_apply_update(struct grid_cell *, struct options *, + const char *); #endif /* TMUX_H */ From 5acee1c04ed38afd6a32da4a66e6855ccdc52af3 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 16 Apr 2014 23:05:38 +0000 Subject: [PATCH 07/20] Memory leak in error path and unnecessary assignment, from clang. --- cmd-save-buffer.c | 1 - grid.c | 2 +- procname.c | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/cmd-save-buffer.c b/cmd-save-buffer.c index 6c15fb42..b6ee2e49 100644 --- a/cmd-save-buffer.c +++ b/cmd-save-buffer.c @@ -142,7 +142,6 @@ do_print: return (CMD_RETURN_ERROR); } msg = NULL; - msglen = 0; used = 0; while (used != pb->size) { diff --git a/grid.c b/grid.c index df2f8b16..28210185 100644 --- a/grid.c +++ b/grid.c @@ -624,7 +624,7 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx, off += size; } - if (trim) { + if (trim) { while (off > 0 && buf[off - 1] == ' ') off--; } diff --git a/procname.c b/procname.c index ee9b99dc..5d3bc306 100644 --- a/procname.c +++ b/procname.c @@ -96,7 +96,7 @@ get_proc_name(int fd, char *tty) retry: if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) == -1) - return (NULL); + goto error; len = (len * 5) / 4; if ((newbuf = realloc(buf, len)) == NULL) From 992ef70fb696d648b3ec6ed97642fd79a8392baf Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 17 Apr 2014 07:36:45 +0000 Subject: [PATCH 08/20] Remove the monitor-content option and associated bits and bobs. It's never worked very well. If there is a big demand for it to return, will consider better ways to do it. --- format.c | 2 -- options-table.c | 33 ----------------------------- server-window.c | 55 ++++--------------------------------------------- status.c | 2 -- tmux.1 | 33 ++--------------------------- tmux.h | 6 ++---- window.c | 2 -- 7 files changed, 8 insertions(+), 125 deletions(-) diff --git a/format.c b/format.c index 5fc76b2b..f462a2a5 100644 --- a/format.c +++ b/format.c @@ -487,8 +487,6 @@ format_winlink(struct format_tree *ft, struct session *s, struct winlink *wl) format_add(ft, "window_bell_flag", "%u", !!(wl->flags & WINLINK_BELL)); - format_add(ft, "window_content_flag", "%u", - !!(wl->flags & WINLINK_CONTENT)); format_add(ft, "window_activity_flag", "%u", !!(wl->flags & WINLINK_ACTIVITY)); format_add(ft, "window_silence_flag", "%u", diff --git a/options-table.c b/options-table.c index bc25573a..a46f5ce6 100644 --- a/options-table.c +++ b/options-table.c @@ -491,11 +491,6 @@ const struct options_table_entry session_options_table[] = { .default_num = 0 }, - { .name = "visual-content", - .type = OPTIONS_TABLE_FLAG, - .default_num = 0 - }, - { .name = "visual-silence", .type = OPTIONS_TABLE_FLAG, .default_num = 0 @@ -629,11 +624,6 @@ const struct options_table_entry window_options_table[] = { .default_num = 0 }, - { .name = "monitor-content", - .type = OPTIONS_TABLE_STRING, - .default_str = "" - }, - { .name = "monitor-silence", .type = OPTIONS_TABLE_NUMBER, .minimum = 0, @@ -735,29 +725,6 @@ const struct options_table_entry window_options_table[] = { .style = "window-status-style" }, - { .name = "window-status-content-attr", - .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = GRID_ATTR_REVERSE, - .style = "window-status-content-style" - }, - - { .name = "window-status-content-bg", - .type = OPTIONS_TABLE_COLOUR, - .default_num = 8, - .style = "window-status-content-style" - }, - - { .name = "window-status-content-fg", - .type = OPTIONS_TABLE_COLOUR, - .default_num = 8, - .style = "window-status-content-style" - }, - - { .name = "window-status-content-style", - .type = OPTIONS_TABLE_STYLE, - .default_str = "reverse" - }, - { .name = "window-status-current-attr", .type = OPTIONS_TABLE_ATTRIBUTES, .default_num = 0, diff --git a/server-window.c b/server-window.c index 86beeef4..a14c3150 100644 --- a/server-window.c +++ b/server-window.c @@ -27,19 +27,16 @@ int server_window_check_bell(struct session *, struct winlink *); int server_window_check_activity(struct session *, struct winlink *); int server_window_check_silence(struct session *, struct winlink *); -int server_window_check_content( - struct session *, struct winlink *, struct window_pane *); void ring_bell(struct session *); /* Window functions that need to happen every loop. */ void server_window_loop(void) { - struct window *w; - struct winlink *wl; - struct window_pane *wp; - struct session *s; - u_int i; + struct window *w; + struct winlink *wl; + struct session *s; + u_int i; for (i = 0; i < ARRAY_LENGTH(&windows); i++) { w = ARRAY_ITEM(&windows, i); @@ -55,8 +52,6 @@ server_window_loop(void) server_window_check_activity(s, wl) || server_window_check_silence(s, wl)) server_status_session(s); - TAILQ_FOREACH(wp, &w->panes, entry) - server_window_check_content(s, wl, wp); } } } @@ -187,48 +182,6 @@ server_window_check_silence(struct session *s, struct winlink *wl) return (1); } -/* Check for content change in window. */ -int -server_window_check_content( - struct session *s, struct winlink *wl, struct window_pane *wp) -{ - struct client *c; - struct window *w = wl->window; - u_int i; - char *found, *ptr; - - /* Activity flag must be set for new content. */ - if (s->curw->window == w) - w->flags &= ~WINDOW_ACTIVITY; - - if (!(w->flags & WINDOW_ACTIVITY) || wl->flags & WINLINK_CONTENT) - return (0); - if (s->curw == wl && !(s->flags & SESSION_UNATTACHED)) - return (0); - - ptr = options_get_string(&w->options, "monitor-content"); - if (ptr == NULL || *ptr == '\0') - return (0); - if ((found = window_pane_search(wp, ptr, NULL)) == NULL) - return (0); - free(found); - - if (options_get_number(&s->options, "bell-on-alert")) - ring_bell(s); - wl->flags |= WINLINK_CONTENT; - - if (options_get_number(&s->options, "visual-content")) { - for (i = 0; i < ARRAY_LENGTH(&clients); i++) { - c = ARRAY_ITEM(&clients, i); - if (c == NULL || c->session != s) - continue; - status_message_set(c, "Content in window %u", wl->idx); - } - } - - return (1); -} - /* Ring terminal bell. */ void ring_bell(struct session *s) diff --git a/status.c b/status.c index 029be4c8..acbf278e 100644 --- a/status.c +++ b/status.c @@ -638,8 +638,6 @@ status_print( if (wl->flags & WINLINK_BELL) style_apply_update(gc, oo, "window-status-bell-style"); - else if (wl->flags & WINLINK_CONTENT) - style_apply_update(gc, oo, "window-status-content-style"); else if (wl->flags & (WINLINK_ACTIVITY|WINLINK_SILENCE)) style_apply_update(gc, oo, "window-status-activity-style"); diff --git a/tmux.1 b/tmux.1 index da4efcdc..39523c99 100644 --- a/tmux.1 +++ b/tmux.1 @@ -2644,15 +2644,6 @@ through to the terminal (which normally makes a sound). Also see the .Ic bell-action option. -.It Xo Ic visual-content -.Op Ic on | off -.Xc -Like -.Ic visual-activity , -display a message when content is present in a window -for which the -.Ic monitor-content -window option is enabled. .It Xo Ic visual-silence .Op Ic on | off .Xc @@ -2834,14 +2825,6 @@ option. Monitor for activity in the window. Windows with activity are highlighted in the status line. .Pp -.It Ic monitor-content Ar match-string -Monitor content in the window. -When -.Xr fnmatch 3 -pattern -.Ar match-string -appears in the window, it is highlighted in the status line. -.Pp .It Xo Ic monitor-silence .Op Ic interval .Xc @@ -2914,14 +2897,6 @@ see the .Ic message-command-style option. .Pp -.It Ic window-status-content-style Ar style -Set status line style for windows with a content alert. -For how to specify -.Ar style , -see the -.Ic message-command-style -option. -.Pp .It Ic window-status-current-format Ar string Like .Ar window-status-format , @@ -3124,7 +3099,6 @@ The following variables are available, where appropriate: .It Li "window_active" Ta "" Ta "1 if window active" .It Li "window_activity_flag" Ta "" Ta "1 if window has activity alert" .It Li "window_bell_flag" Ta "" Ta "1 if window has bell" -.It Li "window_content_flag" Ta "" Ta "1 if window has content alert" .It Li "window_find_matches" Ta "" Ta "Matched data from the find-window" .It Li "window_flags" Ta "#F" Ta "Window flags" .It Li "window_height" Ta "" Ta "Height of window" @@ -3286,18 +3260,15 @@ The flag is one of the following symbols appended to the window name: .It Li "-" Ta "Marks the last window (previously selected)." .It Li "#" Ta "Window is monitored and activity has been detected." .It Li "!" Ta "A bell has occurred in the window." -.It Li "+" Ta "Window is monitored for content and it has appeared." .It Li "~" Ta "The window has been silent for the monitor-silence interval." .It Li "Z" Ta "The window's active pane is zoomed." .El .Pp The # symbol relates to the .Ic monitor-activity -and + to the -.Ic monitor-content -window options. +window option. The window name is printed in inverted colours if an alert (bell, activity or -content) is present. +silence) is present. .Pp The colour and attributes of the status line may be configured, the entire status line using the diff --git a/tmux.h b/tmux.h index 61fa4a39..8964ae00 100644 --- a/tmux.h +++ b/tmux.h @@ -990,10 +990,8 @@ struct winlink { int flags; #define WINLINK_BELL 0x1 #define WINLINK_ACTIVITY 0x2 -#define WINLINK_CONTENT 0x4 -#define WINLINK_SILENCE 0x8 -#define WINLINK_ALERTFLAGS \ - (WINLINK_BELL|WINLINK_ACTIVITY|WINLINK_CONTENT|WINLINK_SILENCE) +#define WINLINK_SILENCE 0x4 +#define WINLINK_ALERTFLAGS (WINLINK_BELL|WINLINK_ACTIVITY|WINLINK_SILENCE) RB_ENTRY(winlink) entry; TAILQ_ENTRY(winlink) sentry; diff --git a/window.c b/window.c index bb69c0bc..d934dabb 100644 --- a/window.c +++ b/window.c @@ -699,8 +699,6 @@ window_printable_flags(struct session *s, struct winlink *wl) flags[pos++] = '#'; if (wl->flags & WINLINK_BELL) flags[pos++] = '!'; - if (wl->flags & WINLINK_CONTENT) - flags[pos++] = '+'; if (wl->flags & WINLINK_SILENCE) flags[pos++] = '~'; if (wl == s->curw) From ebc5cb447f9ecb8f32e4abd0de639df0fc384402 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 17 Apr 2014 07:43:20 +0000 Subject: [PATCH 09/20] Do not show the -fg, -bg and -attr options. If asked for one explicitly, show the equivalent -style option instead. --- cmd-show-options.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/cmd-show-options.c b/cmd-show-options.c index 529289ea..b2c6ec3c 100644 --- a/cmd-show-options.c +++ b/cmd-show-options.c @@ -100,15 +100,17 @@ cmd_show_options_one(struct cmd *self, struct cmd_q *cmdq, struct options *oo, int quiet) { struct args *args = self->args; + const char *name = args->argv[0]; const struct options_table_entry *table, *oe; struct options_entry *o; const char *optval; - if (*args->argv[0] == '@') { - if ((o = options_find1(oo, args->argv[0])) == NULL) { +retry: + if (*name == '@') { + if ((o = options_find1(oo, name)) == NULL) { if (quiet) return (CMD_RETURN_NORMAL); - cmdq_error(cmdq, "unknown option: %s", args->argv[0]); + cmdq_error(cmdq, "unknown option: %s", name); return (CMD_RETURN_ERROR); } if (args_has(self->args, 'v')) @@ -119,16 +121,20 @@ cmd_show_options_one(struct cmd *self, struct cmd_q *cmdq, } table = oe = NULL; - if (options_table_find(args->argv[0], &table, &oe) != 0) { - cmdq_error(cmdq, "ambiguous option: %s", args->argv[0]); + if (options_table_find(name, &table, &oe) != 0) { + cmdq_error(cmdq, "ambiguous option: %s", name); return (CMD_RETURN_ERROR); } if (oe == NULL) { if (quiet) return (CMD_RETURN_NORMAL); - cmdq_error(cmdq, "unknown option: %s", args->argv[0]); + cmdq_error(cmdq, "unknown option: %s", name); return (CMD_RETURN_ERROR); } + if (oe->style != NULL) { + name = oe->style; + goto retry; + } if ((o = options_find1(oo, oe->name)) == NULL) return (CMD_RETURN_NORMAL); optval = options_table_print_entry(oe, o, args_has(self->args, 'v')); @@ -157,6 +163,8 @@ cmd_show_options_all(struct cmd *self, struct cmd_q *cmdq, } for (oe = table; oe->name != NULL; oe++) { + if (oe->style != NULL) + continue; if ((o = options_find1(oo, oe->name)) == NULL) continue; optval = options_table_print_entry(oe, o, From 877bdb46ed91580a3a4c430bc8c550314301352a Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 17 Apr 2014 07:51:38 +0000 Subject: [PATCH 10/20] Extend the -q flag to set-option to suppress errors about unknown options - this will allow options to be removed more easily. --- cmd-set-option.c | 26 ++++++++++++++++++-------- tmux.1 | 4 +--- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/cmd-set-option.c b/cmd-set-option.c index 9882e449..67eb8083 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -117,8 +117,11 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_ERROR); } if (oe == NULL) { - cmdq_error(cmdq, "unknown option: %s", optstr); - return (CMD_RETURN_ERROR); + if (!args_has(args, 'q')) { + cmdq_error(cmdq, "unknown option: %s", optstr); + return (CMD_RETURN_ERROR); + } + return (CMD_RETURN_NORMAL); } /* Work out the tree from the table. */ @@ -163,8 +166,10 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_ERROR); } else { if (args_has(args, 'o') && options_find1(oo, optstr) != NULL) { - if (!args_has(args, 'q')) - cmdq_print(cmdq, "already set: %s", optstr); + if (!args_has(args, 'q')) { + cmdq_error(cmdq, "already set: %s", optstr); + return (CMD_RETURN_ERROR); + } return (CMD_RETURN_NORMAL); } if (cmd_set_option_set(self, cmdq, oe, oo, valstr) != 0) @@ -229,8 +234,11 @@ cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char* optstr, if (args_has(args, 'u')) { if (options_find1(oo, optstr) == NULL) { - cmdq_error(cmdq, "unknown option: %s", optstr); - return (CMD_RETURN_ERROR); + if (!args_has(args, 'q')) { + cmdq_error(cmdq, "unknown option: %s", optstr); + return (CMD_RETURN_ERROR); + } + return (CMD_RETURN_NORMAL); } if (valstr != NULL) { cmdq_error(cmdq, "value passed to unset option: %s", @@ -244,8 +252,10 @@ cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char* optstr, return (CMD_RETURN_ERROR); } if (args_has(args, 'o') && options_find1(oo, optstr) != NULL) { - if (!args_has(args, 'q')) - cmdq_print(cmdq, "already set: %s", optstr); + if (!args_has(args, 'q')) { + cmdq_error(cmdq, "already set: %s", optstr); + return CMD_RETURN_ERROR; + } return (CMD_RETURN_NORMAL); } options_set_string(oo, optstr, "%s", valstr); diff --git a/tmux.1 b/tmux.1 index 39523c99..df305239 100644 --- a/tmux.1 +++ b/tmux.1 @@ -2047,9 +2047,7 @@ flag prevents setting an option that is already set. .Pp The .Fl q -flag suppresses the informational message (as if the -.Ic quiet -server option was set). +flag suppresses errors about unknown options. .Pp With .Fl a , From 2740490e279bac7b01f18cc39aa59a5de09e3a95 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 17 Apr 2014 07:55:43 +0000 Subject: [PATCH 11/20] Remove the "info" message mechanism, this was only used for about five mostly useless and annoying messages. Change those commands to silence on success like all the others. Still accept the -q command line flag and "quiet" server option for now. --- cmd-queue.c | 31 ------------------------------- cmd-run-shell.c | 10 +++------- cmd-select-layout.c | 3 --- cmd-set-option.c | 12 ------------ cmd-switch-client.c | 7 ++----- key-bindings.c | 2 +- options-table.c | 2 +- tmux.1 | 12 +----------- tmux.c | 9 ++++----- tmux.h | 1 - 10 files changed, 12 insertions(+), 77 deletions(-) diff --git a/cmd-queue.c b/cmd-queue.c index caa80afe..7bc154a0 100644 --- a/cmd-queue.c +++ b/cmd-queue.c @@ -86,37 +86,6 @@ cmdq_print(struct cmd_q *cmdq, const char *fmt, ...) va_end(ap); } -/* Show info from command. */ -void printflike2 -cmdq_info(struct cmd_q *cmdq, const char *fmt, ...) -{ - struct client *c = cmdq->client; - va_list ap; - char *msg; - - if (options_get_number(&global_options, "quiet")) - return; - - va_start(ap, fmt); - - if (c == NULL) - /* nothing */; - else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) { - evbuffer_add_vprintf(c->stdout_data, fmt, ap); - - evbuffer_add(c->stdout_data, "\n", 1); - server_push_stdout(c); - } else { - xvasprintf(&msg, fmt, ap); - *msg = toupper((u_char) *msg); - status_message_set(c, "%s", msg); - free(msg); - } - - va_end(ap); - -} - /* Show error from command. */ void printflike2 cmdq_error(struct cmd_q *cmdq, const char *fmt, ...) diff --git a/cmd-run-shell.c b/cmd-run-shell.c index d835e461..8799e0ab 100644 --- a/cmd-run-shell.c +++ b/cmd-run-shell.c @@ -161,13 +161,9 @@ cmd_run_shell_callback(struct job *job) retcode = WTERMSIG(job->status); xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode); } - if (msg != NULL) { - if (lines == 0) - cmdq_info(cmdq, "%s", msg); - else - cmd_run_shell_print(job, msg); - free(msg); - } + if (msg != NULL) + cmd_run_shell_print(job, msg); + free(msg); } void diff --git a/cmd-select-layout.c b/cmd-select-layout.c index 26d8538e..a5f5519c 100644 --- a/cmd-select-layout.c +++ b/cmd-select-layout.c @@ -104,7 +104,6 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_q *cmdq) else layout = layout_set_previous(wl->window); server_redraw_window(wl->window); - cmdq_info(cmdq, "arranging in: %s", layout_set_name(layout)); return (CMD_RETURN_NORMAL); } @@ -115,7 +114,6 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_q *cmdq) if (layout != -1) { layout = layout_set_select(wl->window, layout); server_redraw_window(wl->window); - cmdq_info(cmdq, "arranging in: %s", layout_set_name(layout)); return (CMD_RETURN_NORMAL); } @@ -126,7 +124,6 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_ERROR); } server_redraw_window(wl->window); - cmdq_info(cmdq, "arranging in: %s", layoutname); } return (CMD_RETURN_NORMAL); } diff --git a/cmd-set-option.c b/cmd-set-option.c index 67eb8083..3107746c 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -259,10 +259,6 @@ cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char* optstr, return (CMD_RETURN_NORMAL); } options_set_string(oo, optstr, "%s", valstr); - if (!args_has(args, 'q')) { - cmdq_info(cmdq, "set option: %s -> %s", optstr, - valstr); - } } return (CMD_RETURN_NORMAL); } @@ -285,8 +281,6 @@ cmd_set_option_unset(struct cmd *self, struct cmd_q *cmdq, } options_remove(oo, oe->name); - if (!args_has(args, 'q')) - cmdq_info(cmdq, "unset option: %s", oe->name); return (0); } @@ -295,9 +289,7 @@ int cmd_set_option_set(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; - const char *s; if (oe->type != OPTIONS_TABLE_FLAG && value == NULL) { cmdq_error(cmdq, "empty value"); @@ -337,10 +329,6 @@ cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq, } if (o == NULL) return (-1); - - s = options_table_print_entry(oe, o, 0); - if (!args_has(args, 'q')) - cmdq_info(cmdq, "set option: %s -> %s", oe->name, s); return (0); } diff --git a/cmd-switch-client.c b/cmd-switch-client.c index 99a1ae64..872570b0 100644 --- a/cmd-switch-client.c +++ b/cmd-switch-client.c @@ -71,13 +71,10 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_ERROR); if (args_has(args, 'r')) { - if (c->flags & CLIENT_READONLY) { + if (c->flags & CLIENT_READONLY) c->flags &= ~CLIENT_READONLY; - cmdq_info(cmdq, "made client writable"); - } else { + else c->flags |= CLIENT_READONLY; - cmdq_info(cmdq, "made client read-only"); - } } tflag = args_get(args, 't'); diff --git a/key-bindings.c b/key-bindings.c index 625ffddf..db48f9e7 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -212,7 +212,7 @@ key_bindings_dispatch(struct key_binding *bd, struct client *c) readonly = 0; } if (!readonly && (c->flags & CLIENT_READONLY)) { - cmdq_info(c->cmdq, "client is read-only"); + cmdq_error(c->cmdq, "client is read-only"); return; } diff --git a/options-table.c b/options-table.c index a46f5ce6..1010e84f 100644 --- a/options-table.c +++ b/options-table.c @@ -90,7 +90,7 @@ const struct options_table_entry server_options_table[] = { { .name = "quiet", .type = OPTIONS_TABLE_FLAG, - .default_num = 0 /* overridden in main() */ + .default_num = 0 }, { .name = "set-clipboard", diff --git a/tmux.1 b/tmux.1 index df305239..6aba515f 100644 --- a/tmux.1 +++ b/tmux.1 @@ -23,7 +23,7 @@ .Sh SYNOPSIS .Nm tmux .Bk -words -.Op Fl 2lCquv +.Op Fl 2lCuv .Op Fl c Ar shell-command .Op Fl f Ar file .Op Fl L Ar socket-name @@ -168,10 +168,6 @@ server process to recreate it. Behave as a login shell. This flag currently has no effect and is for compatibility with other shells when using tmux as a login shell. -.It Fl q -Set the -.Ic quiet -server option to prevent the server sending various informational messages. .It Fl S Ar socket-path Specify a full alternative path to the server socket. If @@ -2110,12 +2106,6 @@ option. Set the number of error or information messages to save in the message log for each client. The default is 100. -.It Xo Ic quiet -.Op Ic on | off -.Xc -Enable or disable the display of various informational messages (see also the -.Fl q -command line flag). .It Xo Ic set-clipboard .Op Ic on | off .Xc diff --git a/tmux.c b/tmux.c index 8f9e520d..fd2d5173 100644 --- a/tmux.c +++ b/tmux.c @@ -206,7 +206,7 @@ main(int argc, char **argv) char in[256]; const char *home; long long pid; - int opt, flags, quiet, keys, session; + int opt, flags, keys, session; #ifdef DEBUG malloc_options = (char *) "AFGJPX"; @@ -214,7 +214,7 @@ main(int argc, char **argv) setlocale(LC_TIME, ""); - quiet = flags = 0; + flags = 0; label = path = NULL; login_shell = (**argv == '-'); while ((opt = getopt(argc, argv, "2c:Cdf:lL:qS:uUv")) != -1) { @@ -244,7 +244,6 @@ main(int argc, char **argv) label = xstrdup(optarg); break; case 'q': - quiet = 1; break; case 'S': free(path); @@ -291,11 +290,11 @@ main(int argc, char **argv) options_init(&global_options, NULL); options_table_populate_tree(server_options_table, &global_options); - options_set_number(&global_options, "quiet", quiet); options_init(&global_s_options, NULL); options_table_populate_tree(session_options_table, &global_s_options); - options_set_string(&global_s_options, "default-shell", "%s", getshell()); + options_set_string(&global_s_options, "default-shell", "%s", + getshell()); options_init(&global_w_options, NULL); options_table_populate_tree(window_options_table, &global_w_options); diff --git a/tmux.h b/tmux.h index 8964ae00..18cfbbe1 100644 --- a/tmux.h +++ b/tmux.h @@ -1851,7 +1851,6 @@ size_t cmd_list_print(struct cmd_list *, char *, size_t); struct cmd_q *cmdq_new(struct client *); int cmdq_free(struct cmd_q *); void printflike2 cmdq_print(struct cmd_q *, const char *, ...); -void printflike2 cmdq_info(struct cmd_q *, const char *, ...); void printflike2 cmdq_error(struct cmd_q *, const char *, ...); int cmdq_guard(struct cmd_q *, const char *, int); void cmdq_run(struct cmd_q *, struct cmd_list *); From 2e98c9057de6c5700ca01bd58932373b103ef976 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 17 Apr 2014 09:13:13 +0000 Subject: [PATCH 12/20] Correct the dance to fix the active pane in join-pane by pulling the (right) code from break-pane and window_remove_pane into a helper function. --- cmd-break-pane.c | 11 +---------- cmd-join-pane.c | 6 +----- tmux.h | 1 + window.c | 8 +++++++- 4 files changed, 10 insertions(+), 16 deletions(-) diff --git a/cmd-break-pane.c b/cmd-break-pane.c index defd22ec..85c5d4d9 100644 --- a/cmd-break-pane.c +++ b/cmd-break-pane.c @@ -65,16 +65,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq) server_unzoom_window(w); TAILQ_REMOVE(&w->panes, wp, entry); - if (wp == w->active) { - w->active = w->last; - w->last = NULL; - if (w->active == NULL) { - w->active = TAILQ_PREV(wp, window_panes, entry); - if (w->active == NULL) - w->active = TAILQ_NEXT(wp, entry); - } - } else if (wp == w->last) - w->last = NULL; + window_lost_pane(w, wp); layout_close_pane(wp); w = wp->window = window_create1(s->sx, s->sy); diff --git a/cmd-join-pane.c b/cmd-join-pane.c index b70f93dc..7d7b1eea 100644 --- a/cmd-join-pane.c +++ b/cmd-join-pane.c @@ -139,11 +139,7 @@ join_pane(struct cmd *self, struct cmd_q *cmdq, int not_same_window) layout_close_pane(src_wp); - if (src_w->active == src_wp) { - src_w->active = TAILQ_PREV(src_wp, window_panes, entry); - if (src_w->active == NULL) - src_w->active = TAILQ_NEXT(src_wp, entry); - } + window_lost_pane(src_w, src_wp); TAILQ_REMOVE(&src_w->panes, src_wp, entry); if (window_count_panes(src_w) == 0) diff --git a/tmux.h b/tmux.h index 18cfbbe1..491027fe 100644 --- a/tmux.h +++ b/tmux.h @@ -2138,6 +2138,7 @@ struct window_pane *window_add_pane(struct window *, u_int); void window_resize(struct window *, u_int, u_int); int window_zoom(struct window_pane *); int window_unzoom(struct window *); +void window_lost_pane(struct window *, struct window_pane *); void window_remove_pane(struct window *, struct window_pane *); struct window_pane *window_pane_at_index(struct window *, u_int); struct window_pane *window_pane_next_by_number(struct window *, diff --git a/window.c b/window.c index d934dabb..faea6049 100644 --- a/window.c +++ b/window.c @@ -591,7 +591,7 @@ window_add_pane(struct window *w, u_int hlimit) } void -window_remove_pane(struct window *w, struct window_pane *wp) +window_lost_pane(struct window *w, struct window_pane *wp) { if (wp == w->active) { w->active = w->last; @@ -603,6 +603,12 @@ window_remove_pane(struct window *w, struct window_pane *wp) } } else if (wp == w->last) w->last = NULL; +} + +void +window_remove_pane(struct window *w, struct window_pane *wp) +{ + window_lost_pane(w, wp); TAILQ_REMOVE(&w->panes, wp, entry); window_pane_destroy(wp); From bce952777a491c5099693e2c256a14e51aecfaa6 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 17 Apr 2014 11:38:35 +0000 Subject: [PATCH 13/20] Remove some unnecessary includes and fix a typo. --- cfg.c | 1 - client.c | 2 -- cmd-lock-server.c | 4 ---- cmd-new-session.c | 1 - options-table.c | 4 ++-- window.c | 4 ---- 6 files changed, 2 insertions(+), 14 deletions(-) diff --git a/cfg.c b/cfg.c index 35192dc0..5d98dbe4 100644 --- a/cfg.c +++ b/cfg.c @@ -17,7 +17,6 @@ */ #include -#include #include #include diff --git a/client.c b/client.c index 4cf73fb9..70c1a007 100644 --- a/client.c +++ b/client.c @@ -25,8 +25,6 @@ #include #include -#include -#include #include #include #include diff --git a/cmd-lock-server.c b/cmd-lock-server.c index 97c86c1e..757c2e3f 100644 --- a/cmd-lock-server.c +++ b/cmd-lock-server.c @@ -18,10 +18,6 @@ #include -#include -#include -#include - #include "tmux.h" /* diff --git a/cmd-new-session.c b/cmd-new-session.c index db8416e0..22c3c5d6 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include diff --git a/options-table.c b/options-table.c index 1010e84f..abeae7af 100644 --- a/options-table.c +++ b/options-table.c @@ -28,8 +28,8 @@ * options. These tables are the master copy of the options with their real * (user-visible) types, range limits and default values. At start these are * copied into the runtime global options trees (which only has number and - * string types). These tables are then used to loop up the real type when - * the user sets an option or its value needs to be shown. + * string types). These tables are then used to look up the real type when the + * user sets an option or its value needs to be shown. */ /* Choice option type lists. */ diff --git a/window.c b/window.c index faea6049..575ac909 100644 --- a/window.c +++ b/window.c @@ -17,14 +17,10 @@ */ #include -#include #include #include #include -#include -#include -#include #include #include #include From ada75af199405c546588faacf8806e957c163621 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 17 Apr 2014 12:43:38 +0000 Subject: [PATCH 14/20] Don't limit the DCS buffer to 256 bytes, expand it as needed. Requested by Suraj Kurapati. --- input.c | 55 ++++++++++++++++++++++++++++++++++++++++--------------- tmux.h | 5 ++++- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/input.c b/input.c index 40c9d225..1123f952 100644 --- a/input.c +++ b/input.c @@ -55,6 +55,7 @@ void input_set_state(struct window_pane *, const struct input_transition *); /* Transition entry/exit handlers. */ void input_clear(struct input_ctx *); +void input_ground(struct input_ctx *); void input_enter_osc(struct input_ctx *); void input_exit_osc(struct input_ctx *); void input_enter_apc(struct input_ctx *); @@ -242,7 +243,7 @@ const struct input_transition input_state_utf8_one_table[]; /* ground state definition. */ const struct input_state input_state_ground = { "ground", - NULL, NULL, + input_ground, NULL, input_state_ground_table }; @@ -701,6 +702,12 @@ input_init(struct window_pane *wp) *ictx->param_buf = '\0'; ictx->param_len = 0; + ictx->input_space = INPUT_BUF_START; + ictx->input_buf = xmalloc(INPUT_BUF_START); + + *ictx->input_buf = '\0'; + ictx->input_len = 0; + ictx->state = &input_state_ground; ictx->flags = 0; @@ -711,8 +718,11 @@ input_init(struct window_pane *wp) void input_free(struct window_pane *wp) { - if (wp != NULL) - evbuffer_free(wp->ictx.since_ground); + if (wp == NULL) + return; + + free(wp->ictx.input_buf); + evbuffer_free(wp->ictx.since_ground); } /* Change input state. */ @@ -720,14 +730,9 @@ void input_set_state(struct window_pane *wp, const struct input_transition *itr) { struct input_ctx *ictx = &wp->ictx; - struct evbuffer *ground_evb = ictx->since_ground; if (ictx->state->exit != NULL) ictx->state->exit(ictx); - - if (itr->state == &input_state_ground) - evbuffer_drain(ground_evb, EVBUFFER_LENGTH(ground_evb)); - ictx->state = itr->state; if (ictx->state->enter != NULL) ictx->state->enter(ictx); @@ -882,6 +887,18 @@ input_clear(struct input_ctx *ictx) ictx->flags &= ~INPUT_DISCARD; } +/* Reset for ground state. */ +void +input_ground(struct input_ctx *ictx) +{ + evbuffer_drain(ictx->since_ground, EVBUFFER_LENGTH(ictx->since_ground)); + + if (ictx->input_space > INPUT_BUF_START) { + ictx->input_space = INPUT_BUF_START; + ictx->input_buf = xrealloc(ictx->input_buf, 1, INPUT_BUF_START); + } +} + /* Output this character to the screen. */ int input_print(struct input_ctx *ictx) @@ -924,12 +941,20 @@ input_parameter(struct input_ctx *ictx) int input_input(struct input_ctx *ictx) { - if (ictx->input_len == (sizeof ictx->input_buf) - 1) - ictx->flags |= INPUT_DISCARD; - else { - ictx->input_buf[ictx->input_len++] = ictx->ch; - ictx->input_buf[ictx->input_len] = '\0'; + size_t available; + + available = ictx->input_space; + while (ictx->input_len + 1 >= available) { + available *= 2; + if (available > INPUT_BUF_LIMIT) { + ictx->flags |= INPUT_DISCARD; + return (0); + } + ictx->input_buf = xrealloc(ictx->input_buf, 1, available); + ictx->input_space = available; } + ictx->input_buf[ictx->input_len++] = ictx->ch; + ictx->input_buf[ictx->input_len] = '\0'; return (0); } @@ -1666,8 +1691,8 @@ input_enter_osc(struct input_ctx *ictx) void input_exit_osc(struct input_ctx *ictx) { - u_char *p = ictx->input_buf; - int option; + u_char *p = ictx->input_buf; + int option; if (ictx->flags & INPUT_DISCARD) return; diff --git a/tmux.h b/tmux.h index 491027fe..6abc41d3 100644 --- a/tmux.h +++ b/tmux.h @@ -818,8 +818,11 @@ struct input_ctx { u_char param_buf[64]; size_t param_len; - u_char input_buf[256]; +#define INPUT_BUF_START 32 +#define INPUT_BUF_LIMIT 1048576 + u_char* input_buf; size_t input_len; + size_t input_space; int param_list[24]; /* -1 not present */ u_int param_list_len; From c3b2e5eed3b3ad4fd33cf011c5f4de6d25c602c0 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 17 Apr 2014 12:57:28 +0000 Subject: [PATCH 15/20] Wrap some long lines. --- options-table.c | 3 ++- tty-term.c | 3 ++- tty.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/options-table.c b/options-table.c index abeae7af..d68a41c3 100644 --- a/options-table.c +++ b/options-table.c @@ -528,7 +528,8 @@ const struct options_table_entry window_options_table[] = { { .name = "automatic-rename-format", .type = OPTIONS_TABLE_STRING, - .default_str = "#{?pane_in_mode,[tmux],#{pane_current_command}}#{?pane_dead,[dead],}" + .default_str = "#{?pane_in_mode,[tmux],#{pane_current_command}}" + "#{?pane_dead,[dead],}" }, { .name = "c0-change-trigger", diff --git a/tty-term.c b/tty-term.c index a66aad83..bedf0cfd 100644 --- a/tty-term.c +++ b/tty-term.c @@ -506,7 +506,8 @@ tty_term_ptr1(struct tty_term *term, enum tty_code_code code, const void *a) } const char * -tty_term_ptr2(struct tty_term *term, enum tty_code_code code, const void *a, const void *b) +tty_term_ptr2(struct tty_term *term, enum tty_code_code code, const void *a, + const void *b) { return (tparm((char *) tty_term_string(term, code), a, b)); } diff --git a/tty.c b/tty.c index b545dc33..f148f420 100644 --- a/tty.c +++ b/tty.c @@ -388,7 +388,8 @@ tty_putcode_ptr1(struct tty *tty, enum tty_code_code code, const void *a) } void -tty_putcode_ptr2(struct tty *tty, enum tty_code_code code, const void *a, const void *b) +tty_putcode_ptr2(struct tty *tty, enum tty_code_code code, const void *a, + const void *b) { if (a != NULL && b != NULL) tty_puts(tty, tty_term_ptr2(tty->term, code, a, b)); From 3e27be353d045ea231259e96892ad8be273bf9ae Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 17 Apr 2014 13:02:59 +0000 Subject: [PATCH 16/20] Set PATH explicitly, either from client or session environment. Previously it came from the session environment. From J Raynor. --- cmd-new-session.c | 13 ++++++++++++- cmd-new-window.c | 16 +++++++++++++--- cmd-respawn-pane.c | 15 +++++++++++++-- cmd-respawn-window.c | 15 +++++++++++++-- cmd-split-window.c | 14 ++++++++++++-- session.c | 15 ++++++++------- tmux.h | 16 ++++++++-------- window.c | 14 +++++++++----- 8 files changed, 88 insertions(+), 30 deletions(-) diff --git a/cmd-new-session.c b/cmd-new-session.c index 22c3c5d6..3f8ebe69 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -54,10 +54,12 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) struct environ env; struct termios tio, *tiop; const char *newname, *target, *update, *errstr, *template; + const char *path; char *cmd, *cause, *cp; int detached, already_attached, idx, cwd, fd = -1; u_int sx, sy; struct format_tree *ft; + struct environ_entry *envent; if (args_has(args, 't') && (args->argc != 0 || args_has(args, 'n'))) { cmdq_error(cmdq, "command or window name given with target"); @@ -188,6 +190,14 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) else cmd = options_get_string(&global_s_options, "default-command"); + path = NULL; + if (c != NULL && c->session == NULL) + envent = environ_find(&c->environ, "PATH"); + else + envent = environ_find(&global_environ, "PATH"); + if (envent != NULL) + path = envent->value; + /* Construct the environment. */ environ_init(&env); update = options_get_string(&global_s_options, "update-environment"); @@ -196,7 +206,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) /* Create the new session. */ idx = -1 - options_get_number(&global_s_options, "base-index"); - s = session_create(newname, cmd, cwd, &env, tiop, idx, sx, sy, &cause); + s = session_create(newname, cmd, path, cwd, &env, tiop, idx, sx, sy, + &cause); if (s == NULL) { cmdq_error(cmdq, "create session failed: %s", cause); free(cause); diff --git a/cmd-new-window.c b/cmd-new-window.c index e205e6bc..dc1bbfaa 100644 --- a/cmd-new-window.c +++ b/cmd-new-window.c @@ -49,10 +49,11 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq) struct session *s; struct winlink *wl; struct client *c; - const char *cmd, *template; + const char *cmd, *path, *template; char *cause, *cp; int idx, last, detached, cwd, fd = -1; struct format_tree *ft; + struct environ_entry *envent; if (args_has(args, 'a')) { wl = cmd_find_window(cmdq, args_get(args, 't'), &s); @@ -77,7 +78,8 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq) server_unlink_window(s, wl); } } else { - if ((idx = cmd_find_index(cmdq, args_get(args, 't'), &s)) == -2) + idx = cmd_find_index(cmdq, args_get(args, 't'), &s); + if (idx == -2) return (CMD_RETURN_ERROR); } detached = args_has(args, 'd'); @@ -87,6 +89,14 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq) else cmd = args->argv[0]; + path = NULL; + if (cmdq->client != NULL && cmdq->client->session == NULL) + envent = environ_find(&cmdq->client->environ, "PATH"); + else + envent = environ_find(&s->environ, "PATH"); + if (envent != NULL) + path = envent->value; + if (args_has(args, 'c')) { ft = format_create(); if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL) @@ -135,7 +145,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq) if (idx == -1) idx = -1 - options_get_number(&s->options, "base-index"); - wl = session_new(s, args_get(args, 'n'), cmd, cwd, idx, &cause); + wl = session_new(s, args_get(args, 'n'), cmd, path, cwd, idx, &cause); if (wl == NULL) { cmdq_error(cmdq, "create window failed: %s", cause); free(cause); diff --git a/cmd-respawn-pane.c b/cmd-respawn-pane.c index d7d88c27..1df592e7 100644 --- a/cmd-respawn-pane.c +++ b/cmd-respawn-pane.c @@ -48,9 +48,10 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq) struct window_pane *wp; struct session *s; struct environ env; - const char *cmd; + const char *cmd, *path; char *cause; u_int idx; + struct environ_entry *envent; if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL) return (CMD_RETURN_ERROR); @@ -77,7 +78,17 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq) cmd = args->argv[0]; else cmd = NULL; - if (window_pane_spawn(wp, cmd, NULL, -1, &env, s->tio, &cause) != 0) { + + path = NULL; + if (cmdq->client != NULL && cmdq->client->session == NULL) + envent = environ_find(&cmdq->client->environ, "PATH"); + else + envent = environ_find(&s->environ, "PATH"); + if (envent != NULL) + path = envent->value; + + if (window_pane_spawn(wp, cmd, path, NULL, -1, &env, s->tio, + &cause) != 0) { cmdq_error(cmdq, "respawn pane failed: %s", cause); free(cause); environ_free(&env); diff --git a/cmd-respawn-window.c b/cmd-respawn-window.c index b681f2f4..9dc3f07f 100644 --- a/cmd-respawn-window.c +++ b/cmd-respawn-window.c @@ -47,8 +47,9 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq) struct window_pane *wp; struct session *s; struct environ env; - const char *cmd; + const char *cmd, *path; char *cause; + struct environ_entry *envent; if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL) return (CMD_RETURN_ERROR); @@ -79,7 +80,17 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq) cmd = args->argv[0]; else cmd = NULL; - if (window_pane_spawn(wp, cmd, NULL, -1, &env, s->tio, &cause) != 0) { + + path = NULL; + if (cmdq->client != NULL && cmdq->client->session == NULL) + envent = environ_find(&cmdq->client->environ, "PATH"); + else + envent = environ_find(&s->environ, "PATH"); + if (envent != NULL) + path = envent->value; + + if (window_pane_spawn(wp, cmd, path, NULL, -1, &env, s->tio, + &cause) != 0) { cmdq_error(cmdq, "respawn window failed: %s", cause); free(cause); environ_free(&env); diff --git a/cmd-split-window.c b/cmd-split-window.c index a431e000..50949b39 100644 --- a/cmd-split-window.c +++ b/cmd-split-window.c @@ -61,7 +61,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq) struct window *w; struct window_pane *wp, *new_wp = NULL; struct environ env; - const char *cmd, *shell, *template; + const char *cmd, *path, *shell, *template; char *cause, *new_cause, *cp; u_int hlimit; int size, percentage, cwd, fd = -1; @@ -69,6 +69,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq) struct layout_cell *lc; struct client *c; struct format_tree *ft; + struct environ_entry *envent; if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL) return (CMD_RETURN_ERROR); @@ -148,8 +149,17 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq) goto error; } new_wp = window_add_pane(w, hlimit); + + path = NULL; + if (cmdq->client != NULL && cmdq->client->session == NULL) + envent = environ_find(&cmdq->client->environ, "PATH"); + else + envent = environ_find(&s->environ, "PATH"); + if (envent != NULL) + path = envent->value; + if (window_pane_spawn( - new_wp, cmd, shell, cwd, &env, s->tio, &cause) != 0) + new_wp, cmd, path, shell, cwd, &env, s->tio, &cause) != 0) goto error; layout_assign_pane(lc, new_wp); diff --git a/session.c b/session.c index 11ae2d35..b7d9844d 100644 --- a/session.c +++ b/session.c @@ -85,8 +85,9 @@ session_find_by_id(u_int id) /* Create a new session. */ struct session * -session_create(const char *name, const char *cmd, int cwd, struct environ *env, - struct termios *tio, int idx, u_int sx, u_int sy, char **cause) +session_create(const char *name, const char *cmd, const char *path, int cwd, + struct environ *env, struct termios *tio, int idx, u_int sx, u_int sy, + char **cause) { struct session *s; @@ -132,7 +133,7 @@ session_create(const char *name, const char *cmd, int cwd, struct environ *env, RB_INSERT(sessions, &sessions, s); if (cmd != NULL) { - if (session_new(s, NULL, cmd, cwd, idx, cause) == NULL) { + if (session_new(s, NULL, cmd, path, cwd, idx, cause) == NULL) { session_destroy(s); return (NULL); } @@ -226,8 +227,8 @@ session_previous_session(struct session *s) /* Create a new window on a session. */ struct winlink * -session_new(struct session *s, const char *name, const char *cmd, int cwd, - int idx, char **cause) +session_new(struct session *s, const char *name, const char *cmd, + const char *path, int cwd, int idx, char **cause) { struct window *w; struct winlink *wl; @@ -250,8 +251,8 @@ session_new(struct session *s, const char *name, const char *cmd, int cwd, shell = _PATH_BSHELL; hlimit = options_get_number(&s->options, "history-limit"); - w = window_create(name, cmd, shell, cwd, &env, s->tio, s->sx, s->sy, - hlimit, cause); + w = window_create(name, cmd, path, shell, cwd, &env, s->tio, s->sx, + s->sy, hlimit, cause); if (w == NULL) { winlink_remove(&s->windows, wl); environ_free(&env); diff --git a/tmux.h b/tmux.h index 6abc41d3..6787783e 100644 --- a/tmux.h +++ b/tmux.h @@ -2129,9 +2129,9 @@ void winlink_stack_remove(struct winlink_stack *, struct winlink *); int window_index(struct window *, u_int *); struct window *window_find_by_id(u_int); struct window *window_create1(u_int, u_int); -struct window *window_create(const char *, const char *, const char *, int, - struct environ *, struct termios *, u_int, u_int, u_int, - char **); +struct window *window_create(const char *, const char *, const char *, + const char *, int, struct environ *, struct termios *, + u_int, u_int, u_int, char **); void window_destroy(struct window *); struct window_pane *window_get_active_at(struct window *, u_int, u_int); void window_set_active_at(struct window *, u_int, u_int); @@ -2156,8 +2156,8 @@ struct window_pane *window_pane_create(struct window *, u_int, u_int, u_int); void window_pane_destroy(struct window_pane *); void window_pane_timer_start(struct window_pane *); int window_pane_spawn(struct window_pane *, const char *, - const char *, int, struct environ *, struct termios *, - char **); + const char *, const char *, int, struct environ *, + struct termios *, char **); void window_pane_resize(struct window_pane *, u_int, u_int); void window_pane_alternate_on(struct window_pane *, struct grid_cell *, int); @@ -2293,7 +2293,7 @@ RB_PROTOTYPE(sessions, session, entry, session_cmp); int session_alive(struct session *); struct session *session_find(const char *); struct session *session_find_by_id(u_int); -struct session *session_create(const char *, const char *, int, +struct session *session_create(const char *, const char *, const char *, int, struct environ *, struct termios *, int, u_int, u_int, char **); void session_destroy(struct session *); @@ -2301,8 +2301,8 @@ int session_check_name(const char *); void session_update_activity(struct session *); struct session *session_next_session(struct session *); struct session *session_previous_session(struct session *); -struct winlink *session_new(struct session *, const char *, const char *, int, - int, char **); +struct winlink *session_new(struct session *, const char *, const char *, + const char *, int, int, char **); struct winlink *session_attach( struct session *, struct window *, int, char **); int session_detach(struct session *, struct winlink *); diff --git a/window.c b/window.c index 575ac909..2e460641 100644 --- a/window.c +++ b/window.c @@ -308,8 +308,8 @@ window_create1(u_int sx, u_int sy) } struct window * -window_create(const char *name, const char *cmd, const char *shell, - int cwd, struct environ *env, struct termios *tio, +window_create(const char *name, const char *cmd, const char *path, + const char *shell, int cwd, struct environ *env, struct termios *tio, u_int sx, u_int sy, u_int hlimit, char **cause) { struct window *w; @@ -319,7 +319,8 @@ window_create(const char *name, const char *cmd, const char *shell, wp = window_add_pane(w, hlimit); layout_init(w, wp); - if (window_pane_spawn(wp, cmd, shell, cwd, env, tio, cause) != 0) { + if (window_pane_spawn(wp, cmd, path, shell, cwd, env, tio, + cause) != 0) { window_destroy(w); return (NULL); } @@ -810,8 +811,9 @@ window_pane_destroy(struct window_pane *wp) } int -window_pane_spawn(struct window_pane *wp, const char *cmd, const char *shell, - int cwd, struct environ *env, struct termios *tio, char **cause) +window_pane_spawn(struct window_pane *wp, const char *cmd, const char *path, + const char *shell, int cwd, struct environ *env, struct termios *tio, + char **cause) { struct winsize ws; char *argv0, paneid[16]; @@ -860,6 +862,8 @@ window_pane_spawn(struct window_pane *wp, const char *cmd, const char *shell, closefrom(STDERR_FILENO + 1); + if (path != NULL) + environ_set(env, "PATH", path); xsnprintf(paneid, sizeof paneid, "%%%u", wp->id); environ_set(env, "TMUX_PANE", paneid); environ_push(env); From f194f103a2c8301ba9eea67eefc3e15f76edbca5 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 17 Apr 2014 14:13:59 +0000 Subject: [PATCH 17/20] Only scroll by one line at a time in choose mode, lists are generally pretty small. --- window-choose.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/window-choose.c b/window-choose.c index c354d46f..34ec2eb7 100644 --- a/window-choose.c +++ b/window-choose.c @@ -715,21 +715,23 @@ window_choose_key(struct window_pane *wp, unused struct session *sess, int key) } void -window_choose_mouse( - struct window_pane *wp, unused struct session *sess, struct mouse_event *m) +window_choose_mouse(struct window_pane *wp, struct session *sess, + struct mouse_event *m) { struct window_choose_mode_data *data = wp->modedata; struct screen *s = &data->screen; struct window_choose_mode_item *item; - u_int i, idx; + u_int idx; if (m->event == MOUSE_EVENT_WHEEL) { - for (i = 0; i < m->scroll; i++) { - if (m->wheel == MOUSE_WHEEL_UP) - window_choose_key(wp, sess, KEYC_UP); - else - window_choose_key(wp, sess, KEYC_DOWN); - } + /* + * Don't use m->scroll and just move line-by-line or it's + * annoying. + */ + if (m->wheel == MOUSE_WHEEL_UP) + window_choose_key(wp, sess, KEYC_UP); + else + window_choose_key(wp, sess, KEYC_DOWN); return; } From a5d4b7f3d927b267e21aa34c2451669318536e46 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 17 Apr 2014 14:45:49 +0000 Subject: [PATCH 18/20] Some more long lines. --- cmd-find-window.c | 3 ++- cmd-set-option.c | 24 ++++++++++++++++-------- environ.c | 3 ++- grid-view.c | 6 ++++-- layout-set.c | 4 ++-- screen-write.c | 3 ++- server-fn.c | 3 ++- server.c | 2 +- tty.c | 4 ++-- utf8.c | 3 +-- window-copy.c | 6 ++++-- window.c | 3 ++- 12 files changed, 40 insertions(+), 24 deletions(-) diff --git a/cmd-find-window.c b/cmd-find-window.c index 45dbd571..ccc14fa0 100644 --- a/cmd-find-window.c +++ b/cmd-find-window.c @@ -84,7 +84,8 @@ cmd_find_window_match_flags(struct args *args) void cmd_find_window_match(struct cmd_find_window_data_list *find_list, - int match_flags, struct winlink *wl, const char *str, const char *searchstr) + int match_flags, struct winlink *wl, const char *str, + const char *searchstr) { struct cmd_find_window_data find_data; struct window_pane *wp; diff --git a/cmd-set-option.c b/cmd-set-option.c index 3107746c..d4743d55 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -267,7 +267,8 @@ cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char* optstr, /* Unset an option. */ int cmd_set_option_unset(struct cmd *self, struct cmd_q *cmdq, - const struct options_table_entry *oe, struct options *oo, const char *value) + const struct options_table_entry *oe, struct options *oo, + const char *value) { struct args *args = self->args; @@ -287,7 +288,8 @@ cmd_set_option_unset(struct cmd *self, struct cmd_q *cmdq, /* Set an option. */ int cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq, - const struct options_table_entry *oe, struct options *oo, const char *value) + const struct options_table_entry *oe, struct options *oo, + const char *value) { struct options_entry *o; @@ -335,7 +337,8 @@ cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq, /* Set a string option. */ struct options_entry * cmd_set_option_string(struct cmd *self, unused struct cmd_q *cmdq, - const struct options_table_entry *oe, struct options *oo, const char *value) + const struct options_table_entry *oe, struct options *oo, + const char *value) { struct args *args = self->args; struct options_entry *o; @@ -356,7 +359,8 @@ cmd_set_option_string(struct cmd *self, unused struct cmd_q *cmdq, /* Set a number option. */ struct options_entry * cmd_set_option_number(unused struct cmd *self, struct cmd_q *cmdq, - const struct options_table_entry *oe, struct options *oo, const char *value) + const struct options_table_entry *oe, struct options *oo, + const char *value) { long long ll; const char *errstr; @@ -373,7 +377,8 @@ cmd_set_option_number(unused struct cmd *self, struct cmd_q *cmdq, /* Set a key option. */ struct options_entry * cmd_set_option_key(unused struct cmd *self, struct cmd_q *cmdq, - const struct options_table_entry *oe, struct options *oo, const char *value) + const struct options_table_entry *oe, struct options *oo, + const char *value) { int key; @@ -388,7 +393,8 @@ cmd_set_option_key(unused struct cmd *self, struct cmd_q *cmdq, /* Set a colour option. */ struct options_entry * cmd_set_option_colour(unused struct cmd *self, struct cmd_q *cmdq, - const struct options_table_entry *oe, struct options *oo, const char *value) + const struct options_table_entry *oe, struct options *oo, + const char *value) { int colour; @@ -403,7 +409,8 @@ cmd_set_option_colour(unused struct cmd *self, struct cmd_q *cmdq, /* Set an attributes option. */ struct options_entry * cmd_set_option_attributes(unused struct cmd *self, struct cmd_q *cmdq, - const struct options_table_entry *oe, struct options *oo, const char *value) + const struct options_table_entry *oe, struct options *oo, + const char *value) { int attr; @@ -418,7 +425,8 @@ cmd_set_option_attributes(unused struct cmd *self, struct cmd_q *cmdq, /* Set a flag option. */ struct options_entry * cmd_set_option_flag(unused struct cmd *self, struct cmd_q *cmdq, - const struct options_table_entry *oe, struct options *oo, const char *value) + const struct options_table_entry *oe, struct options *oo, + const char *value) { int flag; diff --git a/environ.c b/environ.c index 2374d764..284f8b55 100644 --- a/environ.c +++ b/environ.c @@ -137,7 +137,8 @@ environ_unset(struct environ *env, const char *name) * environment. */ void -environ_update(const char *vars, struct environ *srcenv, struct environ *dstenv) +environ_update(const char *vars, struct environ *srcenv, + struct environ *dstenv) { struct environ_entry *envent; char *copyvars, *var, *next; diff --git a/grid-view.c b/grid-view.c index fca5fd54..badabd56 100644 --- a/grid-view.c +++ b/grid-view.c @@ -131,7 +131,8 @@ grid_view_insert_lines(struct grid *gd, u_int py, u_int ny) /* Insert lines in region. */ void -grid_view_insert_lines_region(struct grid *gd, u_int rlower, u_int py, u_int ny) +grid_view_insert_lines_region(struct grid *gd, u_int rlower, u_int py, + u_int ny) { u_int ny2; @@ -160,7 +161,8 @@ grid_view_delete_lines(struct grid *gd, u_int py, u_int ny) /* Delete lines inside scroll region. */ void -grid_view_delete_lines_region(struct grid *gd, u_int rlower, u_int py, u_int ny) +grid_view_delete_lines_region(struct grid *gd, u_int rlower, u_int py, + u_int ny) { u_int ny2; diff --git a/layout-set.c b/layout-set.c index 98ed9736..64b655a0 100644 --- a/layout-set.c +++ b/layout-set.c @@ -23,8 +23,8 @@ #include "tmux.h" /* - * Set window layouts - predefined methods to arrange windows. These are one-off - * and generate a layout tree. + * Set window layouts - predefined methods to arrange windows. These are + * one-off and generate a layout tree. */ void layout_set_even_h(struct window *); diff --git a/screen-write.c b/screen-write.c index 3da145e8..7251c93a 100644 --- a/screen-write.c +++ b/screen-write.c @@ -65,7 +65,8 @@ screen_write_reset(struct screen_write_ctx *ctx) /* Write character. */ void -screen_write_putc(struct screen_write_ctx *ctx, struct grid_cell *gc, u_char ch) +screen_write_putc(struct screen_write_ctx *ctx, struct grid_cell *gc, + u_char ch) { grid_cell_one(gc, ch); screen_write_cell(ctx, gc); diff --git a/server-fn.c b/server-fn.c index f585cb71..5b25c925 100644 --- a/server-fn.c +++ b/server-fn.c @@ -291,7 +291,8 @@ server_kill_window(struct window *w) int server_link_window(struct session *src, struct winlink *srcwl, - struct session *dst, int dstidx, int killflag, int selectflag, char **cause) + struct session *dst, int dstidx, int killflag, int selectflag, + char **cause) { struct winlink *dstwl; struct session_group *srcsg, *dstsg; diff --git a/server.c b/server.c index 8ac9321e..ea8b77f1 100644 --- a/server.c +++ b/server.c @@ -216,7 +216,7 @@ server_loop(void) } } -/* Check if the server should be shutting down (no more clients or sessions). */ +/* Check if the server should exit (no more clients or sessions). */ int server_should_shutdown(void) { diff --git a/tty.c b/tty.c index f148f420..c8b6a84a 100644 --- a/tty.c +++ b/tty.c @@ -548,8 +548,8 @@ tty_update_mode(struct tty *tty, int mode, struct screen *s) } void -tty_emulate_repeat( - struct tty *tty, enum tty_code_code code, enum tty_code_code code1, u_int n) +tty_emulate_repeat(struct tty *tty, enum tty_code_code code, + enum tty_code_code code1, u_int n) { if (tty_term_has(tty->term, code)) tty_putcode1(tty, code, n); diff --git a/utf8.c b/utf8.c index 082683e8..945715dd 100644 --- a/utf8.c +++ b/utf8.c @@ -247,8 +247,7 @@ utf8_append(struct utf8_data *utf8data, u_char ch) /* Check if two width tree entries overlap. */ int -utf8_overlap( - struct utf8_width_entry *item1, struct utf8_width_entry *item2) +utf8_overlap(struct utf8_width_entry *item1, struct utf8_width_entry *item2) { if (item1->first >= item2->first && item1->first <= item2->last) return (1); diff --git a/window-copy.c b/window-copy.c index c33a4c3b..ef99ed9a 100644 --- a/window-copy.c +++ b/window-copy.c @@ -2033,7 +2033,8 @@ window_copy_cursor_next_word(struct window_pane *wp, const char *separators) } void -window_copy_cursor_next_word_end(struct window_pane *wp, const char *separators) +window_copy_cursor_next_word_end(struct window_pane *wp, + const char *separators) { struct window_copy_mode_data *data = wp->modedata; struct options *oo = &wp->window->options; @@ -2084,7 +2085,8 @@ window_copy_cursor_next_word_end(struct window_pane *wp, const char *separators) /* Move to the previous place where a word begins. */ void -window_copy_cursor_previous_word(struct window_pane *wp, const char *separators) +window_copy_cursor_previous_word(struct window_pane *wp, + const char *separators) { struct window_copy_mode_data *data = wp->modedata; u_int px, py; diff --git a/window.c b/window.c index 2e460641..1b36f7d7 100644 --- a/window.c +++ b/window.c @@ -1162,7 +1162,8 @@ window_pane_visible(struct window_pane *wp) } char * -window_pane_search(struct window_pane *wp, const char *searchstr, u_int *lineno) +window_pane_search(struct window_pane *wp, const char *searchstr, + u_int *lineno) { struct screen *s = &wp->base; char *newsearchstr, *line, *msg; From 806520f025dccdcbf266bb9c7cbd984bef00d733 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 17 Apr 2014 15:37:55 +0000 Subject: [PATCH 19/20] Add some UTF-8 utility functions and use them to prevent the width limit on formats from splitting UTF-8 characters improperly. --- format.c | 13 +++--- tmux.h | 19 +++++---- utf8.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+), 12 deletions(-) diff --git a/format.c b/format.c index f462a2a5..7c8ce779 100644 --- a/format.c +++ b/format.c @@ -194,10 +194,10 @@ int format_replace(struct format_tree *ft, const char *key, size_t keylen, char **buf, size_t *len, size_t *off) { - char *copy, *copy0, *endptr, *ptr, *saved; + char *copy, *copy0, *endptr, *ptr, *saved, *trimmed; const char *value; size_t valuelen; - u_long limit = ULONG_MAX; + u_long limit = 0; /* Make a copy of the key. */ copy0 = copy = xmalloc(keylen + 1); @@ -256,11 +256,14 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, value = ""; saved = NULL; } - valuelen = strlen(value); /* Truncate the value if needed. */ - if (valuelen > limit) - valuelen = limit; + if (limit != 0) { + value = trimmed = utf8_trimcstr(value, limit); + free(saved); + saved = trimmed; + } + valuelen = strlen(value); /* Expand the buffer and copy in the value. */ while (*len - *off < valuelen + 1) { diff --git a/tmux.h b/tmux.h index 6787783e..ed0f2e44 100644 --- a/tmux.h +++ b/tmux.h @@ -2306,7 +2306,7 @@ struct winlink *session_new(struct session *, const char *, const char *, struct winlink *session_attach( struct session *, struct window *, int, char **); int session_detach(struct session *, struct winlink *); -struct winlink* session_has(struct session *, struct window *); +struct winlink *session_has(struct session *, struct window *); int session_next(struct session *, int); int session_previous(struct session *, int); int session_select(struct session *, int); @@ -2322,12 +2322,17 @@ void session_group_synchronize1(struct session *, struct session *); void session_renumber_windows(struct session *); /* utf8.c */ -void utf8_build(void); -int utf8_open(struct utf8_data *, u_char); -int utf8_append(struct utf8_data *, u_char); -u_int utf8_combine(const struct utf8_data *); -u_int utf8_split2(u_int, u_char *); -int utf8_strvis(char *, const char *, size_t, int); +void utf8_build(void); +void utf8_set(struct utf8_data *, u_char); +int utf8_open(struct utf8_data *, u_char); +int utf8_append(struct utf8_data *, u_char); +u_int utf8_combine(const struct utf8_data *); +u_int utf8_split2(u_int, u_char *); +int utf8_strvis(char *, const char *, size_t, int); +struct utf8_data *utf8_fromcstr(const char *); +char *utf8_tocstr(struct utf8_data *); +u_int utf8_cstrwidth(const char *); +char *utf8_trimcstr(const char *, u_int); /* procname.c */ char *get_proc_name(int, char *); diff --git a/utf8.c b/utf8.c index 945715dd..78ed1675 100644 --- a/utf8.c +++ b/utf8.c @@ -18,6 +18,7 @@ #include +#include #include #include @@ -199,6 +200,16 @@ int utf8_overlap(struct utf8_width_entry *, struct utf8_width_entry *); u_int utf8_combine(const struct utf8_data *); u_int utf8_width(const struct utf8_data *); +/* Set a single character. */ +void +utf8_set(struct utf8_data *utf8data, u_char ch) +{ + *utf8data->data = ch; + utf8data->size = 1; + + utf8data->width = 1; +} + /* * Open UTF-8 sequence. * @@ -392,3 +403,111 @@ utf8_strvis(char *dst, const char *src, size_t len, int flag) *dst = '\0'; return (dst - start); } + +/* + * Convert a string into a buffer of UTF-8 characters. Terminated by size == 0. + * Caller frees. + */ +struct utf8_data * +utf8_fromcstr(const char *src) +{ + struct utf8_data *dst; + size_t n; + int more; + + dst = NULL; + + n = 0; + while (*src != '\0') { + dst = xrealloc(dst, n + 1, sizeof *dst); + if (utf8_open(&dst[n], *src)) { + more = 1; + while (*++src != '\0' && more) + more = utf8_append(&dst[n], *src); + if (!more) { + n++; + continue; + } + src -= dst[n].have; + } + utf8_set(&dst[n], *src); + src++; + + n++; + } + + dst = xrealloc(dst, n + 1, sizeof *dst); + dst[n].size = 0; + return (dst); +} + +/* Convert from a buffer of UTF-8 characters into a string. Caller frees. */ +char * +utf8_tocstr(struct utf8_data *src) +{ + char *dst; + size_t n; + + dst = NULL; + + n = 0; + for(; src->size != 0; src++) { + dst = xrealloc(dst, n + src->size, 1); + memcpy(dst + n, src->data, src->size); + n += src->size; + } + + dst = xrealloc(dst, n + 1, 1); + dst[n] = '\0'; + return (dst); +} + +/* Get width of UTF-8 string. */ +u_int +utf8_cstrwidth(const char *s) +{ + struct utf8_data tmp; + u_int width; + int more; + + width = 0; + while (*s != '\0') { + if (utf8_open(&tmp, *s)) { + more = 1; + while (*++s != '\0' && more) + more = utf8_append(&tmp, *s); + if (!more) { + width += tmp.width; + continue; + } + s -= tmp.have; + } + width++; + s++; + } + return (width); +} + +/* Trim UTF-8 string to width. Caller frees. */ +char * +utf8_trimcstr(const char *s, u_int width) +{ + struct utf8_data *tmp, *next; + char *out; + u_int at; + + tmp = utf8_fromcstr(s); + + at = 0; + for (next = tmp; next->size != 0; next++) { + if (at + next->width > width) { + next->size = 0; + break; + } + at += next->width; + } + + out = utf8_tocstr(tmp); + free(tmp); + return (out); +} From 64613b9d411a7c76a50a2f9c66df345f082fce25 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 17 Apr 2014 15:48:02 +0000 Subject: [PATCH 20/20] #nnT went away a while ago, remove a leftover from the manpage. --- tmux.1 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tmux.1 b/tmux.1 index 6aba515f..44e69f6e 100644 --- a/tmux.1 +++ b/tmux.1 @@ -2535,10 +2535,6 @@ Examples are: #[fg=yellow,bold]#(apm -l)%%#[default] [#S] .Ed .Pp -Where appropriate, special character sequences may be prefixed with a number to -specify the maximum length, for example -.Ql #24T . -.Pp By default, UTF-8 in .Ar string is not interpreted, to enable UTF-8, use the