diff --git a/cmd-rotate-window.c b/cmd-rotate-window.c index 3c15b54e..7a1d9b28 100644 --- a/cmd-rotate-window.c +++ b/cmd-rotate-window.c @@ -43,6 +43,7 @@ const struct cmd_entry cmd_rotate_window_entry = { static enum cmd_retval cmd_rotate_window_exec(struct cmd *self, struct cmdq_item *item) { + struct cmd_find_state *current = &item->shared->current; struct winlink *wl = item->target.wl; struct window *w = wl->window; struct window_pane *wp, *wp2; @@ -77,6 +78,7 @@ cmd_rotate_window_exec(struct cmd *self, struct cmdq_item *item) if ((wp = TAILQ_PREV(w->active, window_panes, entry)) == NULL) wp = TAILQ_LAST(&w->panes, window_panes); window_set_active_pane(w, wp); + cmd_find_from_winlink_pane(current, wl, wp); server_redraw_window(w); } else { wp = TAILQ_FIRST(&w->panes); @@ -104,6 +106,7 @@ cmd_rotate_window_exec(struct cmd *self, struct cmdq_item *item) if ((wp = TAILQ_NEXT(w->active, entry)) == NULL) wp = TAILQ_FIRST(&w->panes); window_set_active_pane(w, wp); + cmd_find_from_winlink_pane(current, wl, wp); server_redraw_window(w); } diff --git a/format.c b/format.c index 6659c577..ddc5a7a5 100644 --- a/format.c +++ b/format.c @@ -130,6 +130,7 @@ struct format_entry { /* Format entry tree. */ struct format_tree { struct window *w; + struct winlink *wl; struct session *s; struct window_pane *wp; @@ -420,7 +421,7 @@ format_cb_session_alerts(struct format_tree *ft, struct format_entry *fe) { struct session *s = ft->s; struct winlink *wl; - char alerts[256], tmp[16]; + char alerts[1024], tmp[16]; if (s == NULL) return; @@ -444,6 +445,48 @@ format_cb_session_alerts(struct format_tree *ft, struct format_entry *fe) fe->value = xstrdup(alerts); } +/* Callback for session_stack. */ +static void +format_cb_session_stack(struct format_tree *ft, struct format_entry *fe) +{ + struct session *s = ft->s; + struct winlink *wl; + char result[1024], tmp[16]; + + if (s == NULL) + return; + + xsnprintf(result, sizeof result, "%u", s->curw->idx); + TAILQ_FOREACH(wl, &s->lastw, sentry) { + xsnprintf(tmp, sizeof tmp, "%u", wl->idx); + + if (*result != '\0') + strlcat(result, ",", sizeof result); + strlcat(result, tmp, sizeof result); + } + fe->value = xstrdup(result); +} + +/* Callback for window_stack_index. */ +static void +format_cb_window_stack_index(struct format_tree *ft, struct format_entry *fe) +{ + struct session *s = ft->wl->session; + struct winlink *wl; + u_int idx; + + idx = 0; + TAILQ_FOREACH(wl, &s->lastw, sentry) { + idx++; + if (wl == ft->wl) + break; + } + if (wl != NULL) + xasprintf(&fe->value, "%u", idx); + else + fe->value = xstrdup("0"); +} + /* Callback for window_layout. */ static void format_cb_window_layout(struct format_tree *ft, struct format_entry *fe) @@ -1220,6 +1263,7 @@ format_defaults_session(struct format_tree *ft, struct session *s) format_add(ft, "session_many_attached", "%d", s->attached > 1); format_add_cb(ft, "session_alerts", format_cb_session_alerts); + format_add_cb(ft, "session_stack", format_cb_session_stack); } /* Set default format keys for a client. */ @@ -1306,10 +1350,12 @@ format_defaults_winlink(struct format_tree *ft, struct winlink *wl) if (ft->w == NULL) ft->w = wl->window; + ft->wl = wl; format_defaults_window(ft, w); format_add(ft, "window_index", "%d", wl->idx); + format_add_cb(ft, "window_stack_index", format_cb_window_stack_index); format_add(ft, "window_flags", "%s", window_printable_flags(wl)); format_add(ft, "window_active", "%d", wl == s->curw); @@ -1364,6 +1410,9 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp) } format_add(ft, "pane_in_mode", "%d", wp->screen != &wp->base); + if (wp->mode != NULL) + format_add(ft, "pane_mode", "%s", wp->mode->name); + format_add(ft, "pane_synchronized", "%d", !!options_get_number(wp->window->options, "synchronize-panes")); format_add(ft, "pane_search_string", "%s", diff --git a/input-keys.c b/input-keys.c index 5773d016..9f0094dd 100644 --- a/input-keys.c +++ b/input-keys.c @@ -200,6 +200,7 @@ input_key(struct window_pane *wp, key_code key, struct mouse_event *m) return; } } + key &= ~KEYC_XTERM; /* Otherwise look the key up in the table. */ for (i = 0; i < nitems(input_keys); i++) { diff --git a/key-bindings.c b/key-bindings.c index 60dbe544..9e327655 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -92,7 +92,7 @@ key_bindings_add(const char *name, key_code key, int repeat, table = key_bindings_get_table(name, 1); - bd_find.key = key; + bd_find.key = (key & ~KEYC_XTERM); bd = RB_FIND(key_bindings, &table->key_bindings, &bd_find); if (bd != NULL) { RB_REMOVE(key_bindings, &table->key_bindings, bd); @@ -119,7 +119,7 @@ key_bindings_remove(const char *name, key_code key) if (table == NULL) return; - bd_find.key = key; + bd_find.key = (key & ~KEYC_XTERM); bd = RB_FIND(key_bindings, &table->key_bindings, &bd_find); if (bd == NULL) return; diff --git a/server-client.c b/server-client.c index ee1ca322..94548724 100644 --- a/server-client.c +++ b/server-client.c @@ -902,7 +902,7 @@ retry: log_debug("currently repeating"); /* Try to see if there is a key binding in the current table. */ - bd_find.key = key; + bd_find.key = (key & ~KEYC_XTERM); bd = RB_FIND(key_bindings, &table->key_bindings, &bd_find); if (bd != NULL) { /* diff --git a/tmux.1 b/tmux.1 index 66220d89..5284f5cc 100644 --- a/tmux.1 +++ b/tmux.1 @@ -3566,6 +3566,7 @@ The following variables are available, where appropriate: .It Li "pane_input_off" Ta "" Ta "If input to pane is disabled" .It Li "pane_index" Ta "#P" Ta "Index of pane" .It Li "pane_left" Ta "" Ta "Left of pane" +.It Li "pane_mode" Ta "" Ta "Name of pane mode, if any." .It Li "pane_pid" Ta "" Ta "PID of first process in pane" .It Li "pane_right" Ta "" Ta "Right of pane" .It Li "pane_search_string" Ta "" Ta "Last search string in copy mode" @@ -3591,6 +3592,7 @@ The following variables are available, where appropriate: .It Li "session_id" Ta "" Ta "Unique session ID" .It Li "session_many_attached" Ta "" Ta "1 if multiple clients attached" .It Li "session_name" Ta "#S" Ta "Name of session" +.It Li "session_stack" Ta "" Ta "Window indexes in most recent order" .It Li "session_width" Ta "" Ta "Width of session" .It Li "session_windows" Ta "" Ta "Number of windows in session" .It Li "socket_path" Ta "" Ta "Server socket path" @@ -3611,6 +3613,7 @@ The following variables are available, where appropriate: .It Li "window_name" Ta "#W" Ta "Name of window" .It Li "window_panes" Ta "" Ta "Number of panes in window" .It Li "window_silence_flag" Ta "" Ta "1 if window has silence alert" +.It Li "window_stack_index" Ta "" Ta "Index in session most recent stack" .It Li "window_visible_layout" Ta "" Ta "Window layout description, respecting zoomed window panes" .It Li "window_width" Ta "" Ta "Width of window" .It Li "window_zoomed_flag" Ta "" Ta "1 if window is zoomed" diff --git a/tmux.h b/tmux.h index 845881ba..9e0d67c6 100644 --- a/tmux.h +++ b/tmux.h @@ -95,9 +95,10 @@ struct tmuxproc; #define KEYC_ESCAPE 0x200000000000ULL #define KEYC_CTRL 0x400000000000ULL #define KEYC_SHIFT 0x800000000000ULL +#define KEYC_XTERM 0x1000000000000ULL /* Mask to obtain key w/o modifiers. */ -#define KEYC_MASK_MOD (KEYC_ESCAPE|KEYC_CTRL|KEYC_SHIFT) +#define KEYC_MASK_MOD (KEYC_ESCAPE|KEYC_CTRL|KEYC_SHIFT|KEYC_XTERM) #define KEYC_MASK_KEY (~KEYC_MASK_MOD) /* Is this a mouse key? */ @@ -692,15 +693,18 @@ struct screen_write_ctx { * right function to handle input and output. */ struct window_mode { - struct screen *(*init)(struct window_pane *); - void (*free)(struct window_pane *); - void (*resize)(struct window_pane *, u_int, u_int); - void (*key)(struct window_pane *, struct client *, struct session *, - key_code, struct mouse_event *); + const char *name; - const char *(*key_table)(struct window_pane *); - void (*command)(struct window_pane *, struct client *, - struct session *, struct args *, struct mouse_event *); + struct screen *(*init)(struct window_pane *); + void (*free)(struct window_pane *); + void (*resize)(struct window_pane *, u_int, u_int); + void (*key)(struct window_pane *, struct client *, + struct session *, key_code, struct mouse_event *); + + const char *(*key_table)(struct window_pane *); + void (*command)(struct window_pane *, struct client *, + struct session *, struct args *, + struct mouse_event *); }; #define WINDOW_MODE_TIMEOUT 180 diff --git a/tty-keys.c b/tty-keys.c index a011fcab..d7797a9c 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -257,67 +257,70 @@ static const struct tty_default_key_code tty_default_code_keys[] = { { TTYC_KCUB1, KEYC_LEFT }, { TTYC_KCUF1, KEYC_RIGHT }, - /* Key and modifier capabilities. */ - { TTYC_KDC2, KEYC_DC|KEYC_SHIFT }, - { TTYC_KDC3, KEYC_DC|KEYC_ESCAPE }, - { TTYC_KDC4, KEYC_DC|KEYC_SHIFT|KEYC_ESCAPE }, - { TTYC_KDC5, KEYC_DC|KEYC_CTRL }, - { TTYC_KDC6, KEYC_DC|KEYC_SHIFT|KEYC_CTRL }, - { TTYC_KDC7, KEYC_DC|KEYC_ESCAPE|KEYC_CTRL }, - { TTYC_KDN2, KEYC_DOWN|KEYC_SHIFT }, - { TTYC_KDN3, KEYC_DOWN|KEYC_ESCAPE }, - { TTYC_KDN4, KEYC_DOWN|KEYC_SHIFT|KEYC_ESCAPE }, - { TTYC_KDN5, KEYC_DOWN|KEYC_CTRL }, - { TTYC_KDN6, KEYC_DOWN|KEYC_SHIFT|KEYC_CTRL }, - { TTYC_KDN7, KEYC_DOWN|KEYC_ESCAPE|KEYC_CTRL }, - { TTYC_KEND2, KEYC_END|KEYC_SHIFT }, - { TTYC_KEND3, KEYC_END|KEYC_ESCAPE }, - { TTYC_KEND4, KEYC_END|KEYC_SHIFT|KEYC_ESCAPE }, - { TTYC_KEND5, KEYC_END|KEYC_CTRL }, - { TTYC_KEND6, KEYC_END|KEYC_SHIFT|KEYC_CTRL }, - { TTYC_KEND7, KEYC_END|KEYC_ESCAPE|KEYC_CTRL }, - { TTYC_KHOM2, KEYC_HOME|KEYC_SHIFT }, - { TTYC_KHOM3, KEYC_HOME|KEYC_ESCAPE }, - { TTYC_KHOM4, KEYC_HOME|KEYC_SHIFT|KEYC_ESCAPE }, - { TTYC_KHOM5, KEYC_HOME|KEYC_CTRL }, - { TTYC_KHOM6, KEYC_HOME|KEYC_SHIFT|KEYC_CTRL }, - { TTYC_KHOM7, KEYC_HOME|KEYC_ESCAPE|KEYC_CTRL }, - { TTYC_KIC2, KEYC_IC|KEYC_SHIFT }, - { TTYC_KIC3, KEYC_IC|KEYC_ESCAPE }, - { TTYC_KIC4, KEYC_IC|KEYC_SHIFT|KEYC_ESCAPE }, - { TTYC_KIC5, KEYC_IC|KEYC_CTRL }, - { TTYC_KIC6, KEYC_IC|KEYC_SHIFT|KEYC_CTRL }, - { TTYC_KIC7, KEYC_IC|KEYC_ESCAPE|KEYC_CTRL }, - { TTYC_KLFT2, KEYC_LEFT|KEYC_SHIFT }, - { TTYC_KLFT3, KEYC_LEFT|KEYC_ESCAPE }, - { TTYC_KLFT4, KEYC_LEFT|KEYC_SHIFT|KEYC_ESCAPE }, - { TTYC_KLFT5, KEYC_LEFT|KEYC_CTRL }, - { TTYC_KLFT6, KEYC_LEFT|KEYC_SHIFT|KEYC_CTRL }, - { TTYC_KLFT7, KEYC_LEFT|KEYC_ESCAPE|KEYC_CTRL }, - { TTYC_KNXT2, KEYC_NPAGE|KEYC_SHIFT }, - { TTYC_KNXT3, KEYC_NPAGE|KEYC_ESCAPE }, - { TTYC_KNXT4, KEYC_NPAGE|KEYC_SHIFT|KEYC_ESCAPE }, - { TTYC_KNXT5, KEYC_NPAGE|KEYC_CTRL }, - { TTYC_KNXT6, KEYC_NPAGE|KEYC_SHIFT|KEYC_CTRL }, - { TTYC_KNXT7, KEYC_NPAGE|KEYC_ESCAPE|KEYC_CTRL }, - { TTYC_KPRV2, KEYC_PPAGE|KEYC_SHIFT }, - { TTYC_KPRV3, KEYC_PPAGE|KEYC_ESCAPE }, - { TTYC_KPRV4, KEYC_PPAGE|KEYC_SHIFT|KEYC_ESCAPE }, - { TTYC_KPRV5, KEYC_PPAGE|KEYC_CTRL }, - { TTYC_KPRV6, KEYC_PPAGE|KEYC_SHIFT|KEYC_CTRL }, - { TTYC_KPRV7, KEYC_PPAGE|KEYC_ESCAPE|KEYC_CTRL }, - { TTYC_KRIT2, KEYC_RIGHT|KEYC_SHIFT }, - { TTYC_KRIT3, KEYC_RIGHT|KEYC_ESCAPE }, - { TTYC_KRIT4, KEYC_RIGHT|KEYC_SHIFT|KEYC_ESCAPE }, - { TTYC_KRIT5, KEYC_RIGHT|KEYC_CTRL }, - { TTYC_KRIT6, KEYC_RIGHT|KEYC_SHIFT|KEYC_CTRL }, - { TTYC_KRIT7, KEYC_RIGHT|KEYC_ESCAPE|KEYC_CTRL }, - { TTYC_KUP2, KEYC_UP|KEYC_SHIFT }, - { TTYC_KUP3, KEYC_UP|KEYC_ESCAPE }, - { TTYC_KUP4, KEYC_UP|KEYC_SHIFT|KEYC_ESCAPE }, - { TTYC_KUP5, KEYC_UP|KEYC_CTRL }, - { TTYC_KUP6, KEYC_UP|KEYC_SHIFT|KEYC_CTRL }, - { TTYC_KUP7, KEYC_UP|KEYC_ESCAPE|KEYC_CTRL }, + /* + * Key and modifier capabilities. We set the xterm flag to mark that + * any leading escape means an escape key press and not the modifier. + */ + { TTYC_KDC2, KEYC_DC|KEYC_SHIFT|KEYC_XTERM }, + { TTYC_KDC3, KEYC_DC|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KDC4, KEYC_DC|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KDC5, KEYC_DC|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KDC6, KEYC_DC|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KDC7, KEYC_DC|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KDN2, KEYC_DOWN|KEYC_SHIFT|KEYC_XTERM }, + { TTYC_KDN3, KEYC_DOWN|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KDN4, KEYC_DOWN|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KDN5, KEYC_DOWN|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KDN6, KEYC_DOWN|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KDN7, KEYC_DOWN|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KEND2, KEYC_END|KEYC_SHIFT|KEYC_XTERM }, + { TTYC_KEND3, KEYC_END|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KEND4, KEYC_END|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KEND5, KEYC_END|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KEND6, KEYC_END|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KEND7, KEYC_END|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KHOM2, KEYC_HOME|KEYC_SHIFT|KEYC_XTERM }, + { TTYC_KHOM3, KEYC_HOME|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KHOM4, KEYC_HOME|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KHOM5, KEYC_HOME|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KHOM6, KEYC_HOME|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KHOM7, KEYC_HOME|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KIC2, KEYC_IC|KEYC_SHIFT|KEYC_XTERM }, + { TTYC_KIC3, KEYC_IC|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KIC4, KEYC_IC|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KIC5, KEYC_IC|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KIC6, KEYC_IC|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KIC7, KEYC_IC|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KLFT2, KEYC_LEFT|KEYC_SHIFT|KEYC_XTERM }, + { TTYC_KLFT3, KEYC_LEFT|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KLFT4, KEYC_LEFT|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KLFT5, KEYC_LEFT|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KLFT6, KEYC_LEFT|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KLFT7, KEYC_LEFT|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KNXT2, KEYC_NPAGE|KEYC_SHIFT|KEYC_XTERM }, + { TTYC_KNXT3, KEYC_NPAGE|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KNXT4, KEYC_NPAGE|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KNXT5, KEYC_NPAGE|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KNXT6, KEYC_NPAGE|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KNXT7, KEYC_NPAGE|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KPRV2, KEYC_PPAGE|KEYC_SHIFT|KEYC_XTERM }, + { TTYC_KPRV3, KEYC_PPAGE|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KPRV4, KEYC_PPAGE|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KPRV5, KEYC_PPAGE|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KPRV6, KEYC_PPAGE|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KPRV7, KEYC_PPAGE|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KRIT2, KEYC_RIGHT|KEYC_SHIFT|KEYC_XTERM }, + { TTYC_KRIT3, KEYC_RIGHT|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KRIT4, KEYC_RIGHT|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KRIT5, KEYC_RIGHT|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KRIT6, KEYC_RIGHT|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KRIT7, KEYC_RIGHT|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KUP2, KEYC_UP|KEYC_SHIFT|KEYC_XTERM }, + { TTYC_KUP3, KEYC_UP|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KUP4, KEYC_UP|KEYC_SHIFT|KEYC_ESCAPE|KEYC_XTERM }, + { TTYC_KUP5, KEYC_UP|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KUP6, KEYC_UP|KEYC_SHIFT|KEYC_CTRL|KEYC_XTERM }, + { TTYC_KUP7, KEYC_UP|KEYC_ESCAPE|KEYC_CTRL|KEYC_XTERM }, }; /* Add key to tree. */ @@ -476,6 +479,7 @@ tty_keys_next1(struct tty *tty, const char *buf, size_t len, key_code *key, enum utf8_state more; u_int i; wchar_t wc; + int n; log_debug("%s: next key is %zu (%.*s) (expired=%d)", c->name, len, (int)len, buf, expired); @@ -493,6 +497,13 @@ tty_keys_next1(struct tty *tty, const char *buf, size_t len, key_code *key, return (0); } + /* Is this an an xterm(1) key? */ + n = xterm_keys_find(buf, len, size, key); + if (n == 0) + return (0); + if (n == 1 && !expired) + return (1); + /* Is this valid UTF-8? */ more = utf8_open(&ud, (u_char)*buf); if (more == UTF8_MORE) { @@ -573,6 +584,18 @@ first_key: /* Look for a key without the escape. */ n = tty_keys_next1(tty, buf + 1, len - 1, &key, &size, expired); if (n == 0) { /* found */ + if (key & KEYC_XTERM) { + /* + * We want the escape key as well as the xterm + * key, because the xterm sequence implicitly + * includes the escape (so if we see + * \033\033[1;3D we know it is an Escape + * followed by M-Left, not just M-Left). + */ + key = '\033'; + size = 1; + goto complete_key; + } key |= KEYC_ESCAPE; size++; goto complete_key; @@ -588,13 +611,6 @@ first_key: if (n == 1) goto partial_key; - /* Is this an an xterm(1) key? */ - n = xterm_keys_find(buf, len, &size, &key); - if (n == 0) - goto complete_key; - if (n == 1 && !expired) - goto partial_key; - /* * At this point, we know the key is not partial (with or without * escape). So pass it through even if the timer has not expired. diff --git a/window-choose.c b/window-choose.c index 0e2f1bf9..2f3a1631 100644 --- a/window-choose.c +++ b/window-choose.c @@ -57,6 +57,8 @@ enum window_choose_input_type { }; const struct window_mode window_choose_mode = { + .name = "choose-mode", + .init = window_choose_init, .free = window_choose_free, .resize = window_choose_resize, diff --git a/window-clock.c b/window-clock.c index 94f014fc..d23ac136 100644 --- a/window-clock.c +++ b/window-clock.c @@ -34,6 +34,8 @@ static void window_clock_timer_callback(int, short, void *); static void window_clock_draw_screen(struct window_pane *); const struct window_mode window_clock_mode = { + .name = "clock-mode", + .init = window_clock_init, .free = window_clock_free, .resize = window_clock_resize, diff --git a/window-copy.c b/window-copy.c index 7def63db..8424bfa6 100644 --- a/window-copy.c +++ b/window-copy.c @@ -105,6 +105,8 @@ static void window_copy_move_mouse(struct mouse_event *); static void window_copy_drag_update(struct client *, struct mouse_event *); const struct window_mode window_copy_mode = { + .name = "copy-mode", + .init = window_copy_init, .free = window_copy_free, .resize = window_copy_resize, diff --git a/xterm-keys.c b/xterm-keys.c index 5ffc845f..b10c10db 100644 --- a/xterm-keys.c +++ b/xterm-keys.c @@ -197,7 +197,7 @@ xterm_keys_find(const char *buf, size_t len, size_t *size, key_code *key) if (matched == -1) continue; if (matched == 0) - *key = entry->key | modifiers; + *key = (entry->key|modifiers|KEYC_XTERM); return (matched); } return (-1); @@ -227,8 +227,16 @@ xterm_keys_lookup(key_code key) if (modifiers == 1) return (NULL); + /* + * If this has the escape modifier, but was not originally an xterm + * key, it may be a genuine escape + key. So don't pass it through as + * an xterm key or programs like vi may be confused. + */ + if ((key & (KEYC_ESCAPE|KEYC_XTERM)) == KEYC_ESCAPE) + return (NULL); + /* Otherwise, find the key in the table. */ - key &= ~(KEYC_SHIFT|KEYC_ESCAPE|KEYC_CTRL); + key &= KEYC_MASK_KEY; for (i = 0; i < nitems(xterm_keys_table); i++) { entry = &xterm_keys_table[i]; if (key == entry->key)