diff --git a/Makefile.am b/Makefile.am index d305db9c..dd6756b9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -73,7 +73,6 @@ dist_tmux_SOURCES = \ 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/arguments.c b/arguments.c index d4e5e53f..fd656b14 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/cfg.c b/cfg.c index bfcdaea4..d12af67d 100644 --- a/cfg.c +++ b/cfg.c @@ -17,7 +17,6 @@ */ #include -#include #include #include diff --git a/client.c b/client.c index 277efb65..2d4a93b5 100644 --- a/client.c +++ b/client.c @@ -25,8 +25,6 @@ #include #include -#include -#include #include #include #include diff --git a/cmd-break-pane.c b/cmd-break-pane.c index d0a5a450..fe7891e9 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-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-find-window.c b/cmd-find-window.c index 647cc8fb..bef9afee 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-join-pane.c b/cmd-join-pane.c index 1a710cec..000fdba9 100644 --- a/cmd-join-pane.c +++ b/cmd-join-pane.c @@ -138,11 +138,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/cmd-list.c b/cmd-list.c index 08e2067c..7ef8d1c5 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/cmd-lock-server.c b/cmd-lock-server.c index 2b591ecf..5e0f6e0f 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 c190e972..3071bd64 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -55,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"); @@ -189,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"); @@ -197,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 58a5eb65..6e9fea50 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-queue.c b/cmd-queue.c index 17955b82..f4b3b97c 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-respawn-pane.c b/cmd-respawn-pane.c index bcde2754..9ac5b0b8 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 e6d913cf..d891eff3 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-run-shell.c b/cmd-run-shell.c index f5231814..a91968d0 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-save-buffer.c b/cmd-save-buffer.c index 3788fc22..f08f80c7 100644 --- a/cmd-save-buffer.c +++ b/cmd-save-buffer.c @@ -111,7 +111,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"); } @@ -141,7 +141,6 @@ do_print: return (CMD_RETURN_ERROR); } msg = NULL; - msglen = 0; used = 0; while (used != pb->size) { diff --git a/cmd-select-layout.c b/cmd-select-layout.c index 053f3e40..37cd22c2 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 5ae4e5c3..f55b0d30 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,15 +252,13 @@ 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); - if (!args_has(args, 'q')) { - cmdq_info(cmdq, "set option: %s -> %s", optstr, - valstr); - } } return (CMD_RETURN_NORMAL); } @@ -261,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; @@ -275,19 +282,16 @@ 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); } /* 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 args *args = self->args; struct options_entry *o; - const char *s; if (oe->type != OPTIONS_TABLE_FLAG && value == NULL) { cmdq_error(cmdq, "empty value"); @@ -327,17 +331,14 @@ 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); } /* 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; @@ -358,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; @@ -375,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; @@ -390,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; @@ -405,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; @@ -420,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/cmd-show-options.c b/cmd-show-options.c index 943353f6..bf3cfef5 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, diff --git a/cmd-split-window.c b/cmd-split-window.c index c43cb96b..9c4734be 100644 --- a/cmd-split-window.c +++ b/cmd-split-window.c @@ -60,7 +60,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; @@ -68,6 +68,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); @@ -147,8 +148,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/cmd-switch-client.c b/cmd-switch-client.c index d8f7346f..9e7967cd 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/cmd.c b/cmd.c index a7a71a62..f2d88c05 100644 --- a/cmd.c +++ b/cmd.c @@ -34,7 +34,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/environ.c b/environ.c index 3c0a5cb2..f04afd15 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/format.c b/format.c index 29e26525..6f988b9a 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) { @@ -487,8 +490,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/grid-view.c b/grid-view.c index 13385cd1..e75b6049 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/grid.c b/grid.c index 83270754..a84a58b5 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/input.c b/input.c index ee46c982..b6c27cbe 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/job.c b/job.c index d7bd852b..47f25d01 100644 --- a/job.c +++ b/job.c @@ -59,6 +59,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); diff --git a/key-bindings.c b/key-bindings.c index 86048ea6..f725508b 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/layout-set.c b/layout-set.c index 646528ba..377002f4 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/options-table.c b/options-table.c index c73ac84d..8d680b3c 100644 --- a/options-table.c +++ b/options-table.c @@ -27,8 +27,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. */ @@ -89,7 +89,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", @@ -490,11 +490,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 @@ -532,7 +527,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", @@ -628,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, @@ -734,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/osdep-openbsd.c b/osdep-openbsd.c index 0a4c1445..9d88fb04 100644 --- a/osdep-openbsd.c +++ b/osdep-openbsd.c @@ -99,7 +99,7 @@ osdep_get_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) diff --git a/screen-write.c b/screen-write.c index 0de1df40..325fb9a4 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-client.c b/server-client.c index 2c407b8c..e225de30 100644 --- a/server-client.c +++ b/server-client.c @@ -118,6 +118,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); diff --git a/server-fn.c b/server-fn.c index 30626984..e0859f70 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-window.c b/server-window.c index 900060b5..61be1b80 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/server.c b/server.c index f372de4f..c8bc7edd 100644 --- a/server.c +++ b/server.c @@ -217,7 +217,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/session.c b/session.c index 07307710..ae6f35c9 100644 --- a/session.c +++ b/session.c @@ -84,8 +84,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; @@ -131,7 +132,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); } @@ -225,8 +226,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; @@ -249,8 +250,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/status.c b/status.c index af9dd7bc..eed31dc5 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 06a5d598..c05eacfd 100644 --- a/tmux.1 +++ b/tmux.1 @@ -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 @@ -1159,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 @@ -2077,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 , @@ -2142,12 +2110,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 @@ -2577,10 +2539,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 @@ -2674,15 +2632,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 @@ -2864,14 +2813,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 @@ -2944,14 +2885,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 , @@ -3155,7 +3088,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" @@ -3317,18 +3249,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.c b/tmux.c index 7374dd5d..631e8502 100644 --- a/tmux.c +++ b/tmux.c @@ -209,7 +209,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; #if defined(DEBUG) && defined(__OpenBSD__) malloc_options = (char *) "AFGJPX"; @@ -217,7 +217,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:uUVv")) != -1) { @@ -250,7 +250,6 @@ main(int argc, char **argv) label = xstrdup(optarg); break; case 'q': - quiet = 1; break; case 'S': free(path); @@ -297,11 +296,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 dacda666..6f29126c 100644 --- a/tmux.h +++ b/tmux.h @@ -815,8 +815,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; @@ -987,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; @@ -1756,7 +1757,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; @@ -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 *); @@ -2127,9 +2126,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); @@ -2139,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 *, @@ -2153,8 +2153,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); @@ -2290,7 +2290,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 *); @@ -2298,12 +2298,12 @@ 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 *); -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); @@ -2319,12 +2319,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); /* osdep-*.c */ char *osdep_get_name(int, char *); @@ -2355,7 +2360,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 */ diff --git a/tty-term.c b/tty-term.c index 7f8a2d5b..8e500f2f 100644 --- a/tty-term.c +++ b/tty-term.c @@ -512,7 +512,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, 0, 0, 0, 0, 0, 0, 0)); } diff --git a/tty.c b/tty.c index 02b74ee6..e17a134d 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)); @@ -547,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 20e35137..4b2560c4 100644 --- a/utf8.c +++ b/utf8.c @@ -18,6 +18,7 @@ #include +#include #include #include "tmux.h" @@ -200,6 +201,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. * @@ -248,8 +259,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); @@ -394,3 +404,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); +} diff --git a/window-choose.c b/window-choose.c index e75858ef..86f37ed5 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; } diff --git a/window-copy.c b/window-copy.c index 9aaf554c..afa6d4d1 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); @@ -2031,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; @@ -2082,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 9a26b904..ee851bde 100644 --- a/window.c +++ b/window.c @@ -17,13 +17,11 @@ */ #include -#include #include #include #include -#include -#include +#include #include #include #include @@ -309,8 +307,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; @@ -320,7 +318,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); } @@ -588,7 +587,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; @@ -600,6 +599,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); @@ -696,8 +701,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) @@ -810,8 +813,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]; @@ -867,6 +871,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); @@ -1170,7 +1176,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;