The branch, master has been updated
       via  c11f628342e068baff30c7bee48eb62476406145 (commit)
       via  504b97b6a4314a7a052d9b05de746515e2a03628 (commit)
       via  92faa2eaebd32117f01b0b7d7ae81abdfde2d935 (commit)
       via  592cb73a69e23d321a29ae367d52b9e9b4f506c2 (commit)
       via  74b2c40b1b2f38b1aafe4178cb33db63d3be8de0 (commit)
       via  a538141a72882e10988b68d7d1ede94cbb7140c1 (commit)
       via  c4a4bd6ac5748939c7c17beba9e14bee5929c552 (commit)
       via  879de25583a5a0bce57bd816ced96e0caf62c436 (commit)
       via  d174b9cfcc2d4c60bd89804ef63e5ee41ca6d490 (commit)
       via  8e9b6e09485f3400aac9e6cd8a711e2cc1819b03 (commit)
       via  1282bb81fe9fbb1b2ff1b63a9c4e8978444703c4 (commit)
       via  7becf326e3b756016f2df6230db9fcf714d44955 (commit)
       via  73c871ba0a075bdd458a1b4208afd0e9bb293096 (commit)
       via  b6be03f01aaf10230bf4de4c49d56bc7d9bee9bf (commit)
       via  0b39e6427fde3fadb9a3453b6423865829a59ad6 (commit)
      from  63b7a031a52786e9ec72d8d284a46806bfdc848b (commit)

- Log -----------------------------------------------------------------
commit c11f628342e068baff30c7bee48eb62476406145
Merge: 504b97b 63b7a03
Author: Thomas Adam <tho...@xteddy.org>
Commit: Thomas Adam <tho...@xteddy.org>

    Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code

 compat/imsg-buffer.c |    1 -
 compat/imsg.c        |    1 -
 2 files changed, 0 insertions(+), 2 deletions(-)


commit 504b97b6a4314a7a052d9b05de746515e2a03628
Merge: 6525ca5 92faa2e
Author: Thomas Adam <tho...@xteddy.org>
Commit: Thomas Adam <tho...@xteddy.org>

    Merge branch 'obsd-master'
    
    Conflicts:
        tmux.h

 cfg.c               |    2 +-
 cmd-capture-pane.c  |   14 ++-
 cmd-find-window.c   |   67 +++++++------
 cmd-find.c          |    8 +-
 cmd-send-keys.c     |   18 +---
 cmd-switch-client.c |    7 +-
 environ.c           |   25 ++---
 format.c            |    2 -
 grid.c              |   29 ++----
 input.c             |   93 +++++++++++++++++--
 key-bindings.c      |    2 +-
 mode-key.c          |   14 +++
 screen-redraw.c     |    9 +-
 server-client.c     |    5 -
 status.c            |  260 ++++++++++++++++++++++++++++++++++++++-------------
 style.c             |    4 +-
 tmux.1              |    2 -
 tmux.h              |  195 +++++++++++++-------------------------
 window-choose.c     |    9 ++
 window.c            |    2 +-
 20 files changed, 454 insertions(+), 313 deletions(-)

diff --cc tmux.h
index 6d02fac,6d4e29f..725b915
--- a/tmux.h
+++ b/tmux.h
@@@ -30,19 -34,12 +30,20 @@@
  #include <stdio.h>
  #include <termios.h>
  
 +#ifdef HAVE_UTEMPTER
 +#include <utempter.h>
 +#endif
 +
- #include "array.h"
- 
 +#include "compat.h"
 +
 +extern char    *__progname;
 +extern char   **environ;
 +
- /* Default prompt history length. */
- #define PROMPT_HISTORY 100
+ extern char    *__progname;
+ extern char   **environ;
+ 
+ /* Default global configuration file. */
+ #define TMUX_CONF "/etc/tmux.conf"
  
  /*
   * Minimum layout cell size, NOT including separator line. The scroll region


commit 92faa2eaebd32117f01b0b7d7ae81abdfde2d935
Author: nicm <nicm>
Commit: nicm <nicm>

    Put the tty structs together, and tabify.
---
 tmux.h |   96 ++++++++++++++++++++++++++++++++--------------------------------
 1 files changed, 48 insertions(+), 48 deletions(-)

diff --git a/tmux.h b/tmux.h
index f1575d2..6d4e29f 100644
--- a/tmux.h
+++ b/tmux.h
@@ -689,7 +689,7 @@ struct options_entry {
        } type;
 
        char                    *str;
-       long long                num;
+       long long                num;
        struct grid_cell         style;
 
        RB_ENTRY(options_entry) entry;
@@ -804,7 +804,7 @@ struct window_choose_data {
        struct winlink          *wl;
        int                      pane_id;
 
-       char                    *ft_template;
+       char                    *ft_template;
        struct format_tree      *ft;
 
        char                    *command;
@@ -882,7 +882,7 @@ struct window {
        u_int            id;
        char            *name;
        struct event     name_timer;
-       struct timeval   silence_timer;
+       struct timeval   silence_timer;
 
        struct window_pane *active;
        struct window_pane *last;
@@ -923,7 +923,7 @@ struct winlink {
        struct grid_cell status_cell;
        char            *status_text;
 
-       int              flags;
+       int              flags;
 #define WINLINK_BELL 0x1
 #define WINLINK_ACTIVITY 0x2
 #define WINLINK_SILENCE 0x4
@@ -1015,7 +1015,7 @@ struct session {
 #define SESSION_UNATTACHED 0x1 /* not attached to any clients */
        int              flags;
 
-       u_int            attached;
+       u_int            attached;
 
        struct termios  *tio;
 
@@ -1028,33 +1028,6 @@ struct session {
 };
 RB_HEAD(sessions, session);
 
-/* TTY information. */
-struct tty_key {
-       char             ch;
-       int              key;
-
-       struct tty_key  *left;
-       struct tty_key  *right;
-
-       struct tty_key  *next;
-};
-
-struct tty_term {
-       char            *name;
-       u_int            references;
-
-       char             acs[UCHAR_MAX + 1][2];
-
-       struct tty_code  codes[NTTYCODE];
-
-#define TERM_256COLOURS 0x1
-#define TERM_EARLYWRAP 0x2
-       int              flags;
-
-       LIST_ENTRY(tty_term) entry;
-};
-LIST_HEAD(tty_terms, tty_term);
-
 /* Mouse button masks. */
 #define MOUSE_MASK_BUTTONS 3
 #define MOUSE_MASK_SHIFT 4
@@ -1096,6 +1069,33 @@ struct mouse_event {
        u_int   sgr_b;
 };
 
+/* TTY information. */
+struct tty_key {
+       char             ch;
+       int              key;
+
+       struct tty_key  *left;
+       struct tty_key  *right;
+
+       struct tty_key  *next;
+};
+
+struct tty_term {
+       char            *name;
+       u_int            references;
+
+       char             acs[UCHAR_MAX + 1][2];
+
+       struct tty_code  codes[NTTYCODE];
+
+#define TERM_256COLOURS 0x1
+#define TERM_EARLYWRAP 0x2
+       int              flags;
+
+       LIST_ENTRY(tty_term) entry;
+};
+LIST_HEAD(tty_terms, tty_term);
+
 struct tty {
        struct client   *client;
 
@@ -1143,7 +1143,7 @@ struct tty {
        void            (*mouse_drag_update)(struct client *,
                            struct mouse_event *);
        void            (*mouse_drag_release)(struct client *,
-                           struct mouse_event *);
+                           struct mouse_event *);
 
        struct event     key_timer;
        struct tty_key  *key_tree;
@@ -1217,7 +1217,7 @@ struct client {
        void            (*stdin_callback)(struct client *, int, void *);
        void            *stdin_callback_data;
        struct evbuffer *stdin_data;
-       int              stdin_closed;
+       int              stdin_closed;
        struct evbuffer *stdout_data;
        struct evbuffer *stderr_data;
 
@@ -1263,7 +1263,7 @@ struct client {
        int              (*prompt_callbackfn)(void *, const char *);
        void             (*prompt_freefn)(void *);
        void            *prompt_data;
-       u_int            prompt_hindex;
+       u_int            prompt_hindex;
 
 #define PROMPT_SINGLE 0x1
        int              prompt_flags;
@@ -1292,8 +1292,8 @@ RB_HEAD(args_tree, args_entry);
 
 struct args {
        struct args_tree          tree;
-       int                       argc;
-       char                    **argv;
+       int                       argc;
+       char                    **argv;
 };
 
 /* Command and list of commands. */
@@ -1311,8 +1311,8 @@ struct cmd {
 };
 
 struct cmd_list {
-       int                      references;
-       TAILQ_HEAD(, cmd)        list;
+       int                      references;
+       TAILQ_HEAD(, cmd)        list;
 };
 
 /* Command return values. */
@@ -1351,7 +1351,7 @@ struct cmd_q {
        void                     (*emptyfn)(struct cmd_q *);
        void                    *data;
 
-       TAILQ_ENTRY(cmd_q)       waitentry;
+       TAILQ_ENTRY(cmd_q)       waitentry;
 };
 
 /* Command definition. */
@@ -1413,8 +1413,8 @@ struct options_table_entry {
        const char             *name;
        enum options_table_type type;
 
-       u_int                   minimum;
-       u_int                   maximum;
+       u_int                   minimum;
+       u_int                   maximum;
        const char            **choices;
 
        const char             *default_str;
@@ -1801,7 +1801,7 @@ void printflike(2, 3) cmdq_print(struct cmd_q *, const 
char *, ...);
 void printflike(2, 3) cmdq_error(struct cmd_q *, const char *, ...);
 void            cmdq_guard(struct cmd_q *, const char *, int);
 void            cmdq_run(struct cmd_q *, struct cmd_list *,
-                    struct mouse_event *);
+                    struct mouse_event *);
 void            cmdq_append(struct cmd_q *, struct cmd_list *,
                     struct mouse_event *);
 int             cmdq_continue(struct cmd_q *);
@@ -1823,8 +1823,8 @@ RB_PROTOTYPE(key_tables, key_table, entry, key_table_cmp);
 extern struct key_tables key_tables;
 int     key_table_cmp(struct key_table *, struct key_table *);
 int     key_bindings_cmp(struct key_binding *, struct key_binding *);
-struct          key_table *key_bindings_get_table(const char *, int);
-void    key_bindings_unref_table(struct key_table *);
+struct  key_table *key_bindings_get_table(const char *, int);
+void    key_bindings_unref_table(struct key_table *);
 void    key_bindings_add(const char *, int, int, struct cmd_list *);
 void    key_bindings_remove(const char *, int);
 void    key_bindings_remove_table(const char *);
@@ -1846,7 +1846,7 @@ void       server_add_accept(int);
 /* server-client.c */
 void    server_client_handle_key(struct client *, int);
 void    server_client_create(int);
-int      server_client_open(struct client *, char **);
+int     server_client_open(struct client *, char **);
 void    server_client_lost(struct client *);
 void    server_client_callback(int, short, void *);
 void    server_client_status_timer(void);
@@ -2097,9 +2097,9 @@ 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 *,
-                       struct window_pane *, u_int);
+                       struct window_pane *, u_int);
 struct window_pane *window_pane_previous_by_number(struct window *,
-                       struct window_pane *, u_int);
+                       struct window_pane *, u_int);
 int             window_pane_index(struct window_pane *, u_int *);
 u_int           window_count_panes(struct window *);
 void            window_destroy_panes(struct window *);


commit 592cb73a69e23d321a29ae367d52b9e9b4f506c2
Author: nicm <nicm>
Commit: nicm <nicm>

    grid_marker_cell is no longer used.
---
 tmux.h |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/tmux.h b/tmux.h
index 3c9db50..f1575d2 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1940,7 +1940,6 @@ int        attributes_fromstring(const char *);
 
 /* grid.c */
 extern const struct grid_cell grid_default_cell;
-extern const struct grid_cell grid_marker_cell;
 struct grid *grid_create(u_int, u_int, u_int);
 void    grid_destroy(struct grid *);
 int     grid_compare(struct grid *, struct grid *);


commit 74b2c40b1b2f38b1aafe4178cb33db63d3be8de0
Author: nicm <nicm>
Commit: nicm <nicm>

    mode_key_entry can go into mode-key.c; also a few spaces->tabs.
---
 mode-key.c |   14 ++++++++++++++
 tmux.h     |   27 ++++++++-------------------
 2 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/mode-key.c b/mode-key.c
index c06d7ed..5ed45bd 100644
--- a/mode-key.c
+++ b/mode-key.c
@@ -38,6 +38,20 @@
  * (any matching MODEKEYEDIT_SWITCHMODE*) are special-cased to do this.
  */
 
+/* Entry in the default mode key tables. */
+struct mode_key_entry {
+       int                     key;
+
+       /*
+        * Editing mode for vi: 0 is edit mode, keys not in the table are
+        * returned as MODEKEY_OTHER; 1 is command mode, keys not in the table
+        * are returned as MODEKEY_NONE. This is also matched on, allowing some
+        * keys to be bound in edit mode.
+        */
+       int                     mode;
+       enum mode_key_cmd       cmd;
+};
+
 /* Edit keys command strings. */
 const struct mode_key_cmdstr mode_key_cmdstr_edit[] = {
        { MODEKEYEDIT_BACKSPACE, "backspace" },
diff --git a/tmux.h b/tmux.h
index f48797d..3c9db50 100644
--- a/tmux.h
+++ b/tmux.h
@@ -566,20 +566,6 @@ enum mode_key_cmd {
        MODEKEYCOPY_UP,
 };
 
-/* Entry in the default mode key tables. */
-struct mode_key_entry {
-       int                     key;
-
-       /*
-        * Editing mode for vi: 0 is edit mode, keys not in the table are
-        * returned as MODEKEY_OTHER; 1 is command mode, keys not in the table
-        * are returned as MODEKEY_NONE. This is also matched on, allowing some
-        * keys to be bound in edit mode.
-        */
-       int                     mode;
-       enum mode_key_cmd       cmd;
-};
-
 /* Data required while mode keys are in use. */
 struct mode_key_data {
        struct mode_key_tree   *tree;
@@ -607,6 +593,7 @@ struct mode_key_cmdstr {
 };
 
 /* Named mode key table description. */
+struct mode_key_entry;
 struct mode_key_table {
        const char                      *name;
        const struct mode_key_cmdstr    *cmdstr;
@@ -1192,16 +1179,16 @@ struct tty_ctx {
 
 /* Saved message entry. */
 struct message_entry {
-       char   *msg;
-       u_int   msg_num;
-       time_t  msg_time;
+       char    *msg;
+       u_int    msg_num;
+       time_t   msg_time;
        TAILQ_ENTRY(message_entry) entry;
 };
 
 /* Status output data from a job. */
 struct status_out {
-       char   *cmd;
-       char   *out;
+       char    *cmd;
+       char    *out;
 
        RB_ENTRY(status_out) entry;
 };
@@ -1322,6 +1309,7 @@ struct cmd {
 
        TAILQ_ENTRY(cmd)         qentry;
 };
+
 struct cmd_list {
        int                      references;
        TAILQ_HEAD(, cmd)        list;
@@ -1394,6 +1382,7 @@ struct key_binding {
        RB_ENTRY(key_binding)    entry;
 };
 RB_HEAD(key_bindings, key_binding);
+
 struct key_table {
        const char               *name;
        struct key_bindings      key_bindings;


commit a538141a72882e10988b68d7d1ede94cbb7140c1
Author: nicm <nicm>
Commit: nicm <nicm>

    window_choose_mode_item can move into window-choose.c.
---
 tmux.h          |    8 --------
 window-choose.c |    8 ++++++++
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/tmux.h b/tmux.h
index ad79d79..f48797d 100644
--- a/tmux.h
+++ b/tmux.h
@@ -823,14 +823,6 @@ struct window_choose_data {
        char                    *command;
 };
 
-struct window_choose_mode_item {
-       struct window_choose_data       *wcd;
-       char                            *name;
-       int                              pos;
-       int                              state;
-#define TREE_EXPANDED 0x1
-};
-
 /* Child window structure. */
 struct input_ctx;
 struct window_pane {
diff --git a/window-choose.c b/window-choose.c
index d4b20bc..2af56e2 100644
--- a/window-choose.c
+++ b/window-choose.c
@@ -60,6 +60,14 @@ const struct window_mode window_choose_mode = {
        NULL,
 };
 
+struct window_choose_mode_item {
+       struct window_choose_data       *wcd;
+       char                            *name;
+       int                              pos;
+       int                              state;
+#define TREE_EXPANDED 0x1
+};
+
 struct window_choose_mode_data {
        struct screen           screen;
 


commit c4a4bd6ac5748939c7c17beba9e14bee5929c552
Author: nicm <nicm>
Commit: nicm <nicm>

    Move input parser structs into input.c (removing fairly useless
    saved_cursor_[xy] formats as a side-effect).
---
 cmd-capture-pane.c |   14 ++++---
 cmd-send-keys.c    |   18 +---------
 format.c           |    2 -
 input.c            |   93 ++++++++++++++++++++++++++++++++++++++++++++++++----
 tmux.1             |    2 -
 tmux.h             |   54 ++----------------------------
 6 files changed, 100 insertions(+), 83 deletions(-)

diff --git a/cmd-capture-pane.c b/cmd-capture-pane.c
index b44ebe9..a348e15 100644
--- a/cmd-capture-pane.c
+++ b/cmd-capture-pane.c
@@ -57,15 +57,17 @@ char *
 cmd_capture_pane_pending(struct args *args, struct window_pane *wp,
     size_t *len)
 {
-       char    *buf, *line, tmp[5];
-       size_t   linelen;
-       u_int    i;
+       struct evbuffer *pending;
+       char            *buf, *line, tmp[5];
+       size_t           linelen;
+       u_int            i;
 
-       if (wp->ictx.since_ground == NULL)
+       pending = input_pending(wp);
+       if (pending == NULL)
                return (xstrdup(""));
 
-       line = EVBUFFER_DATA(wp->ictx.since_ground);
-       linelen = EVBUFFER_LENGTH(wp->ictx.since_ground);
+       line = EVBUFFER_DATA(pending);
+       linelen = EVBUFFER_LENGTH(pending);
 
        buf = xstrdup("");
        if (args_has(args, 'C')) {
diff --git a/cmd-send-keys.c b/cmd-send-keys.c
index 27da410..b1f8d67 100644
--- a/cmd-send-keys.c
+++ b/cmd-send-keys.c
@@ -52,7 +52,6 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
        struct mouse_event      *m = &cmdq->item->mouse;
        struct window_pane      *wp;
        struct session          *s;
-       struct input_ctx        *ictx;
        const u_char            *str;
        int                      i, key;
 
@@ -78,21 +77,8 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
                return (CMD_RETURN_NORMAL);
        }
 
-       if (args_has(args, 'R')) {
-               ictx = &wp->ictx;
-
-               memcpy(&ictx->cell, &grid_default_cell, sizeof ictx->cell);
-               memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
-               ictx->old_cx = 0;
-               ictx->old_cy = 0;
-
-               if (wp->mode == NULL)
-                       screen_write_start(&ictx->ctx, wp, &wp->base);
-               else
-                       screen_write_start(&ictx->ctx, NULL, &wp->base);
-               screen_write_reset(&ictx->ctx);
-               screen_write_stop(&ictx->ctx);
-       }
+       if (args_has(args, 'R'))
+               input_reset(wp);
 
        for (i = 0; i < args->argc; i++) {
                str = args->argv[i];
diff --git a/format.c b/format.c
index ac28604..39351fc 100644
--- a/format.c
+++ b/format.c
@@ -715,8 +715,6 @@ format_defaults_pane(struct format_tree *ft, struct 
window_pane *wp)
        format_add(ft, "cursor_y", "%u", wp->base.cy);
        format_add(ft, "scroll_region_upper", "%u", wp->base.rupper);
        format_add(ft, "scroll_region_lower", "%u", wp->base.rlower);
-       format_add(ft, "saved_cursor_x", "%u", wp->ictx.old_cx);
-       format_add(ft, "saved_cursor_y", "%u", wp->ictx.old_cy);
 
        format_add(ft, "alternate_on", "%d", wp->saved_grid ? 1 : 0);
        format_add(ft, "alternate_saved_x", "%u", wp->saved_cx);
diff --git a/input.c b/input.c
index 9f7d441..384ab45 100644
--- a/input.c
+++ b/input.c
@@ -46,6 +46,55 @@
  *   be passed to the underlying teminal(s).
  */
 
+/* Input parser cell. */
+struct input_cell {
+       struct grid_cell        cell;
+       int                     set;
+       int                     g0set;  /* 1 if ACS */
+       int                     g1set;  /* 1 if ACS */
+};
+
+/* Input parser context. */
+struct input_ctx {
+       struct window_pane     *wp;
+       struct screen_write_ctx ctx;
+
+       struct input_cell       cell;
+
+       struct input_cell       old_cell;
+       u_int                   old_cx;
+       u_int                   old_cy;
+
+       u_char                  interm_buf[4];
+       size_t                  interm_len;
+
+       u_char                  param_buf[64];
+       size_t                  param_len;
+
+#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;
+
+       struct utf8_data        utf8data;
+
+       int                     ch;
+       int                     flags;
+#define INPUT_DISCARD 0x1
+
+       const struct input_state *state;
+
+       /*
+        * All input received since we were last in the ground state. Sent to
+        * control clients on connection.
+        */
+       struct evbuffer         *since_ground;
+};
+
 /* Helper functions. */
 struct input_transition;
 int    input_split(struct input_ctx *);
@@ -706,7 +755,9 @@ input_reset_cell(struct input_ctx *ictx)
 void
 input_init(struct window_pane *wp)
 {
-       struct input_ctx        *ictx = &wp->ictx;
+       struct input_ctx        *ictx;
+
+       ictx = wp->ictx = xcalloc(1, sizeof *ictx);
 
        input_reset_cell(ictx);
 
@@ -732,18 +783,46 @@ input_init(struct window_pane *wp)
 void
 input_free(struct window_pane *wp)
 {
-       if (wp == NULL)
-               return;
+       struct input_ctx        *ictx = wp->ictx;
 
-       free(wp->ictx.input_buf);
-       evbuffer_free(wp->ictx.since_ground);
+       free(ictx->input_buf);
+       evbuffer_free(ictx->since_ground);
+
+       free (ictx);
+       wp->ictx = NULL;
+}
+
+/* Reset input state and clear screen. */
+void
+input_reset(struct window_pane *wp)
+{
+       struct input_ctx        *ictx = wp->ictx;
+
+       memcpy(&ictx->cell, &grid_default_cell, sizeof ictx->cell);
+       memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
+       ictx->old_cx = 0;
+       ictx->old_cy = 0;
+
+       if (wp->mode == NULL)
+               screen_write_start(&ictx->ctx, wp, &wp->base);
+       else
+               screen_write_start(&ictx->ctx, NULL, &wp->base);
+       screen_write_reset(&ictx->ctx);
+       screen_write_stop(&ictx->ctx);
+}
+
+/* Return pending data. */
+struct evbuffer *
+input_pending(struct window_pane *wp)
+{
+       return (wp->ictx->since_ground);
 }
 
 /* Change input state. */
 void
 input_set_state(struct window_pane *wp, const struct input_transition *itr)
 {
-       struct input_ctx        *ictx = &wp->ictx;
+       struct input_ctx        *ictx = wp->ictx;
 
        if (ictx->state->exit != NULL)
                ictx->state->exit(ictx);
@@ -756,7 +835,7 @@ input_set_state(struct window_pane *wp, const struct 
input_transition *itr)
 void
 input_parse(struct window_pane *wp)
 {
-       struct input_ctx                *ictx = &wp->ictx;
+       struct input_ctx                *ictx = wp->ictx;
        const struct input_transition   *itr;
        struct evbuffer                 *evb = wp->event->input;
        u_char                          *buf;
diff --git a/tmux.1 b/tmux.1
index ea178b7..9debeaf 100644
--- a/tmux.1
+++ b/tmux.1
@@ -3318,8 +3318,6 @@ The following variables are available, where appropriate:
 .It Li "pane_top" Ta "" Ta "Top of pane"
 .It Li "pane_tty" Ta "" Ta "Pseudo terminal of pane"
 .It Li "pane_width" Ta "" Ta "Width of pane"
-.It Li "saved_cursor_x" Ta "" Ta "Saved cursor X in pane"
-.It Li "saved_cursor_y" Ta "" Ta "Saved cursor Y in pane"
 .It Li "scroll_region_lower" Ta "" Ta "Bottom of scroll region in pane"
 .It Li "scroll_region_upper" Ta "" Ta "Top of scroll region in pane"
 .It Li "session_attached" Ta "" Ta "Number of clients session is attached to"
diff --git a/tmux.h b/tmux.h
index 72e172e..ad79d79 100644
--- a/tmux.h
+++ b/tmux.h
@@ -785,55 +785,6 @@ struct screen_write_ctx {
 #define screen_hsize(s) ((s)->grid->hsize)
 #define screen_hlimit(s) ((s)->grid->hlimit)
 
-/* Input parser cell. */
-struct input_cell {
-       struct grid_cell        cell;
-       int                     set;
-       int                     g0set;  /* 1 if ACS */
-       int                     g1set;  /* 1 if ACS */
-};
-
-/* Input parser context. */
-struct input_ctx {
-       struct window_pane     *wp;
-       struct screen_write_ctx ctx;
-
-       struct input_cell       cell;
-
-       struct input_cell       old_cell;
-       u_int                   old_cx;
-       u_int                   old_cy;
-
-       u_char                  interm_buf[4];
-       size_t                  interm_len;
-
-       u_char                  param_buf[64];
-       size_t                  param_len;
-
-#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;
-
-       struct utf8_data        utf8data;
-
-       int                     ch;
-       int                     flags;
-#define INPUT_DISCARD 0x1
-
-       const struct input_state *state;
-
-       /*
-        * All input received since we were last in the ground state. Sent to
-        * control clients on connection.
-        */
-       struct evbuffer         *since_ground;
-};
-
 /*
  * Window mode. Windows can be in several modes and this is used to call the
  * right function to handle input and output.
@@ -881,6 +832,7 @@ struct window_choose_mode_item {
 };
 
 /* Child window structure. */
+struct input_ctx;
 struct window_pane {
        u_int            id;
        u_int            active_point;
@@ -920,7 +872,7 @@ struct window_pane {
        int              fd;
        struct bufferevent *event;
 
-       struct input_ctx ictx;
+       struct input_ctx *ictx;
 
        struct grid_cell colgc;
 
@@ -1983,6 +1935,8 @@ void       recalculate_sizes(void);
 /* input.c */
 void    input_init(struct window_pane *);
 void    input_free(struct window_pane *);
+void    input_reset(struct window_pane *);
+struct evbuffer *input_pending(struct window_pane *);
 void    input_parse(struct window_pane *);
 
 /* input-key.c */


commit 879de25583a5a0bce57bd816ced96e0caf62c436
Author: nicm <nicm>
Commit: nicm <nicm>

    Remove some stuff that accidentally ended up here from portable, and
    remove a little-used debug function.
---
 grid.c          |   29 ++++++++++-------------------
 server-client.c |    5 -----
 2 files changed, 10 insertions(+), 24 deletions(-)

diff --git a/grid.c b/grid.c
index 2dc266d..7e08614 100644
--- a/grid.c
+++ b/grid.c
@@ -49,15 +49,16 @@ const struct grid_cell grid_default_cell = { 0, 0, 8, 8, (1 
<< 4) | 1, " " };
 
 int    grid_check_y(struct grid *, u_int);
 
-#ifdef DEBUG
-int
-grid_check_y(struct grid *gd, u_int py)
-{
-       if ((py) >= (gd)->hsize + (gd)->sy)
-               log_fatalx("y out of range: %u", py);
-       return (0);
-}
-#else
+void   grid_reflow_join(struct grid *, u_int *, struct grid_line *, u_int);
+void   grid_reflow_split(struct grid *, u_int *, struct grid_line *, u_int,
+           u_int);
+void   grid_reflow_move(struct grid *, u_int *, struct grid_line *);
+size_t grid_string_cells_fg(const struct grid_cell *, int *);
+size_t grid_string_cells_bg(const struct grid_cell *, int *);
+void   grid_string_cells_code(const struct grid_cell *,
+           const struct grid_cell *, char *, size_t, int);
+
+/* Check grid y position. */
 int
 grid_check_y(struct grid *gd, u_int py)
 {
@@ -67,16 +68,6 @@ grid_check_y(struct grid *gd, u_int py)
        }
        return (0);
 }
-#endif
-
-void   grid_reflow_join(struct grid *, u_int *, struct grid_line *, u_int);
-void   grid_reflow_split(struct grid *, u_int *, struct grid_line *, u_int,
-           u_int);
-void   grid_reflow_move(struct grid *, u_int *, struct grid_line *);
-size_t grid_string_cells_fg(const struct grid_cell *, int *);
-size_t grid_string_cells_bg(const struct grid_cell *, int *);
-void   grid_string_cells_code(const struct grid_cell *,
-           const struct grid_cell *, char *, size_t, int);
 
 /* Create a new grid. */
 struct grid *
diff --git a/server-client.c b/server-client.c
index ce3f3d5..dd6eda1 100644
--- a/server-client.c
+++ b/server-client.c
@@ -1178,11 +1178,6 @@ server_client_msg_identify(struct client *c, struct imsg 
*imsg)
                return;
        c->flags |= CLIENT_IDENTIFIED;
 
-#ifdef __CYGWIN__
-       c->fd = open(c->ttyname, O_RDWR|O_NOCTTY);
-       c->cwd = open(".", O_RDONLY);
-#endif
-
        if (c->flags & CLIENT_CONTROL) {
                c->stdin_callback = control_callback;
 


commit d174b9cfcc2d4c60bd89804ef63e5ee41ca6d490
Author: nicm <nicm>
Commit: nicm <nicm>

    Update environment when switching sessions as well as attaching, from Si
    Beaumont.
---
 cmd-switch-client.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/cmd-switch-client.c b/cmd-switch-client.c
index 18de0eb..369fc91 100644
--- a/cmd-switch-client.c
+++ b/cmd-switch-client.c
@@ -46,7 +46,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
        struct winlink          *wl = NULL;
        struct window           *w = NULL;
        struct window_pane      *wp = NULL;
-       const char              *tflag, *tablename;
+       const char              *tflag, *tablename, *update;
        struct key_table        *table;
 
        if ((c = cmd_find_client(cmdq, args_get(args, 'c'), 0)) == NULL)
@@ -119,6 +119,11 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q 
*cmdq)
                }
        }
 
+       if (c != NULL && s != c->session) {
+               update = options_get_string(&s->options, "update-environment");
+               environ_update(update, &c->environ, &s->environ);
+       }
+
        if (c->session != NULL)
                c->last_session = c->session;
        c->session = s;


commit 8e9b6e09485f3400aac9e6cd8a711e2cc1819b03
Author: nicm <nicm>
Commit: nicm <nicm>

    Style spacing nits.
---
 cfg.c          |    2 +-
 cmd-find.c     |    8 ++++----
 key-bindings.c |    2 +-
 style.c        |    4 ++--
 window.c       |    2 +-
 5 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/cfg.c b/cfg.c
index 8b44ce2..ff43976 100644
--- a/cfg.c
+++ b/cfg.c
@@ -121,7 +121,7 @@ cfg_add_cause(const char *fmt, ...)
 
        va_start(ap, fmt);
        xvasprintf(&msg, fmt, ap);
-       va_end (ap);
+       va_end(ap);
 
        cfg_ncauses++;
        cfg_causes = xreallocarray(cfg_causes, cfg_ncauses, sizeof *cfg_causes);
diff --git a/cmd-find.c b/cmd-find.c
index ec4cf6c..98f1e18 100644
--- a/cmd-find.c
+++ b/cmd-find.c
@@ -193,7 +193,7 @@ cmd_find_best_session_with_window(struct cmd_find_state *fs)
        RB_FOREACH(s, sessions, &sessions) {
                if (!session_has(s, fs->w))
                        continue;
-               slist = xreallocarray (slist, ssize + 1, sizeof *slist);
+               slist = xreallocarray(slist, ssize + 1, sizeof *slist);
                slist[ssize++] = s;
        }
        if (ssize == 0)
@@ -201,7 +201,7 @@ cmd_find_best_session_with_window(struct cmd_find_state *fs)
        fs->s = cmd_find_best_session(slist, ssize, fs->flags);
        if (fs->s == NULL)
                goto fail;
-       free (slist);
+       free(slist);
        return (cmd_find_best_winlink_with_window(fs));
 
 fail:
@@ -329,7 +329,7 @@ cmd_find_current_client(struct cmd_q *cmdq)
                TAILQ_FOREACH(c, &clients, entry) {
                        if (c->session != s)
                                continue;
-                       clist = xreallocarray (clist, csize + 1, sizeof *clist);
+                       clist = xreallocarray(clist, csize + 1, sizeof *clist);
                        clist[csize++] = c;
                }
                if (csize != 0) {
@@ -739,7 +739,7 @@ cmd_find_get_pane_with_window(struct cmd_find_state *fs, 
const char *pane)
 void
 cmd_find_clear_state(struct cmd_find_state *fs, struct cmd_q *cmdq, int flags)
 {
-       memset (fs, 0, sizeof *fs);
+       memset(fs, 0, sizeof *fs);
 
        fs->cmdq = cmdq;
        fs->flags = flags;
diff --git a/key-bindings.c b/key-bindings.c
index d56428b..a3cb0be 100644
--- a/key-bindings.c
+++ b/key-bindings.c
@@ -236,7 +236,7 @@ key_bindings_init(void)
                if (error != 0)
                        fatalx("bad default key");
                cmdq_run(cmdq, cmdlist, NULL);
-               cmd_list_free (cmdlist);
+               cmd_list_free(cmdlist);
        }
        cmdq_free(cmdq);
 }
diff --git a/style.c b/style.c
index 5534f11..9fafdd1 100644
--- a/style.c
+++ b/style.c
@@ -168,12 +168,12 @@ style_update_new(struct options *oo, const char *name, 
const char *newname)
 
        o = options_find1(oo, newname);
        if (o == NULL)
-               o = options_set_style (oo, newname, "default", 0);
+               o = options_set_style(oo, newname, "default", 0);
        gc = &o->style;
 
        o = options_find1(oo, name);
        if (o == NULL)
-               o = options_set_number (oo, name, 8);
+               o = options_set_number(oo, name, 8);
        value = o->num;
 
        if (strstr(name, "-bg") != NULL)
diff --git a/window.c b/window.c
index a2277e2..8366833 100644
--- a/window.c
+++ b/window.c
@@ -302,7 +302,7 @@ window_create1(u_int sx, u_int sy)
        w->references = 0;
 
        w->id = next_window_id++;
-       RB_INSERT (windows, &windows, w);
+       RB_INSERT(windows, &windows, w);
 
        return (w);
 }


commit 1282bb81fe9fbb1b2ff1b63a9c4e8978444703c4
Author: nicm <nicm>
Commit: nicm <nicm>

    array.h can be local to window-choose.c now.
---
 tmux.h          |    2 --
 window-choose.c |    1 +
 2 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/tmux.h b/tmux.h
index 9783a65..72e172e 100644
--- a/tmux.h
+++ b/tmux.h
@@ -35,8 +35,6 @@
 #include <stdio.h>
 #include <termios.h>
 
-#include "array.h"
-
 extern char    *__progname;
 extern char   **environ;
 
diff --git a/window-choose.c b/window-choose.c
index 8672212..d4b20bc 100644
--- a/window-choose.c
+++ b/window-choose.c
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "array.h"
 #include "tmux.h"
 
 struct screen *window_choose_init(struct window_pane *);


commit 7becf326e3b756016f2df6230db9fcf714d44955
Author: nicm <nicm>
Commit: nicm <nicm>

    Use a TAILQ not array for find-window.
---
 cmd-find-window.c |   67 +++++++++++++++++++++++++++++-----------------------
 1 files changed, 37 insertions(+), 30 deletions(-)

diff --git a/cmd-find-window.c b/cmd-find-window.c
index 64e092b..e92ae60 100644
--- a/cmd-find-window.c
+++ b/cmd-find-window.c
@@ -59,11 +59,12 @@ struct cmd_find_window_data {
        struct winlink  *wl;
        char            *list_ctx;
        u_int            pane_id;
+       TAILQ_ENTRY(cmd_find_window_data) entry;
 };
-ARRAY_DECL(cmd_find_window_data_list, struct cmd_find_window_data);
+TAILQ_HEAD(cmd_find_window_list, cmd_find_window_data);
 
 u_int  cmd_find_window_match_flags(struct args *);
-void   cmd_find_window_match(struct cmd_find_window_data_list *, int,
+void   cmd_find_window_match(struct cmd_find_window_list *, int,
            struct winlink *, const char *, const char *);
 
 u_int
@@ -87,16 +88,16 @@ cmd_find_window_match_flags(struct args *args)
 }
 
 void
-cmd_find_window_match(struct cmd_find_window_data_list *find_list,
+cmd_find_window_match(struct cmd_find_window_list *find_list,
     int match_flags, struct winlink *wl, const char *str,
     const char *searchstr)
 {
-       struct cmd_find_window_data      find_data;
+       struct cmd_find_window_data     *find_data;
        struct window_pane              *wp;
        u_int                            i, line;
        char                            *sres;
 
-       memset(&find_data, 0, sizeof find_data);
+       find_data = xcalloc(1, sizeof *find_data);
 
        i = 0;
        TAILQ_FOREACH(wp, &wl->window->panes, entry) {
@@ -104,30 +105,32 @@ cmd_find_window_match(struct cmd_find_window_data_list 
*find_list,
 
                if ((match_flags & CMD_FIND_WINDOW_BY_NAME) &&
                    fnmatch(searchstr, wl->window->name, 0) == 0) {
-                       find_data.list_ctx = xstrdup("");
+                       find_data->list_ctx = xstrdup("");
                        break;
                }
 
                if ((match_flags & CMD_FIND_WINDOW_BY_TITLE) &&
                    fnmatch(searchstr, wp->base.title, 0) == 0) {
-                       xasprintf(&find_data.list_ctx,
+                       xasprintf(&find_data->list_ctx,
                            "pane %u title: \"%s\"", i - 1, wp->base.title);
                        break;
                }
 
                if (match_flags & CMD_FIND_WINDOW_BY_CONTENT &&
                    (sres = window_pane_search(wp, str, &line)) != NULL) {
-                       xasprintf(&find_data.list_ctx,
+                       xasprintf(&find_data->list_ctx,
                            "pane %u line %u: \"%s\"", i - 1, line + 1, sres);
                        free(sres);
                        break;
                }
        }
-       if (find_data.list_ctx != NULL) {
-               find_data.wl = wl;
-               find_data.pane_id = i - 1;
-               ARRAY_ADD(find_list, find_data);
-       }
+
+       if (find_data->list_ctx != NULL) {
+               find_data->wl = wl;
+               find_data->pane_id = i - 1;
+               TAILQ_INSERT_TAIL(find_list, find_data, entry);
+       } else
+               free(find_data);
 }
 
 enum cmd_retval
@@ -138,7 +141,9 @@ cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq)
        struct window_choose_data       *cdata;
        struct session                  *s;
        struct winlink                  *wl, *wm;
-       struct cmd_find_window_data_list find_list;
+       struct cmd_find_window_list      find_list;
+       struct cmd_find_window_data     *find_data;
+       struct cmd_find_window_data     *find_data1;
        char                            *str, *searchstr;
        const char                      *template;
        u_int                            i, match_flags;
@@ -158,21 +163,20 @@ cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq)
        match_flags = cmd_find_window_match_flags(args);
        str = args->argv[0];
 
-       ARRAY_INIT(&find_list);
+       TAILQ_INIT(&find_list);
 
        xasprintf(&searchstr, "*%s*", str);
        RB_FOREACH(wm, winlinks, &s->windows)
            cmd_find_window_match(&find_list, match_flags, wm, str, searchstr);
        free(searchstr);
 
-       if (ARRAY_LENGTH(&find_list) == 0) {
+       if (TAILQ_EMPTY(&find_list)) {
                cmdq_error(cmdq, "no windows matching: %s", str);
-               ARRAY_FREE(&find_list);
                return (CMD_RETURN_ERROR);
        }
 
-       if (ARRAY_LENGTH(&find_list) == 1) {
-               if (session_select(s, ARRAY_FIRST(&find_list).wl->idx) == 0)
+       if (TAILQ_NEXT(TAILQ_FIRST(&find_list), entry) == NULL) {
+               if (session_select(s, TAILQ_FIRST(&find_list)->wl->idx) == 0)
                        server_redraw_session(s);
                recalculate_sizes();
                goto out;
@@ -181,30 +185,33 @@ cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq)
        if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
                goto out;
 
-       for (i = 0; i < ARRAY_LENGTH(&find_list); i++) {
-               wm = ARRAY_ITEM(&find_list, i).wl;
-
+       i = 0;
+       TAILQ_FOREACH(find_data, &find_list, entry) {
                cdata = window_choose_data_create(TREE_OTHER, c, c->session);
-               cdata->idx = wm->idx;
-               cdata->wl = wm;
+               cdata->idx = find_data->wl->idx;
+               cdata->wl = find_data->wl;
 
                cdata->ft_template = xstrdup(template);
-               cdata->pane_id = ARRAY_ITEM(&find_list, i).pane_id;
+               cdata->pane_id = find_data->pane_id;
 
                format_add(cdata->ft, "line", "%u", i);
                format_add(cdata->ft, "window_find_matches", "%s",
-                   ARRAY_ITEM(&find_list, i).list_ctx);
-               format_defaults(cdata->ft, NULL, s, wm, NULL);
+                   find_data->list_ctx);
+               format_defaults(cdata->ft, NULL, s, find_data->wl, NULL);
 
                window_choose_add(wl->window->active, cdata);
+
+               i++;
        }
 
        window_choose_ready(wl->window->active, 0, cmd_find_window_callback);
 
 out:
-       for (i = 0; i < ARRAY_LENGTH(&find_list); i++)
-               free(ARRAY_ITEM(&find_list, i).list_ctx);
-       ARRAY_FREE(&find_list);
+       TAILQ_FOREACH_SAFE(find_data, &find_list, entry, find_data1) {
+               free(find_data->list_ctx);
+               TAILQ_REMOVE(&find_list, find_data, entry);
+               free(find_data);
+       }
        return (CMD_RETURN_NORMAL);
 }
 


commit 73c871ba0a075bdd458a1b4208afd0e9bb293096
Author: nicm <nicm>
Commit: nicm <nicm>

    Simplify environ_push so it doesn't need the ARRAY_* functions.
---
 environ.c |   25 +++++++++----------------
 1 files changed, 9 insertions(+), 16 deletions(-)

diff --git a/environ.c b/environ.c
index 0dd9178..11b8c84 100644
--- a/environ.c
+++ b/environ.c
@@ -157,23 +157,16 @@ environ_update(const char *vars, struct environ *srcenv,
 void
 environ_push(struct environ *env)
 {
-       ARRAY_DECL(, char *)    varlist;
-       struct environ_entry   *envent;
-       char                  **varp, *var;
-       u_int                   i;
-
-       ARRAY_INIT(&varlist);
-       for (varp = environ; *varp != NULL; varp++) {
-               var = xstrdup(*varp);
-               var[strcspn(var, "=")] = '\0';
-               ARRAY_ADD(&varlist, var);
-       }
-       for (i = 0; i < ARRAY_LENGTH(&varlist); i++) {
-               var = ARRAY_ITEM(&varlist, i);
-               unsetenv(var);
-               free(var);
+       struct environ_entry     *envent;
+       char                    **vp, *v;
+
+       for (vp = environ; *vp != NULL; vp++) {
+               v = xstrdup(*vp);
+               v[strcspn(v, "=")] = '\0';
+
+               unsetenv(v);
+               free(v);
        }
-       ARRAY_FREE(&varlist);
 
        RB_FOREACH(envent, environ, env) {
                if (envent->value != NULL)


commit b6be03f01aaf10230bf4de4c49d56bc7d9bee9bf
Author: nicm <nicm>
Commit: nicm <nicm>

    If status line is at the top, the offset needs to be adjusted when
    drawing pane numbers.  Based on a diff from John O'Meara.
---
 screen-redraw.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/screen-redraw.c b/screen-redraw.c
index e3369b8..babc74a 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -32,7 +32,7 @@ int   screen_redraw_check_active(u_int, u_int, int, struct 
window *,
 void   screen_redraw_draw_borders(struct client *, int, u_int);
 void   screen_redraw_draw_panes(struct client *, u_int);
 void   screen_redraw_draw_status(struct client *, u_int);
-void   screen_redraw_draw_number(struct client *, struct window_pane *);
+void   screen_redraw_draw_number(struct client *, struct window_pane *, u_int);
 
 #define CELL_INSIDE 0
 #define CELL_LEFTRIGHT 1
@@ -354,7 +354,7 @@ screen_redraw_draw_panes(struct client *c, u_int top)
                for (i = 0; i < wp->sy; i++)
                        tty_draw_pane(tty, wp, i, wp->xoff, top + wp->yoff);
                if (c->flags & CLIENT_IDENTIFY)
-                       screen_redraw_draw_number(c, wp);
+                       screen_redraw_draw_number(c, wp, top);
        }
 }
 
@@ -372,7 +372,7 @@ screen_redraw_draw_status(struct client *c, u_int top)
 
 /* Draw number on a pane. */
 void
-screen_redraw_draw_number(struct client *c, struct window_pane *wp)
+screen_redraw_draw_number(struct client *c, struct window_pane *wp, u_int top)
 {
        struct tty              *tty = &c->tty;
        struct session          *s = c->session;
@@ -396,6 +396,9 @@ screen_redraw_draw_number(struct client *c, struct 
window_pane *wp)
        px = wp->sx / 2; py = wp->sy / 2;
        xoff = wp->xoff; yoff = wp->yoff;
 
+       if (top)
+               yoff++;
+
        if (wp->sx < len * 6 || wp->sy < 5) {
                tty_cursor(tty, xoff + px - len / 2, yoff + py);
                goto draw_text;


commit 0b39e6427fde3fadb9a3453b6423865829a59ad6
Author: nicm <nicm>
Commit: nicm <nicm>

    Remove ARRAY_* from history and expand completion to complete a) layout
    names and b) targets beginning with -t or -s.
---
 status.c |  260 ++++++++++++++++++++++++++++++++++++++++++++++----------------
 tmux.h   |    3 -
 2 files changed, 193 insertions(+), 70 deletions(-)

diff --git a/status.c b/status.c
index e3d335f..9bd5111 100644
--- a/status.c
+++ b/status.c
@@ -45,10 +45,15 @@ void        status_message_callback(int, short, void *);
 const char *status_prompt_up_history(u_int *);
 const char *status_prompt_down_history(u_int *);
 void   status_prompt_add_history(const char *);
-char   *status_prompt_complete(const char *);
+
+const char **status_prompt_complete_list(u_int *, const char *);
+char   *status_prompt_complete_prefix(const char **, u_int);
+char   *status_prompt_complete(struct session *, const char *);
 
 /* Status prompt history. */
-ARRAY_DECL(, char *) status_prompt_history = ARRAY_INITIALIZER;
+#define PROMPT_HISTORY 100
+char   **status_prompt_hlist;
+u_int    status_prompt_hsize;
 
 /* Status output tree. */
 RB_GENERATE(status_out_tree, status_out, entry, status_out_cmp);
@@ -977,7 +982,7 @@ status_prompt_key(struct client *c, int key)
                word[last - first] = '\0';
 
                /* And try to complete it. */
-               if ((s = status_prompt_complete(word)) == NULL)
+               if ((s = status_prompt_complete(sess, word)) == NULL)
                        break;
 
                /* Trim out word. */
@@ -1235,114 +1240,235 @@ status_prompt_key(struct client *c, int key)
 const char *
 status_prompt_up_history(u_int *idx)
 {
-       u_int size;
-
        /*
-        * History runs from 0 to size - 1.
-        *
-        * Index is from 0 to size. Zero is empty.
+        * History runs from 0 to size - 1. Index is from 0 to size. Zero is
+        * empty.
         */
 
-       size = ARRAY_LENGTH(&status_prompt_history);
-       if (size == 0 || *idx == size)
+       if (status_prompt_hsize == 0 || *idx == status_prompt_hsize)
                return (NULL);
        (*idx)++;
-       return (ARRAY_ITEM(&status_prompt_history, size - *idx));
+       return (status_prompt_hlist[status_prompt_hsize - *idx]);
 }
 
 /* Get next line from the history. */
 const char *
 status_prompt_down_history(u_int *idx)
 {
-       u_int size;
-
-       size = ARRAY_LENGTH(&status_prompt_history);
-       if (size == 0 || *idx == 0)
+       if (status_prompt_hsize == 0 || *idx == 0)
                return ("");
        (*idx)--;
        if (*idx == 0)
                return ("");
-       return (ARRAY_ITEM(&status_prompt_history, size - *idx));
+       return (status_prompt_hlist[status_prompt_hsize - *idx]);
 }
 
 /* Add line to the history. */
 void
 status_prompt_add_history(const char *line)
 {
-       u_int size;
+       size_t  size;
 
-       size = ARRAY_LENGTH(&status_prompt_history);
-       if (size > 0 && strcmp(ARRAY_LAST(&status_prompt_history), line) == 0)
+       if (status_prompt_hsize > 0 &&
+           strcmp(status_prompt_hlist[status_prompt_hsize - 1], line) == 0)
                return;
 
-       if (size == PROMPT_HISTORY) {
-               free(ARRAY_FIRST(&status_prompt_history));
-               ARRAY_REMOVE(&status_prompt_history, 0);
+       if (status_prompt_hsize == PROMPT_HISTORY) {
+               free(status_prompt_hlist[0]);
+
+               size = (PROMPT_HISTORY - 1) * sizeof *status_prompt_hlist;
+               memmove(&status_prompt_hlist[0], &status_prompt_hlist[1], size);
+
+               status_prompt_hlist[status_prompt_hsize - 1] = xstrdup(line);
+               return;
        }
 
-       ARRAY_ADD(&status_prompt_history, xstrdup(line));
+       status_prompt_hlist = xreallocarray(status_prompt_hlist,
+           status_prompt_hsize + 1, sizeof *status_prompt_hlist);
+       status_prompt_hlist[status_prompt_hsize++] = xstrdup(line);
 }
 
-/* Complete word. */
-char *
-status_prompt_complete(const char *s)
+/* Build completion list. */
+const char **
+status_prompt_complete_list(u_int *size, const char *s)
 {
-       const struct cmd_entry                 **cmdent;
-       const struct options_table_entry        *oe;
-       ARRAY_DECL(, const char *)               list;
-       char                                    *prefix, *s2;
-       u_int                                    i;
-       size_t                                   j;
-
-       if (*s == '\0')
-               return (NULL);
-
-       /* First, build a list of all the possible matches. */
-       ARRAY_INIT(&list);
+       const char                              **list = NULL, **layout;
+       const struct cmd_entry                  **cmdent;
+       const struct options_table_entry         *oe;
+       const char                               *layouts[] = {
+               "even-horizontal", "even-vertical", "main-horizontal",
+               "main-vertical", "tiled", NULL
+       };
+
+       *size = 0;
        for (cmdent = cmd_table; *cmdent != NULL; cmdent++) {
-               if (strncmp((*cmdent)->name, s, strlen(s)) == 0)
-                       ARRAY_ADD(&list, (*cmdent)->name);
+               if (strncmp((*cmdent)->name, s, strlen(s)) == 0) {
+                       list = xreallocarray(list, (*size) + 1, sizeof *list);
+                       list[(*size)++] = (*cmdent)->name;
+               }
        }
        for (oe = server_options_table; oe->name != NULL; oe++) {
-               if (strncmp(oe->name, s, strlen(s)) == 0)
-                       ARRAY_ADD(&list, oe->name);
+               if (strncmp(oe->name, s, strlen(s)) == 0) {
+                       list = xreallocarray(list, (*size) + 1, sizeof *list);
+                       list[(*size)++] = oe->name;
+               }
        }
        for (oe = session_options_table; oe->name != NULL; oe++) {
-               if (strncmp(oe->name, s, strlen(s)) == 0)
-                       ARRAY_ADD(&list, oe->name);
+               if (strncmp(oe->name, s, strlen(s)) == 0) {
+                       list = xreallocarray(list, (*size) + 1, sizeof *list);
+                       list[(*size)++] = oe->name;
+               }
        }
        for (oe = window_options_table; oe->name != NULL; oe++) {
-               if (strncmp(oe->name, s, strlen(s)) == 0)
-                       ARRAY_ADD(&list, oe->name);
+               if (strncmp(oe->name, s, strlen(s)) == 0) {
+                       list = xreallocarray(list, (*size) + 1, sizeof *list);
+                       list[(*size)++] = oe->name;
+               }
        }
+       for (layout = layouts; *layout != NULL; layout++) {
+               if (strncmp(*layout, s, strlen(s)) == 0) {
+                       list = xreallocarray(list, (*size) + 1, sizeof *list);
+                       list[(*size)++] = *layout;
+               }
+       }
+       return (list);
+}
 
-       /* If none, bail now. */
-       if (ARRAY_LENGTH(&list) == 0) {
-               ARRAY_FREE(&list);
-               return (NULL);
+/* Find longest prefix. */
+char *
+status_prompt_complete_prefix(const char **list, u_int size)
+{
+       char     *out;
+       u_int     i;
+       size_t    j;
+
+       out = xstrdup(list[0]);
+       for (i = 1; i < size; i++) {
+               j = strlen(list[i]);
+               if (j > strlen(out))
+                       j = strlen(out);
+               for (; j > 0; j--) {
+                       if (out[j - 1] != list[i][j - 1])
+                               out[j - 1] = '\0';
+               }
        }
+       return (out);
+}
 
-       /* If an exact match, return it, with a trailing space. */
-       if (ARRAY_LENGTH(&list) == 1) {
-               xasprintf(&s2, "%s ", ARRAY_FIRST(&list));
-               ARRAY_FREE(&list);
-               return (s2);
+/* Complete word. */
+char *
+status_prompt_complete(struct session *sess, const char *s)
+{
+       const char      **list = NULL, *colon;
+       u_int             size = 0, i;
+       struct session   *s_loop;
+       struct winlink   *wl;
+       struct window    *w;
+       char             *copy, *out, *tmp;
+
+       if (*s == '\0')
+               return (NULL);
+       out = NULL;
+
+       if (strncmp(s, "-t", 2) != 0 && strncmp(s, "-s", 2) != 0) {
+               list = status_prompt_complete_list(&size, s);
+               if (size == 0)
+                       out = NULL;
+               else if (size == 1)
+                       xasprintf(&out, "%s ", list[0]);
+               else
+                       out = status_prompt_complete_prefix(list, size);
+               free(list);
+               return (out);
        }
+       copy = xstrdup(s);
 
-       /* Now loop through the list and find the longest common prefix. */
-       prefix = xstrdup(ARRAY_FIRST(&list));
-       for (i = 1; i < ARRAY_LENGTH(&list); i++) {
-               s = ARRAY_ITEM(&list, i);
+       colon = ":";
+       if (copy[strlen(copy) - 1] == ':')
+               copy[strlen(copy) - 1] = '\0';
+       else
+               colon = "";
+       s = copy + 2;
 
-               j = strlen(s);
-               if (j > strlen(prefix))
-                       j = strlen(prefix);
-               for (; j > 0; j--) {
-                       if (prefix[j - 1] != s[j - 1])
-                               prefix[j - 1] = '\0';
+       RB_FOREACH(s_loop, sessions, &sessions) {
+               if (strncmp(s_loop->name, s, strlen(s)) == 0) {
+                       list = xreallocarray(list, size + 2, sizeof *list);
+                       list[size++] = s_loop->name;
                }
        }
+       if (size == 1) {
+               out = xstrdup(list[0]);
+               if (session_find(list[0]) != NULL)
+                       colon = ":";
+       } else if (size != 0)
+               out = status_prompt_complete_prefix(list, size);
+       if (out != NULL) {
+               xasprintf(&tmp, "-%c%s%s", copy[1], out, colon);
+               out = tmp;
+               goto found;
+       }
+
+       colon = "";
+       if (*s == ':') {
+               RB_FOREACH(wl, winlinks, &sess->windows) {
+                       xasprintf(&tmp, ":%s", wl->window->name);
+                       if (strncmp(tmp, s, strlen(s)) == 0){
+                               list = xreallocarray(list, size + 1,
+                                   sizeof *list);
+                               list[size++] = tmp;
+                               continue;
+                       }
+                       free(tmp);
+
+                       xasprintf(&tmp, ":%d", wl->idx);
+                       if (strncmp(tmp, s, strlen(s)) == 0) {
+                               list = xreallocarray(list, size + 1,
+                                   sizeof *list);
+                               list[size++] = tmp;
+                               continue;
+                       }
+                       free(tmp);
+               }
+       } else {
+               RB_FOREACH(s_loop, sessions, &sessions) {
+                       RB_FOREACH(wl, winlinks, &s_loop->windows) {
+                               w = wl->window;
+
+                               xasprintf(&tmp, "%s:%s", s_loop->name, w->name);
+                               if (strncmp(tmp, s, strlen(s)) == 0) {
+                                       list = xreallocarray(list, size + 1,
+                                           sizeof *list);
+                                       list[size++] = tmp;
+                                       continue;
+                               }
+                               free(tmp);
+
+                               xasprintf(&tmp, "%s:%d", s_loop->name, wl->idx);
+                               if (strncmp(tmp, s, strlen(s)) == 0) {
+                                       list = xreallocarray(list, size + 1,
+                                           sizeof *list);
+                                       list[size++] = tmp;
+                                       continue;
+                               }
+                               free(tmp);
+                       }
+               }
+       }
+       if (size == 1) {
+               out = xstrdup(list[0]);
+               colon = " ";
+       } else if (size != 0)
+               out = status_prompt_complete_prefix(list, size);
+       if (out != NULL) {
+               xasprintf(&tmp, "-%c%s%s", copy[1], out, colon);
+               out = tmp;
+       }
+
+       for (i = 0; i < size; i++)
+               free((void *)list[i]);
 
-       ARRAY_FREE(&list);
-       return (prefix);
+found:
+       free(copy);
+       free(list);
+       return (out);
 }
diff --git a/tmux.h b/tmux.h
index 83b6e4a..9783a65 100644
--- a/tmux.h
+++ b/tmux.h
@@ -43,9 +43,6 @@ extern char   **environ;
 /* Default global configuration file. */
 #define TMUX_CONF "/etc/tmux.conf"
 
-/* Default prompt history length. */
-#define PROMPT_HISTORY 100
-
 /*
  * Minimum layout cell size, NOT including separator line. The scroll region
  * cannot be one line in height so this must be at least two.


-----------------------------------------------------------------------

Summary of changes:
 cfg.c               |    2 +-
 cmd-capture-pane.c  |   14 ++-
 cmd-find-window.c   |   67 +++++++------
 cmd-find.c          |    8 +-
 cmd-send-keys.c     |   18 +---
 cmd-switch-client.c |    7 +-
 environ.c           |   25 ++---
 format.c            |    2 -
 grid.c              |   29 ++----
 input.c             |   93 +++++++++++++++++--
 key-bindings.c      |    2 +-
 mode-key.c          |   14 +++
 screen-redraw.c     |    9 +-
 server-client.c     |    5 -
 status.c            |  260 ++++++++++++++++++++++++++++++++++++++-------------
 style.c             |    4 +-
 tmux.1              |    2 -
 tmux.h              |  195 +++++++++++++-------------------------
 window-choose.c     |    9 ++
 window.c            |    2 +-
 20 files changed, 454 insertions(+), 313 deletions(-)


hooks/post-receive
-- 
tmux

------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud 
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
tmux-cvs mailing list
tmux-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-cvs

Reply via email to