diff --git a/cmd-set-option.c b/cmd-set-option.c index a46460a8..c246743c 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -128,8 +128,13 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq) oo = &global_w_options; else { wl = cmd_find_window(cmdq, args_get(args, 't'), NULL); - if (wl == NULL) + if (wl == NULL) { + cmdq_error(cmdq, + "couldn't set '%s'%s", optstr, + (!args_has(args, 't') && !args_has(args, + 'g')) ? " need target window or -g" : ""); return (CMD_RETURN_ERROR); + } oo = &wl->window->options; } } else if (table == session_options_table) { @@ -137,8 +142,13 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq) oo = &global_s_options; else { s = cmd_find_session(cmdq, args_get(args, 't'), 0); - if (s == NULL) + if (s == NULL) { + cmdq_error(cmdq, + "couldn't set '%s'%s", optstr, + (!args_has(args, 't') && !args_has(args, + 'g')) ? " need target session or -g" : ""); return (CMD_RETURN_ERROR); + } oo = &s->options; } } else { diff --git a/format.c b/format.c index 811068ad..8c4c7842 100644 --- a/format.c +++ b/format.c @@ -460,6 +460,8 @@ format_window_pane(struct format_tree *ft, struct window_pane *wp) format_add(ft, "pane_dead", "%d", wp->fd == -1); format_add(ft, "pane_in_mode", "%d", wp->screen != &wp->base); + format_add(ft, "pane_synchronized", "%d", + !!options_get_number(&wp->window->options, "synchronize-panes")); if (wp->tty != NULL) format_add(ft, "pane_tty", "%s", wp->tty); diff --git a/mode-key.c b/mode-key.c index 94115ebb..1ed6d40b 100644 --- a/mode-key.c +++ b/mode-key.c @@ -35,9 +35,7 @@ * * vi command mode is handled by having a mode flag in the struct which allows * two sets of bindings to be swapped between. A couple of editing commands - * (MODEKEYEDIT_SWITCHMODE, MODEKEYEDIT_SWITCHMODEAPPEND, - * MODEKEYEDIT_SWITCHMODEAPPENDLINE, and MODEKEYEDIT_SWITCHMODEBEGINLINE) - * are special-cased to do this. + * (any matching MODEKEYEDIT_SWITCHMODE*) are special-cased to do this. */ /* Edit keys command strings. */ @@ -67,6 +65,9 @@ const struct mode_key_cmdstr mode_key_cmdstr_edit[] = { { MODEKEYEDIT_SWITCHMODEAPPEND, "switch-mode-append" }, { MODEKEYEDIT_SWITCHMODEAPPENDLINE, "switch-mode-append-line" }, { MODEKEYEDIT_SWITCHMODEBEGINLINE, "switch-mode-begin-line" }, + { MODEKEYEDIT_SWITCHMODECHANGELINE, "switch-mode-change-line" }, + { MODEKEYEDIT_SWITCHMODESUBSTITUTE, "switch-mode-substitute" }, + { MODEKEYEDIT_SWITCHMODESUBSTITUTELINE, "switch-mode-substitute-line" }, { MODEKEYEDIT_TRANSPOSECHARS, "transpose-chars" }, { 0, NULL } @@ -166,9 +167,11 @@ const struct mode_key_entry mode_key_vi_edit[] = { { '0', 1, MODEKEYEDIT_STARTOFLINE }, { 'A', 1, MODEKEYEDIT_SWITCHMODEAPPENDLINE }, { 'B', 1, MODEKEYEDIT_PREVIOUSSPACE }, + { 'C', 1, MODEKEYEDIT_SWITCHMODECHANGELINE }, { 'D', 1, MODEKEYEDIT_DELETETOENDOFLINE }, { 'E', 1, MODEKEYEDIT_NEXTSPACEEND }, { 'I', 1, MODEKEYEDIT_SWITCHMODEBEGINLINE }, + { 'S', 1, MODEKEYEDIT_SWITCHMODESUBSTITUTELINE }, { 'W', 1, MODEKEYEDIT_NEXTSPACE }, { 'X', 1, MODEKEYEDIT_BACKSPACE }, { '\003' /* C-c */, 1, MODEKEYEDIT_CANCEL }, @@ -185,6 +188,7 @@ const struct mode_key_entry mode_key_vi_edit[] = { { 'k', 1, MODEKEYEDIT_HISTORYUP }, { 'l', 1, MODEKEYEDIT_CURSORRIGHT }, { 'p', 1, MODEKEYEDIT_PASTE }, + { 's', 1, MODEKEYEDIT_SWITCHMODESUBSTITUTE }, { 'w', 1, MODEKEYEDIT_NEXTWORD }, { 'x', 1, MODEKEYEDIT_DELETE }, { KEYC_BSPACE, 1, MODEKEYEDIT_BACKSPACE }, @@ -227,8 +231,8 @@ const struct mode_key_entry mode_key_vi_choice[] = { { KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP }, { KEYC_UP, 0, MODEKEYCHOICE_UP }, { ' ', 0, MODEKEYCHOICE_TREE_TOGGLE }, - { KEYC_LEFT, 0, MODEKEYCHOICE_TREE_COLLAPSE }, - { KEYC_RIGHT, 0, MODEKEYCHOICE_TREE_EXPAND }, + { KEYC_LEFT, 0, MODEKEYCHOICE_TREE_COLLAPSE }, + { KEYC_RIGHT, 0, MODEKEYCHOICE_TREE_EXPAND }, { KEYC_LEFT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_COLLAPSE_ALL }, { KEYC_RIGHT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_EXPAND_ALL }, @@ -369,8 +373,8 @@ const struct mode_key_entry mode_key_emacs_choice[] = { { KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP }, { KEYC_UP, 0, MODEKEYCHOICE_UP }, { ' ', 0, MODEKEYCHOICE_TREE_TOGGLE }, - { KEYC_LEFT, 0, MODEKEYCHOICE_TREE_COLLAPSE }, - { KEYC_RIGHT, 0, MODEKEYCHOICE_TREE_EXPAND }, + { KEYC_LEFT, 0, MODEKEYCHOICE_TREE_COLLAPSE }, + { KEYC_RIGHT, 0, MODEKEYCHOICE_TREE_EXPAND }, { KEYC_LEFT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_COLLAPSE_ALL }, { KEYC_RIGHT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_EXPAND_ALL }, @@ -545,6 +549,9 @@ mode_key_lookup(struct mode_key_data *mdata, int key, const char **arg) case MODEKEYEDIT_SWITCHMODEAPPEND: case MODEKEYEDIT_SWITCHMODEAPPENDLINE: case MODEKEYEDIT_SWITCHMODEBEGINLINE: + case MODEKEYEDIT_SWITCHMODECHANGELINE: + case MODEKEYEDIT_SWITCHMODESUBSTITUTE: + case MODEKEYEDIT_SWITCHMODESUBSTITUTELINE: mdata->mode = 1 - mdata->mode; /* FALLTHROUGH */ default: diff --git a/server-fn.c b/server-fn.c index 7ef64138..86e2054e 100644 --- a/server-fn.c +++ b/server-fn.c @@ -262,8 +262,9 @@ server_lock_client(struct client *c) void server_kill_window(struct window *w) { - struct session *s, *next_s; - struct winlink *wl; + struct session *s, *next_s, *target_s; + struct session_group *sg; + struct winlink *wl; next_s = RB_MIN(sessions, &sessions); while (next_s != NULL) { @@ -280,8 +281,13 @@ server_kill_window(struct window *w) server_redraw_session_group(s); } - if (options_get_number(&s->options, "renumber-windows")) - session_renumber_windows(s); + if (options_get_number(&s->options, "renumber-windows")) { + if ((sg = session_group_find(s)) != NULL) { + TAILQ_FOREACH(target_s, &sg->sessions, gentry) + session_renumber_windows(target_s); + } else + session_renumber_windows(s); + } } recalculate_sizes(); } diff --git a/status.c b/status.c index 385ec8e1..358f809c 100644 --- a/status.c +++ b/status.c @@ -142,10 +142,8 @@ status_set_window_at(struct client *c, u_int x) x += c->wlmouse; RB_FOREACH(wl, winlinks, &s->windows) { - if (x < wl->status_width && - session_select(s, wl->idx) == 0) { + if (x < wl->status_width && session_select(s, wl->idx) == 0) server_redraw_session(s); - } x -= wl->status_width + 1; } } @@ -938,6 +936,7 @@ status_prompt_redraw(struct client *c) off = 0; memcpy(&gc, &grid_default_cell, sizeof gc); + /* Change colours for command mode. */ if (c->prompt_mdata.mode == 1) { colour_set_fg(&gc, options_get_number(&s->options, "message-command-fg")); @@ -1099,6 +1098,7 @@ status_prompt_key(struct client *c, int key) } break; case MODEKEYEDIT_DELETE: + case MODEKEYEDIT_SWITCHMODESUBSTITUTE: if (c->prompt_index != size) { memmove(c->prompt_buffer + c->prompt_index, c->prompt_buffer + c->prompt_index + 1, @@ -1107,11 +1107,13 @@ status_prompt_key(struct client *c, int key) } break; case MODEKEYEDIT_DELETELINE: + case MODEKEYEDIT_SWITCHMODESUBSTITUTELINE: *c->prompt_buffer = '\0'; c->prompt_index = 0; c->flags |= CLIENT_STATUS; break; case MODEKEYEDIT_DELETETOENDOFLINE: + case MODEKEYEDIT_SWITCHMODECHANGELINE: if (c->prompt_index < size) { c->prompt_buffer[c->prompt_index] = '\0'; c->flags |= CLIENT_STATUS; @@ -1190,6 +1192,11 @@ status_prompt_key(struct client *c, int key) break; } + /* Back up to the end-of-word like vi. */ + if (options_get_number(oo, "status-keys") == MODEKEY_VI && + c->prompt_index != 0) + c->prompt_index--; + c->flags |= CLIENT_STATUS; break; case MODEKEYEDIT_PREVIOUSSPACE: diff --git a/tmux.1 b/tmux.1 index 0aeb5a17..11251790 100644 --- a/tmux.1 +++ b/tmux.1 @@ -3072,6 +3072,7 @@ The following variables are available, where appropriate: .It Li "pane_height" Ta "" Ta "Height of pane" .It Li "pane_id" Ta "#D" Ta "Unique pane ID" .It Li "pane_in_mode" Ta "" Ta "If pane is in a mode" +.It Li "pane_synchronized" Ta "" Ta "If pane is synchronized" .It Li "pane_index" Ta "#P" Ta "Index of pane" .It Li "pane_pid" Ta "" Ta "PID of first process in pane" .It Li "pane_start_command" Ta "" Ta "Command pane started with" diff --git a/tmux.h b/tmux.h index 5dd86d38..eb53d3b4 100644 --- a/tmux.h +++ b/tmux.h @@ -541,6 +541,9 @@ enum mode_key_cmd { MODEKEYEDIT_SWITCHMODEAPPEND, MODEKEYEDIT_SWITCHMODEAPPENDLINE, MODEKEYEDIT_SWITCHMODEBEGINLINE, + MODEKEYEDIT_SWITCHMODECHANGELINE, + MODEKEYEDIT_SWITCHMODESUBSTITUTE, + MODEKEYEDIT_SWITCHMODESUBSTITUTELINE, MODEKEYEDIT_TRANSPOSECHARS, /* Menu (choice) keys. */ diff --git a/window-copy.c b/window-copy.c index 51a8f108..75fff92f 100644 --- a/window-copy.c +++ b/window-copy.c @@ -1116,7 +1116,7 @@ window_copy_write_line( struct options *oo = &wp->window->options; struct grid_cell gc; char hdr[32]; - size_t last, xoff = 0, size = 0; + size_t last, xoff = 0, size = 0; window_mode_attrs(&gc, oo); @@ -1894,6 +1894,7 @@ void 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; struct screen *back_s = data->backing; u_int px, py, xx, yy; int expected = 1; @@ -1927,6 +1928,10 @@ window_copy_cursor_next_word_end(struct window_pane *wp, const char *separators) expected = !expected; } while (expected == 0); + /* Back up to the end-of-word like vi. */ + if (options_get_number(oo, "status-keys") == MODEKEY_VI && px != 0) + px--; + window_copy_update_cursor(wp, px, data->cy); if (window_copy_update_selection(wp)) window_copy_redraw_lines(wp, data->cy, 1);