Home | History | Annotate | Line # | Download | only in dist
      1 /* $OpenBSD$ */
      2 
      3 /*
      4  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott (at) gmail.com>
      5  *
      6  * Permission to use, copy, modify, and distribute this software for any
      7  * purpose with or without fee is hereby granted, provided that the above
      8  * copyright notice and this permission notice appear in all copies.
      9  *
     10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     14  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
     15  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
     16  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     17  */
     18 
     19 #include <sys/types.h>
     20 #include <sys/time.h>
     21 
     22 #include <errno.h>
     23 #include <limits.h>
     24 #include <stdarg.h>
     25 #include <stdlib.h>
     26 #include <string.h>
     27 #include <time.h>
     28 #include <unistd.h>
     29 
     30 #include "tmux.h"
     31 
     32 static void	 status_message_callback(int, short, void *);
     33 static void	 status_timer_callback(int, short, void *);
     34 
     35 static char	*status_prompt_find_history_file(void);
     36 static const char *status_prompt_up_history(u_int *, u_int);
     37 static const char *status_prompt_down_history(u_int *, u_int);
     38 static void	 status_prompt_add_history(const char *, u_int);
     39 
     40 static char	*status_prompt_complete(struct client *, const char *, u_int);
     41 static char	*status_prompt_complete_window_menu(struct client *,
     42 		     struct session *, const char *, u_int, char);
     43 
     44 struct status_prompt_menu {
     45 	struct client	 *c;
     46 	u_int		  start;
     47 	u_int		  size;
     48 	char		**list;
     49 	char		  flag;
     50 };
     51 
     52 static const char	*prompt_type_strings[] = {
     53 	"command",
     54 	"search",
     55 	"target",
     56 	"window-target"
     57 };
     58 
     59 /* Status prompt history. */
     60 char		**status_prompt_hlist[PROMPT_NTYPES];
     61 u_int		  status_prompt_hsize[PROMPT_NTYPES];
     62 
     63 /* Find the history file to load/save from/to. */
     64 static char *
     65 status_prompt_find_history_file(void)
     66 {
     67 	const char	*home, *history_file;
     68 	char		*path;
     69 
     70 	history_file = options_get_string(global_options, "history-file");
     71 	if (*history_file == '\0')
     72 		return (NULL);
     73 	if (*history_file == '/')
     74 		return (xstrdup(history_file));
     75 
     76 	if (history_file[0] != '~' || history_file[1] != '/')
     77 		return (NULL);
     78 	if ((home = find_home()) == NULL)
     79 		return (NULL);
     80 	xasprintf(&path, "%s%s", home, history_file + 1);
     81 	return (path);
     82 }
     83 
     84 /* Add loaded history item to the appropriate list. */
     85 static void
     86 status_prompt_add_typed_history(char *line)
     87 {
     88 	char			*typestr;
     89 	enum prompt_type	 type = PROMPT_TYPE_INVALID;
     90 
     91 	typestr = strsep(&line, ":");
     92 	if (line != NULL)
     93 		type = status_prompt_type(typestr);
     94 	if (type == PROMPT_TYPE_INVALID) {
     95 		/*
     96 		 * Invalid types are not expected, but this provides backward
     97 		 * compatibility with old history files.
     98 		 */
     99 		if (line != NULL)
    100 			*(--line) = ':';
    101 		status_prompt_add_history(typestr, PROMPT_TYPE_COMMAND);
    102 	} else
    103 		status_prompt_add_history(line, type);
    104 }
    105 
    106 /* Load status prompt history from file. */
    107 void
    108 status_prompt_load_history(void)
    109 {
    110 	FILE	*f;
    111 	char	*history_file, *line, *tmp;
    112 	size_t	 length;
    113 
    114 	if ((history_file = status_prompt_find_history_file()) == NULL)
    115 		return;
    116 	log_debug("loading history from %s", history_file);
    117 
    118 	f = fopen(history_file, "r");
    119 	if (f == NULL) {
    120 		log_debug("%s: %s", history_file, strerror(errno));
    121 		free(history_file);
    122 		return;
    123 	}
    124 	free(history_file);
    125 
    126 	for (;;) {
    127 		if ((line = fgetln(f, &length)) == NULL)
    128 			break;
    129 
    130 		if (length > 0) {
    131 			if (line[length - 1] == '\n') {
    132 				line[length - 1] = '\0';
    133 				status_prompt_add_typed_history(line);
    134 			} else {
    135 				tmp = xmalloc(length + 1);
    136 				memcpy(tmp, line, length);
    137 				tmp[length] = '\0';
    138 				status_prompt_add_typed_history(tmp);
    139 				free(tmp);
    140 			}
    141 		}
    142 	}
    143 	fclose(f);
    144 }
    145 
    146 /* Save status prompt history to file. */
    147 void
    148 status_prompt_save_history(void)
    149 {
    150 	FILE	*f;
    151 	u_int	 i, type;
    152 	char	*history_file;
    153 
    154 	if ((history_file = status_prompt_find_history_file()) == NULL)
    155 		return;
    156 	log_debug("saving history to %s", history_file);
    157 
    158 	f = fopen(history_file, "w");
    159 	if (f == NULL) {
    160 		log_debug("%s: %s", history_file, strerror(errno));
    161 		free(history_file);
    162 		return;
    163 	}
    164 	free(history_file);
    165 
    166 	for (type = 0; type < PROMPT_NTYPES; type++) {
    167 		for (i = 0; i < status_prompt_hsize[type]; i++) {
    168 			fputs(prompt_type_strings[type], f);
    169 			fputc(':', f);
    170 			fputs(status_prompt_hlist[type][i], f);
    171 			fputc('\n', f);
    172 		}
    173 	}
    174 	fclose(f);
    175 
    176 }
    177 
    178 /* Status timer callback. */
    179 static void
    180 status_timer_callback(__unused int fd, __unused short events, void *arg)
    181 {
    182 	struct client	*c = arg;
    183 	struct session	*s = c->session;
    184 	struct timeval	 tv;
    185 
    186 	evtimer_del(&c->status.timer);
    187 
    188 	if (s == NULL)
    189 		return;
    190 
    191 	if (c->message_string == NULL && c->prompt_string == NULL)
    192 		c->flags |= CLIENT_REDRAWSTATUS;
    193 
    194 	timerclear(&tv);
    195 	tv.tv_sec = options_get_number(s->options, "status-interval");
    196 
    197 	if (tv.tv_sec != 0)
    198 		evtimer_add(&c->status.timer, &tv);
    199 	log_debug("client %p, status interval %d", c, (int)tv.tv_sec);
    200 }
    201 
    202 /* Start status timer for client. */
    203 void
    204 status_timer_start(struct client *c)
    205 {
    206 	struct session	*s = c->session;
    207 
    208 	if (event_initialized(&c->status.timer))
    209 		evtimer_del(&c->status.timer);
    210 	else
    211 		evtimer_set(&c->status.timer, status_timer_callback, c);
    212 
    213 	if (s != NULL && options_get_number(s->options, "status"))
    214 		status_timer_callback(-1, 0, c);
    215 }
    216 
    217 /* Start status timer for all clients. */
    218 void
    219 status_timer_start_all(void)
    220 {
    221 	struct client	*c;
    222 
    223 	TAILQ_FOREACH(c, &clients, entry)
    224 		status_timer_start(c);
    225 }
    226 
    227 /* Update status cache. */
    228 void
    229 status_update_cache(struct session *s)
    230 {
    231 	s->statuslines = options_get_number(s->options, "status");
    232 	if (s->statuslines == 0)
    233 		s->statusat = -1;
    234 	else if (options_get_number(s->options, "status-position") == 0)
    235 		s->statusat = 0;
    236 	else
    237 		s->statusat = 1;
    238 }
    239 
    240 /* Get screen line of status line. -1 means off. */
    241 int
    242 status_at_line(struct client *c)
    243 {
    244 	struct session	*s = c->session;
    245 
    246 	if (c->flags & (CLIENT_STATUSOFF|CLIENT_CONTROL))
    247 		return (-1);
    248 	if (s->statusat != 1)
    249 		return (s->statusat);
    250 	return (c->tty.sy - status_line_size(c));
    251 }
    252 
    253 /* Get size of status line for client's session. 0 means off. */
    254 u_int
    255 status_line_size(struct client *c)
    256 {
    257 	struct session	*s = c->session;
    258 
    259 	if (c->flags & (CLIENT_STATUSOFF|CLIENT_CONTROL))
    260 		return (0);
    261 	if (s == NULL)
    262 		return (options_get_number(global_s_options, "status"));
    263 	return (s->statuslines);
    264 }
    265 
    266 /* Get the prompt line number for client's session. 1 means at the bottom. */
    267 u_int
    268 status_prompt_line_at(struct client *c)
    269 {
    270 	struct session	*s = c->session;
    271 	u_int		 line, lines;
    272 
    273 	lines = status_line_size(c);
    274 	if (lines == 0)
    275 		return (0);
    276 	line = options_get_number(s->options, "message-line");
    277 	if (line >= lines)
    278 		return (lines - 1);
    279 	return (line);
    280 }
    281 
    282 /* Get window at window list position. */
    283 struct style_range *
    284 status_get_range(struct client *c, u_int x, u_int y)
    285 {
    286 	struct status_line	*sl = &c->status;
    287 	struct style_range	*sr;
    288 
    289 	if (y >= nitems(sl->entries))
    290 		return (NULL);
    291 	TAILQ_FOREACH(sr, &sl->entries[y].ranges, entry) {
    292 		if (x >= sr->start && x < sr->end)
    293 			return (sr);
    294 	}
    295 	return (NULL);
    296 }
    297 
    298 /* Free all ranges. */
    299 static void
    300 status_free_ranges(struct style_ranges *srs)
    301 {
    302 	struct style_range	*sr, *sr1;
    303 
    304 	TAILQ_FOREACH_SAFE(sr, srs, entry, sr1) {
    305 		TAILQ_REMOVE(srs, sr, entry);
    306 		free(sr);
    307 	}
    308 }
    309 
    310 /* Save old status line. */
    311 static void
    312 status_push_screen(struct client *c)
    313 {
    314 	struct status_line *sl = &c->status;
    315 
    316 	if (sl->active == &sl->screen) {
    317 		sl->active = xmalloc(sizeof *sl->active);
    318 		screen_init(sl->active, c->tty.sx, status_line_size(c), 0);
    319 	}
    320 	sl->references++;
    321 }
    322 
    323 /* Restore old status line. */
    324 static void
    325 status_pop_screen(struct client *c)
    326 {
    327 	struct status_line *sl = &c->status;
    328 
    329 	if (--sl->references == 0) {
    330 		screen_free(sl->active);
    331 		free(sl->active);
    332 		sl->active = &sl->screen;
    333 	}
    334 }
    335 
    336 /* Initialize status line. */
    337 void
    338 status_init(struct client *c)
    339 {
    340 	struct status_line	*sl = &c->status;
    341 	u_int			 i;
    342 
    343 	for (i = 0; i < nitems(sl->entries); i++)
    344 		TAILQ_INIT(&sl->entries[i].ranges);
    345 
    346 	screen_init(&sl->screen, c->tty.sx, 1, 0);
    347 	sl->active = &sl->screen;
    348 }
    349 
    350 /* Free status line. */
    351 void
    352 status_free(struct client *c)
    353 {
    354 	struct status_line	*sl = &c->status;
    355 	u_int			 i;
    356 
    357 	for (i = 0; i < nitems(sl->entries); i++) {
    358 		status_free_ranges(&sl->entries[i].ranges);
    359 		free((void *)sl->entries[i].expanded);
    360 	}
    361 
    362 	if (event_initialized(&sl->timer))
    363 		evtimer_del(&sl->timer);
    364 
    365 	if (sl->active != &sl->screen) {
    366 		screen_free(sl->active);
    367 		free(sl->active);
    368 	}
    369 	screen_free(&sl->screen);
    370 }
    371 
    372 /* Draw status line for client. */
    373 int
    374 status_redraw(struct client *c)
    375 {
    376 	struct status_line		*sl = &c->status;
    377 	struct status_line_entry	*sle;
    378 	struct session			*s = c->session;
    379 	struct screen_write_ctx		 ctx;
    380 	struct grid_cell		 gc;
    381 	u_int				 lines, i, n, width = c->tty.sx;
    382 	int				 flags, force = 0, changed = 0, fg, bg;
    383 	struct options_entry		*o;
    384 	union options_value		*ov;
    385 	struct format_tree		*ft;
    386 	char				*expanded;
    387 
    388 	log_debug("%s enter", __func__);
    389 
    390 	/* Shouldn't get here if not the active screen. */
    391 	if (sl->active != &sl->screen)
    392 		fatalx("not the active screen");
    393 
    394 	/* No status line? */
    395 	lines = status_line_size(c);
    396 	if (c->tty.sy == 0 || lines == 0)
    397 		return (1);
    398 
    399 	/* Create format tree. */
    400 	flags = FORMAT_STATUS;
    401 	if (c->flags & CLIENT_STATUSFORCE)
    402 		flags |= FORMAT_FORCE;
    403 	ft = format_create(c, NULL, FORMAT_NONE, flags);
    404 	format_defaults(ft, c, NULL, NULL, NULL);
    405 
    406 	/* Set up default colour. */
    407 	style_apply(&gc, s->options, "status-style", ft);
    408 	fg = options_get_number(s->options, "status-fg");
    409 	if (!COLOUR_DEFAULT(fg))
    410 		gc.fg = fg;
    411 	bg = options_get_number(s->options, "status-bg");
    412 	if (!COLOUR_DEFAULT(bg))
    413 		gc.bg = bg;
    414 	if (!grid_cells_equal(&gc, &sl->style)) {
    415 		force = 1;
    416 		memcpy(&sl->style, &gc, sizeof sl->style);
    417 	}
    418 
    419 	/* Resize the target screen. */
    420 	if (screen_size_x(&sl->screen) != width ||
    421 	    screen_size_y(&sl->screen) != lines) {
    422 		screen_resize(&sl->screen, width, lines, 0);
    423 		changed = force = 1;
    424 	}
    425 	screen_write_start(&ctx, &sl->screen);
    426 
    427 	/* Write the status lines. */
    428 	o = options_get(s->options, "status-format");
    429 	if (o == NULL) {
    430 		for (n = 0; n < width * lines; n++)
    431 			screen_write_putc(&ctx, &gc, ' ');
    432 	} else {
    433 		for (i = 0; i < lines; i++) {
    434 			screen_write_cursormove(&ctx, 0, i, 0);
    435 
    436 			ov = options_array_get(o, i);
    437 			if (ov == NULL) {
    438 				for (n = 0; n < width; n++)
    439 					screen_write_putc(&ctx, &gc, ' ');
    440 				continue;
    441 			}
    442 			sle = &sl->entries[i];
    443 
    444 			expanded = format_expand_time(ft, ov->string);
    445 			if (!force &&
    446 			    sle->expanded != NULL &&
    447 			    strcmp(expanded, sle->expanded) == 0) {
    448 				free(expanded);
    449 				continue;
    450 			}
    451 			changed = 1;
    452 
    453 			for (n = 0; n < width; n++)
    454 				screen_write_putc(&ctx, &gc, ' ');
    455 			screen_write_cursormove(&ctx, 0, i, 0);
    456 
    457 			status_free_ranges(&sle->ranges);
    458 			format_draw(&ctx, &gc, width, expanded, &sle->ranges,
    459 			    0);
    460 
    461 			free(sle->expanded);
    462 			sle->expanded = expanded;
    463 		}
    464 	}
    465 	screen_write_stop(&ctx);
    466 
    467 	/* Free the format tree. */
    468 	format_free(ft);
    469 
    470 	/* Return if the status line has changed. */
    471 	log_debug("%s exit: force=%d, changed=%d", __func__, force, changed);
    472 	return (force || changed);
    473 }
    474 
    475 /* Set a status line message. */
    476 void
    477 status_message_set(struct client *c, int delay, int ignore_styles,
    478     int ignore_keys, int no_freeze, const char *fmt, ...)
    479 {
    480 	struct timeval	 tv;
    481 	va_list		 ap;
    482 	char		*s;
    483 
    484 	va_start(ap, fmt);
    485 	xvasprintf(&s, fmt, ap);
    486 	va_end(ap);
    487 
    488 	log_debug("%s: %s", __func__, s);
    489 
    490 	if (c == NULL) {
    491 		server_add_message("message: %s", s);
    492 		free(s);
    493 		return;
    494 	}
    495 
    496 	status_message_clear(c);
    497 	status_push_screen(c);
    498 	c->message_string = s;
    499 	server_add_message("%s message: %s", c->name, s);
    500 
    501 	/*
    502 	 * With delay -1, the display-time option is used; zero means wait for
    503 	 * key press; more than zero is the actual delay time in milliseconds.
    504 	 */
    505 	if (delay == -1)
    506 		delay = options_get_number(c->session->options, "display-time");
    507 	if (delay > 0) {
    508 		tv.tv_sec = delay / 1000;
    509 		tv.tv_usec = (delay % 1000) * 1000L;
    510 
    511 		if (event_initialized(&c->message_timer))
    512 			evtimer_del(&c->message_timer);
    513 		evtimer_set(&c->message_timer, status_message_callback, c);
    514 
    515 		evtimer_add(&c->message_timer, &tv);
    516 	}
    517 
    518 	if (delay != 0)
    519 		c->message_ignore_keys = ignore_keys;
    520 	c->message_ignore_styles = ignore_styles;
    521 
    522 	if (!no_freeze)
    523 		c->tty.flags |= TTY_FREEZE;
    524 	c->tty.flags |= TTY_NOCURSOR;
    525 	c->flags |= CLIENT_REDRAWSTATUS;
    526 }
    527 
    528 /* Clear status line message. */
    529 void
    530 status_message_clear(struct client *c)
    531 {
    532 	if (c->message_string == NULL)
    533 		return;
    534 
    535 	free(c->message_string);
    536 	c->message_string = NULL;
    537 
    538 	if (c->prompt_string == NULL)
    539 		c->tty.flags &= ~(TTY_NOCURSOR|TTY_FREEZE);
    540 	c->flags |= CLIENT_ALLREDRAWFLAGS; /* was frozen and may have changed */
    541 
    542 	status_pop_screen(c);
    543 }
    544 
    545 /* Clear status line message after timer expires. */
    546 static void
    547 status_message_callback(__unused int fd, __unused short event, void *data)
    548 {
    549 	struct client	*c = data;
    550 
    551 	status_message_clear(c);
    552 }
    553 
    554 /* Draw client message on status line of present else on last line. */
    555 int
    556 status_message_redraw(struct client *c)
    557 {
    558 	struct status_line	*sl = &c->status;
    559 	struct screen_write_ctx	 ctx;
    560 	struct session		*s = c->session;
    561 	struct screen		 old_screen;
    562 	size_t			 len;
    563 	u_int			 lines, offset, messageline;
    564 	struct grid_cell	 gc;
    565 	struct format_tree	*ft;
    566 
    567 	if (c->tty.sx == 0 || c->tty.sy == 0)
    568 		return (0);
    569 	memcpy(&old_screen, sl->active, sizeof old_screen);
    570 
    571 	lines = status_line_size(c);
    572 	if (lines <= 1)
    573 		lines = 1;
    574 	screen_init(sl->active, c->tty.sx, lines, 0);
    575 
    576 	messageline = status_prompt_line_at(c);
    577 	if (messageline > lines - 1)
    578 		messageline = lines - 1;
    579 
    580 	len = screen_write_strlen("%s", c->message_string);
    581 	if (len > c->tty.sx)
    582 		len = c->tty.sx;
    583 
    584 	ft = format_create_defaults(NULL, c, NULL, NULL, NULL);
    585 	style_apply(&gc, s->options, "message-style", ft);
    586 	format_free(ft);
    587 
    588 	screen_write_start(&ctx, sl->active);
    589 	screen_write_fast_copy(&ctx, &sl->screen, 0, 0, c->tty.sx, lines);
    590 	screen_write_cursormove(&ctx, 0, messageline, 0);
    591 	for (offset = 0; offset < c->tty.sx; offset++)
    592 		screen_write_putc(&ctx, &gc, ' ');
    593 	screen_write_cursormove(&ctx, 0, messageline, 0);
    594 	if (c->message_ignore_styles)
    595 		screen_write_nputs(&ctx, len, &gc, "%s", c->message_string);
    596 	else
    597 		format_draw(&ctx, &gc, c->tty.sx, c->message_string, NULL, 0);
    598 	screen_write_stop(&ctx);
    599 
    600 	if (grid_compare(sl->active->grid, old_screen.grid) == 0) {
    601 		screen_free(&old_screen);
    602 		return (0);
    603 	}
    604 	screen_free(&old_screen);
    605 	return (1);
    606 }
    607 
    608 /* Accept prompt immediately. */
    609 static enum cmd_retval
    610 status_prompt_accept(__unused struct cmdq_item *item, void *data)
    611 {
    612 	struct client	*c = data;
    613 
    614 	if (c->prompt_string != NULL) {
    615 		c->prompt_inputcb(c, c->prompt_data, "y", 1);
    616 		status_prompt_clear(c);
    617 	}
    618 	return (CMD_RETURN_NORMAL);
    619 }
    620 
    621 /* Enable status line prompt. */
    622 void
    623 status_prompt_set(struct client *c, struct cmd_find_state *fs,
    624     const char *msg, const char *input, prompt_input_cb inputcb,
    625     prompt_free_cb freecb, void *data, int flags, enum prompt_type prompt_type)
    626 {
    627 	struct format_tree	*ft;
    628 	char			*tmp;
    629 
    630 	server_client_clear_overlay(c);
    631 
    632 	if (fs != NULL)
    633 		ft = format_create_from_state(NULL, c, fs);
    634 	else
    635 		ft = format_create_defaults(NULL, c, NULL, NULL, NULL);
    636 
    637 	if (input == NULL)
    638 		input = "";
    639 
    640 	status_message_clear(c);
    641 	status_prompt_clear(c);
    642 	status_push_screen(c);
    643 
    644 	c->prompt_formats = ft;
    645 	c->prompt_string = xstrdup (msg);
    646 
    647 	if (flags & PROMPT_NOFORMAT)
    648 		tmp = xstrdup(input);
    649 	else
    650 		tmp = format_expand_time(ft, input);
    651 	if (flags & PROMPT_INCREMENTAL) {
    652 		c->prompt_last = xstrdup(tmp);
    653 		c->prompt_buffer = utf8_fromcstr("");
    654 	} else {
    655 		c->prompt_last = NULL;
    656 		c->prompt_buffer = utf8_fromcstr(tmp);
    657 	}
    658 	c->prompt_index = utf8_strlen(c->prompt_buffer);
    659 	free(tmp);
    660 
    661 	c->prompt_inputcb = inputcb;
    662 	c->prompt_freecb = freecb;
    663 	c->prompt_data = data;
    664 
    665 	memset(c->prompt_hindex, 0, sizeof c->prompt_hindex);
    666 
    667 	c->prompt_flags = flags;
    668 	c->prompt_type = prompt_type;
    669 	c->prompt_mode = PROMPT_ENTRY;
    670 
    671 	if (~flags & PROMPT_INCREMENTAL)
    672 		c->tty.flags |= TTY_FREEZE;
    673 	c->flags |= CLIENT_REDRAWSTATUS;
    674 
    675 	if (flags & PROMPT_INCREMENTAL)
    676 		c->prompt_inputcb(c, c->prompt_data, "=", 0);
    677 
    678 	if ((flags & PROMPT_SINGLE) && (flags & PROMPT_ACCEPT))
    679 		cmdq_append(c, cmdq_get_callback(status_prompt_accept, c));
    680 }
    681 
    682 /* Remove status line prompt. */
    683 void
    684 status_prompt_clear(struct client *c)
    685 {
    686 	if (c->prompt_string == NULL)
    687 		return;
    688 
    689 	if (c->prompt_freecb != NULL && c->prompt_data != NULL)
    690 		c->prompt_freecb(c->prompt_data);
    691 
    692 	free(c->prompt_last);
    693 	c->prompt_last = NULL;
    694 
    695 	format_free(c->prompt_formats);
    696 	c->prompt_formats = NULL;
    697 
    698 	free(c->prompt_string);
    699 	c->prompt_string = NULL;
    700 
    701 	free(c->prompt_buffer);
    702 	c->prompt_buffer = NULL;
    703 
    704 	free(c->prompt_saved);
    705 	c->prompt_saved = NULL;
    706 
    707 	c->tty.flags &= ~(TTY_NOCURSOR|TTY_FREEZE);
    708 	c->flags |= CLIENT_ALLREDRAWFLAGS; /* was frozen and may have changed */
    709 
    710 	status_pop_screen(c);
    711 }
    712 
    713 /* Update status line prompt with a new prompt string. */
    714 void
    715 status_prompt_update(struct client *c, const char *msg, const char *input)
    716 {
    717 	char	*tmp;
    718 
    719 	free(c->prompt_string);
    720 	c->prompt_string = xstrdup(msg);
    721 
    722 	free(c->prompt_buffer);
    723 	tmp = format_expand_time(c->prompt_formats, input);
    724 	c->prompt_buffer = utf8_fromcstr(tmp);
    725 	c->prompt_index = utf8_strlen(c->prompt_buffer);
    726 	free(tmp);
    727 
    728 	memset(c->prompt_hindex, 0, sizeof c->prompt_hindex);
    729 
    730 	c->flags |= CLIENT_REDRAWSTATUS;
    731 }
    732 
    733 /* Redraw character. Return 1 if can continue redrawing, 0 otherwise. */
    734 static int
    735 status_prompt_redraw_character(struct screen_write_ctx *ctx, u_int offset,
    736     u_int pwidth, u_int *width, struct grid_cell *gc,
    737     const struct utf8_data *ud)
    738 {
    739 	u_char	ch;
    740 
    741 	if (*width < offset) {
    742 		*width += ud->width;
    743 		return (1);
    744 	}
    745 	if (*width >= offset + pwidth)
    746 		return (0);
    747 	*width += ud->width;
    748 	if (*width > offset + pwidth)
    749 		return (0);
    750 
    751 	ch = *ud->data;
    752 	if (ud->size == 1 && (ch <= 0x1f || ch == 0x7f)) {
    753 		gc->data.data[0] = '^';
    754 		gc->data.data[1] = (ch == 0x7f) ? '?' : ch|0x40;
    755 		gc->data.size = gc->data.have = 2;
    756 		gc->data.width = 2;
    757 	} else
    758 		utf8_copy(&gc->data, ud);
    759 	screen_write_cell(ctx, gc);
    760 	return (1);
    761 }
    762 
    763 /*
    764  * Redraw quote indicator '^' if necessary. Return 1 if can continue redrawing,
    765  * 0 otherwise.
    766  */
    767 static int
    768 status_prompt_redraw_quote(const struct client *c, u_int pcursor,
    769     struct screen_write_ctx *ctx, u_int offset, u_int pwidth, u_int *width,
    770     struct grid_cell *gc)
    771 {
    772 	struct utf8_data	ud;
    773 
    774 	if (c->prompt_flags & PROMPT_QUOTENEXT && ctx->s->cx == pcursor + 1) {
    775 		utf8_set(&ud, '^');
    776 		return (status_prompt_redraw_character(ctx, offset, pwidth,
    777 		    width, gc, &ud));
    778 	}
    779 	return (1);
    780 }
    781 
    782 /* Draw client prompt on status line of present else on last line. */
    783 int
    784 status_prompt_redraw(struct client *c)
    785 {
    786 	struct status_line	*sl = &c->status;
    787 	struct screen_write_ctx	 ctx;
    788 	struct session		*s = c->session;
    789 	struct screen		 old_screen;
    790 	u_int			 i, lines, offset, left, start, width, n;
    791 	u_int			 pcursor, pwidth, promptline;
    792 	struct grid_cell	 gc;
    793 	struct format_tree	*ft = c->prompt_formats;
    794 	char			*prompt, *tmp;
    795 
    796 	if (c->tty.sx == 0 || c->tty.sy == 0)
    797 		return (0);
    798 	memcpy(&old_screen, sl->active, sizeof old_screen);
    799 
    800 	lines = status_line_size(c);
    801 	if (lines <= 1)
    802 		lines = 1;
    803 	screen_init(sl->active, c->tty.sx, lines, 0);
    804 
    805 	n = options_get_number(s->options, "prompt-cursor-colour");
    806 	sl->active->default_ccolour = n;
    807 	n = options_get_number(s->options, "prompt-cursor-style");
    808 	screen_set_cursor_style(n, &sl->active->default_cstyle,
    809 	    &sl->active->default_mode);
    810 
    811 	promptline = status_prompt_line_at(c);
    812 	if (promptline > lines - 1)
    813 		promptline = lines - 1;
    814 
    815 	if (c->prompt_mode == PROMPT_COMMAND)
    816 		style_apply(&gc, s->options, "message-command-style", ft);
    817 	else
    818 		style_apply(&gc, s->options, "message-style", ft);
    819 
    820 	tmp = utf8_tocstr(c->prompt_buffer);
    821 	format_add(c->prompt_formats, "prompt-input", "%s", tmp);
    822 	prompt = format_expand_time(c->prompt_formats, c->prompt_string);
    823 	free (tmp);
    824 
    825 	start = format_width(prompt);
    826 	if (start > c->tty.sx)
    827 		start = c->tty.sx;
    828 
    829 	screen_write_start(&ctx, sl->active);
    830 	screen_write_fast_copy(&ctx, &sl->screen, 0, 0, c->tty.sx, lines);
    831 	screen_write_cursormove(&ctx, 0, promptline, 0);
    832 	for (offset = 0; offset < c->tty.sx; offset++)
    833 		screen_write_putc(&ctx, &gc, ' ');
    834 	screen_write_cursormove(&ctx, 0, promptline, 0);
    835 	format_draw(&ctx, &gc, start, prompt, NULL, 0);
    836 	screen_write_cursormove(&ctx, start, promptline, 0);
    837 
    838 	left = c->tty.sx - start;
    839 	if (left == 0)
    840 		goto finished;
    841 
    842 	pcursor = utf8_strwidth(c->prompt_buffer, c->prompt_index);
    843 	pwidth = utf8_strwidth(c->prompt_buffer, -1);
    844 	if (c->prompt_flags & PROMPT_QUOTENEXT)
    845 		pwidth++;
    846 	if (pcursor >= left) {
    847 		/*
    848 		 * The cursor would be outside the screen so start drawing
    849 		 * with it on the right.
    850 		 */
    851 		offset = (pcursor - left) + 1;
    852 		pwidth = left;
    853 	} else
    854 		offset = 0;
    855 	if (pwidth > left)
    856 		pwidth = left;
    857 	c->prompt_cursor = start + pcursor - offset;
    858 
    859 	width = 0;
    860 	for (i = 0; c->prompt_buffer[i].size != 0; i++) {
    861 		if (!status_prompt_redraw_quote(c, pcursor, &ctx, offset,
    862 		    pwidth, &width, &gc))
    863 			break;
    864 		if (!status_prompt_redraw_character(&ctx, offset, pwidth,
    865 		    &width, &gc, &c->prompt_buffer[i]))
    866 			break;
    867 	}
    868 	status_prompt_redraw_quote(c, pcursor, &ctx, offset, pwidth, &width,
    869 	    &gc);
    870 
    871 finished:
    872 	screen_write_stop(&ctx);
    873 
    874 	if (grid_compare(sl->active->grid, old_screen.grid) == 0) {
    875 		screen_free(&old_screen);
    876 		return (0);
    877 	}
    878 	screen_free(&old_screen);
    879 	return (1);
    880 }
    881 
    882 /* Is this a separator? */
    883 static int
    884 status_prompt_in_list(const char *ws, const struct utf8_data *ud)
    885 {
    886 	if (ud->size != 1 || ud->width != 1)
    887 		return (0);
    888 	return (strchr(ws, *ud->data) != NULL);
    889 }
    890 
    891 /* Is this a space? */
    892 static int
    893 status_prompt_space(const struct utf8_data *ud)
    894 {
    895 	if (ud->size != 1 || ud->width != 1)
    896 		return (0);
    897 	return (*ud->data == ' ');
    898 }
    899 
    900 /*
    901  * Translate key from vi to emacs. Return 0 to drop key, 1 to process the key
    902  * as an emacs key; return 2 to append to the buffer.
    903  */
    904 static int
    905 status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
    906 {
    907 	if (c->prompt_mode == PROMPT_ENTRY) {
    908 		switch (key) {
    909 		case 'a'|KEYC_CTRL:
    910 		case 'c'|KEYC_CTRL:
    911 		case 'e'|KEYC_CTRL:
    912 		case 'g'|KEYC_CTRL:
    913 		case 'h'|KEYC_CTRL:
    914 		case '\011': /* Tab */
    915 		case 'k'|KEYC_CTRL:
    916 		case 'n'|KEYC_CTRL:
    917 		case 'p'|KEYC_CTRL:
    918 		case 't'|KEYC_CTRL:
    919 		case 'u'|KEYC_CTRL:
    920 		case 'v'|KEYC_CTRL:
    921 		case 'w'|KEYC_CTRL:
    922 		case 'y'|KEYC_CTRL:
    923 		case '\n':
    924 		case '\r':
    925 		case KEYC_LEFT|KEYC_CTRL:
    926 		case KEYC_RIGHT|KEYC_CTRL:
    927 		case KEYC_BSPACE:
    928 		case KEYC_DC:
    929 		case KEYC_DOWN:
    930 		case KEYC_END:
    931 		case KEYC_HOME:
    932 		case KEYC_LEFT:
    933 		case KEYC_RIGHT:
    934 		case KEYC_UP:
    935 			*new_key = key;
    936 			return (1);
    937 		case '\033': /* Escape */
    938 			c->prompt_mode = PROMPT_COMMAND;
    939 			c->flags |= CLIENT_REDRAWSTATUS;
    940 			return (0);
    941 		}
    942 		*new_key = key;
    943 		return (2);
    944 	}
    945 
    946 	switch (key) {
    947 	case KEYC_BSPACE:
    948 		*new_key = KEYC_LEFT;
    949 		return (1);
    950 	case 'A':
    951 	case 'I':
    952 	case 'C':
    953 	case 's':
    954 	case 'a':
    955 		c->prompt_mode = PROMPT_ENTRY;
    956 		c->flags |= CLIENT_REDRAWSTATUS;
    957 		break; /* switch mode and... */
    958 	case 'S':
    959 		c->prompt_mode = PROMPT_ENTRY;
    960 		c->flags |= CLIENT_REDRAWSTATUS;
    961 		*new_key = 'u'|KEYC_CTRL;
    962 		return (1);
    963 	case 'i':
    964 	case '\033': /* Escape */
    965 		c->prompt_mode = PROMPT_ENTRY;
    966 		c->flags |= CLIENT_REDRAWSTATUS;
    967 		return (0);
    968 	}
    969 
    970 	switch (key) {
    971 	case 'A':
    972 	case '$':
    973 		*new_key = KEYC_END;
    974 		return (1);
    975 	case 'I':
    976 	case '0':
    977 	case '^':
    978 		*new_key = KEYC_HOME;
    979 		return (1);
    980 	case 'C':
    981 	case 'D':
    982 		*new_key = 'k'|KEYC_CTRL;
    983 		return (1);
    984 	case KEYC_BSPACE:
    985 	case 'X':
    986 		*new_key = KEYC_BSPACE;
    987 		return (1);
    988 	case 'b':
    989 		*new_key = 'b'|KEYC_META;
    990 		return (1);
    991 	case 'B':
    992 		*new_key = 'B'|KEYC_VI;
    993 		return (1);
    994 	case 'd':
    995 		*new_key = 'u'|KEYC_CTRL;
    996 		return (1);
    997 	case 'e':
    998 		*new_key = 'e'|KEYC_VI;
    999 		return (1);
   1000 	case 'E':
   1001 		*new_key = 'E'|KEYC_VI;
   1002 		return (1);
   1003 	case 'w':
   1004 		*new_key = 'w'|KEYC_VI;
   1005 		return (1);
   1006 	case 'W':
   1007 		*new_key = 'W'|KEYC_VI;
   1008 		return (1);
   1009 	case 'p':
   1010 		*new_key = 'y'|KEYC_CTRL;
   1011 		return (1);
   1012 	case 'q':
   1013 		*new_key = 'c'|KEYC_CTRL;
   1014 		return (1);
   1015 	case 's':
   1016 	case KEYC_DC:
   1017 	case 'x':
   1018 		*new_key = KEYC_DC;
   1019 		return (1);
   1020 	case KEYC_DOWN:
   1021 	case 'j':
   1022 		*new_key = KEYC_DOWN;
   1023 		return (1);
   1024 	case KEYC_LEFT:
   1025 	case 'h':
   1026 		*new_key = KEYC_LEFT;
   1027 		return (1);
   1028 	case 'a':
   1029 	case KEYC_RIGHT:
   1030 	case 'l':
   1031 		*new_key = KEYC_RIGHT;
   1032 		return (1);
   1033 	case KEYC_UP:
   1034 	case 'k':
   1035 		*new_key = KEYC_UP;
   1036 		return (1);
   1037 	case 'h'|KEYC_CTRL:
   1038 	case 'c'|KEYC_CTRL:
   1039 	case '\n':
   1040 	case '\r':
   1041 		return (1);
   1042 	}
   1043 	return (0);
   1044 }
   1045 
   1046 /* Paste into prompt. */
   1047 static int
   1048 status_prompt_paste(struct client *c)
   1049 {
   1050 	struct paste_buffer	*pb;
   1051 	const char		*bufdata;
   1052 	size_t			 size, n, bufsize;
   1053 	u_int			 i;
   1054 	struct utf8_data	*ud, *udp;
   1055 	enum utf8_state		 more;
   1056 
   1057 	size = utf8_strlen(c->prompt_buffer);
   1058 	if (c->prompt_saved != NULL) {
   1059 		ud = c->prompt_saved;
   1060 		n = utf8_strlen(c->prompt_saved);
   1061 	} else {
   1062 		if ((pb = paste_get_top(NULL)) == NULL)
   1063 			return (0);
   1064 		bufdata = paste_buffer_data(pb, &bufsize);
   1065 		ud = udp = xreallocarray(NULL, bufsize + 1, sizeof *ud);
   1066 		for (i = 0; i != bufsize; /* nothing */) {
   1067 			more = utf8_open(udp, bufdata[i]);
   1068 			if (more == UTF8_MORE) {
   1069 				while (++i != bufsize && more == UTF8_MORE)
   1070 					more = utf8_append(udp, bufdata[i]);
   1071 				if (more == UTF8_DONE) {
   1072 					udp++;
   1073 					continue;
   1074 				}
   1075 				i -= udp->have;
   1076 			}
   1077 			if (bufdata[i] <= 31 || bufdata[i] >= 127)
   1078 				break;
   1079 			utf8_set(udp, bufdata[i]);
   1080 			udp++;
   1081 			i++;
   1082 		}
   1083 		udp->size = 0;
   1084 		n = udp - ud;
   1085 	}
   1086 	if (n != 0) {
   1087 		c->prompt_buffer = xreallocarray(c->prompt_buffer, size + n + 1,
   1088 		    sizeof *c->prompt_buffer);
   1089 		if (c->prompt_index == size) {
   1090 			memcpy(c->prompt_buffer + c->prompt_index, ud,
   1091 			    n * sizeof *c->prompt_buffer);
   1092 			c->prompt_index += n;
   1093 			c->prompt_buffer[c->prompt_index].size = 0;
   1094 		} else {
   1095 			memmove(c->prompt_buffer + c->prompt_index + n,
   1096 			    c->prompt_buffer + c->prompt_index,
   1097 			    (size + 1 - c->prompt_index) *
   1098 			    sizeof *c->prompt_buffer);
   1099 			memcpy(c->prompt_buffer + c->prompt_index, ud,
   1100 			    n * sizeof *c->prompt_buffer);
   1101 			c->prompt_index += n;
   1102 		}
   1103 	}
   1104 	if (ud != c->prompt_saved)
   1105 		free(ud);
   1106 	return (1);
   1107 }
   1108 
   1109 /* Finish completion. */
   1110 static int
   1111 status_prompt_replace_complete(struct client *c, const char *s)
   1112 {
   1113 	char			 word[64], *allocated = NULL;
   1114 	size_t			 size, n, off, idx, used;
   1115 	struct utf8_data	*first, *last, *ud;
   1116 
   1117 	/* Work out where the cursor currently is. */
   1118 	idx = c->prompt_index;
   1119 	if (idx != 0)
   1120 		idx--;
   1121 	size = utf8_strlen(c->prompt_buffer);
   1122 
   1123 	/* Find the word we are in. */
   1124 	first = &c->prompt_buffer[idx];
   1125 	while (first > c->prompt_buffer && !status_prompt_space(first))
   1126 		first--;
   1127 	while (first->size != 0 && status_prompt_space(first))
   1128 		first++;
   1129 	last = &c->prompt_buffer[idx];
   1130 	while (last->size != 0 && !status_prompt_space(last))
   1131 		last++;
   1132 	while (last > c->prompt_buffer && status_prompt_space(last))
   1133 		last--;
   1134 	if (last->size != 0)
   1135 		last++;
   1136 	if (last < first)
   1137 		return (0);
   1138 	if (s == NULL) {
   1139 		used = 0;
   1140 		for (ud = first; ud < last; ud++) {
   1141 			if (used + ud->size >= sizeof word)
   1142 				break;
   1143 			memcpy(word + used, ud->data, ud->size);
   1144 			used += ud->size;
   1145 		}
   1146 		if (ud != last)
   1147 			return (0);
   1148 		word[used] = '\0';
   1149 	}
   1150 
   1151 	/* Try to complete it. */
   1152 	if (s == NULL) {
   1153 		allocated = status_prompt_complete(c, word,
   1154 		    first - c->prompt_buffer);
   1155 		if (allocated == NULL)
   1156 			return (0);
   1157 		s = allocated;
   1158 	}
   1159 
   1160 	/* Trim out word. */
   1161 	n = size - (last - c->prompt_buffer) + 1; /* with \0 */
   1162 	memmove(first, last, n * sizeof *c->prompt_buffer);
   1163 	size -= last - first;
   1164 
   1165 	/* Insert the new word. */
   1166 	size += strlen(s);
   1167 	off = first - c->prompt_buffer;
   1168 	c->prompt_buffer = xreallocarray(c->prompt_buffer, size + 1,
   1169 	    sizeof *c->prompt_buffer);
   1170 	first = c->prompt_buffer + off;
   1171 	memmove(first + strlen(s), first, n * sizeof *c->prompt_buffer);
   1172 	for (idx = 0; idx < strlen(s); idx++)
   1173 		utf8_set(&first[idx], s[idx]);
   1174 	c->prompt_index = (first - c->prompt_buffer) + strlen(s);
   1175 
   1176 	free(allocated);
   1177 	return (1);
   1178 }
   1179 
   1180 /* Prompt forward to the next beginning of a word. */
   1181 static void
   1182 status_prompt_forward_word(struct client *c, size_t size, int vi,
   1183     const char *separators)
   1184 {
   1185 	size_t		 idx = c->prompt_index;
   1186 	int		 word_is_separators;
   1187 
   1188 	/* In emacs mode, skip until the first non-whitespace character. */
   1189 	if (!vi)
   1190 		while (idx != size &&
   1191 		    status_prompt_space(&c->prompt_buffer[idx]))
   1192 			idx++;
   1193 
   1194 	/* Can't move forward if we're already at the end. */
   1195 	if (idx == size) {
   1196 		c->prompt_index = idx;
   1197 		return;
   1198 	}
   1199 
   1200 	/* Determine the current character class (separators or not). */
   1201 	word_is_separators = status_prompt_in_list(separators,
   1202 	    &c->prompt_buffer[idx]) &&
   1203 	    !status_prompt_space(&c->prompt_buffer[idx]);
   1204 
   1205 	/* Skip ahead until the first space or opposite character class. */
   1206 	do {
   1207 		idx++;
   1208 		if (status_prompt_space(&c->prompt_buffer[idx])) {
   1209 			/* In vi mode, go to the start of the next word. */
   1210 			if (vi)
   1211 				while (idx != size &&
   1212 				    status_prompt_space(&c->prompt_buffer[idx]))
   1213 					idx++;
   1214 			break;
   1215 		}
   1216 	} while (idx != size && word_is_separators == status_prompt_in_list(
   1217 	    separators, &c->prompt_buffer[idx]));
   1218 
   1219 	c->prompt_index = idx;
   1220 }
   1221 
   1222 /* Prompt forward to the next end of a word. */
   1223 static void
   1224 status_prompt_end_word(struct client *c, size_t size, const char *separators)
   1225 {
   1226 	size_t		 idx = c->prompt_index;
   1227 	int		 word_is_separators;
   1228 
   1229 	/* Can't move forward if we're already at the end. */
   1230 	if (idx == size)
   1231 		return;
   1232 
   1233 	/* Find the next word. */
   1234 	do {
   1235 		idx++;
   1236 		if (idx == size) {
   1237 			c->prompt_index = idx;
   1238 			return;
   1239 		}
   1240 	} while (status_prompt_space(&c->prompt_buffer[idx]));
   1241 
   1242 	/* Determine the character class (separators or not). */
   1243 	word_is_separators = status_prompt_in_list(separators,
   1244 	    &c->prompt_buffer[idx]);
   1245 
   1246 	/* Skip ahead until the next space or opposite character class. */
   1247 	do {
   1248 		idx++;
   1249 		if (idx == size)
   1250 			break;
   1251 	} while (!status_prompt_space(&c->prompt_buffer[idx]) &&
   1252 	    word_is_separators == status_prompt_in_list(separators,
   1253 	    &c->prompt_buffer[idx]));
   1254 
   1255 	/* Back up to the previous character to stop at the end of the word. */
   1256 	c->prompt_index = idx - 1;
   1257 }
   1258 
   1259 /* Prompt backward to the previous beginning of a word. */
   1260 static void
   1261 status_prompt_backward_word(struct client *c, const char *separators)
   1262 {
   1263 	size_t	idx = c->prompt_index;
   1264 	int	word_is_separators;
   1265 
   1266 	/* Find non-whitespace. */
   1267 	while (idx != 0) {
   1268 		--idx;
   1269 		if (!status_prompt_space(&c->prompt_buffer[idx]))
   1270 			break;
   1271 	}
   1272 	word_is_separators = status_prompt_in_list(separators,
   1273 	    &c->prompt_buffer[idx]);
   1274 
   1275 	/* Find the character before the beginning of the word. */
   1276 	while (idx != 0) {
   1277 		--idx;
   1278 		if (status_prompt_space(&c->prompt_buffer[idx]) ||
   1279 		    word_is_separators != status_prompt_in_list(separators,
   1280 		    &c->prompt_buffer[idx])) {
   1281 			/* Go back to the word. */
   1282 			idx++;
   1283 			break;
   1284 		}
   1285 	}
   1286 	c->prompt_index = idx;
   1287 }
   1288 
   1289 /* Handle keys in prompt. */
   1290 int
   1291 status_prompt_key(struct client *c, key_code key)
   1292 {
   1293 	struct options		*oo = c->session->options;
   1294 	char			*s, *cp, prefix = '=';
   1295 	const char		*histstr, *separators = NULL, *keystring;
   1296 	size_t			 size, idx;
   1297 	struct utf8_data	 tmp;
   1298 	int			 keys, word_is_separators;
   1299 
   1300 	if (c->prompt_flags & PROMPT_KEY) {
   1301 		keystring = key_string_lookup_key(key, 0);
   1302 		c->prompt_inputcb(c, c->prompt_data, keystring, 1);
   1303 		status_prompt_clear(c);
   1304 		return (0);
   1305 	}
   1306 	size = utf8_strlen(c->prompt_buffer);
   1307 
   1308 	if (c->prompt_flags & PROMPT_NUMERIC) {
   1309 		if (key >= '0' && key <= '9')
   1310 			goto append_key;
   1311 		s = utf8_tocstr(c->prompt_buffer);
   1312 		c->prompt_inputcb(c, c->prompt_data, s, 1);
   1313 		status_prompt_clear(c);
   1314 		free(s);
   1315 		return (1);
   1316 	}
   1317 	key &= ~KEYC_MASK_FLAGS;
   1318 
   1319 	if (c->prompt_flags & (PROMPT_SINGLE|PROMPT_QUOTENEXT)) {
   1320 		if ((key & KEYC_MASK_KEY) == KEYC_BSPACE)
   1321 			key = 0x7f;
   1322 		else if ((key & KEYC_MASK_KEY) > 0x7f) {
   1323 			if (!KEYC_IS_UNICODE(key))
   1324 				return (0);
   1325 			key &= KEYC_MASK_KEY;
   1326 		} else
   1327 			key &= (key & KEYC_CTRL) ? 0x1f : KEYC_MASK_KEY;
   1328 		c->prompt_flags &= ~PROMPT_QUOTENEXT;
   1329 		goto append_key;
   1330 	}
   1331 
   1332 	keys = options_get_number(c->session->options, "status-keys");
   1333 	if (keys == MODEKEY_VI) {
   1334 		switch (status_prompt_translate_key(c, key, &key)) {
   1335 		case 1:
   1336 			goto process_key;
   1337 		case 2:
   1338 			goto append_key;
   1339 		default:
   1340 			return (0);
   1341 		}
   1342 	}
   1343 
   1344 process_key:
   1345 	switch (key) {
   1346 	case KEYC_LEFT:
   1347 	case 'b'|KEYC_CTRL:
   1348 		if (c->prompt_index > 0) {
   1349 			c->prompt_index--;
   1350 			break;
   1351 		}
   1352 		break;
   1353 	case KEYC_RIGHT:
   1354 	case 'f'|KEYC_CTRL:
   1355 		if (c->prompt_index < size) {
   1356 			c->prompt_index++;
   1357 			break;
   1358 		}
   1359 		break;
   1360 	case KEYC_HOME:
   1361 	case 'a'|KEYC_CTRL:
   1362 		if (c->prompt_index != 0) {
   1363 			c->prompt_index = 0;
   1364 			break;
   1365 		}
   1366 		break;
   1367 	case KEYC_END:
   1368 	case 'e'|KEYC_CTRL:
   1369 		if (c->prompt_index != size) {
   1370 			c->prompt_index = size;
   1371 			break;
   1372 		}
   1373 		break;
   1374 	case '\011': /* Tab */
   1375 		if (status_prompt_replace_complete(c, NULL))
   1376 			goto changed;
   1377 		break;
   1378 	case KEYC_BSPACE:
   1379 	case 'h'|KEYC_CTRL:
   1380 		if (c->prompt_index != 0) {
   1381 			if (c->prompt_index == size)
   1382 				c->prompt_buffer[--c->prompt_index].size = 0;
   1383 			else {
   1384 				memmove(c->prompt_buffer + c->prompt_index - 1,
   1385 				    c->prompt_buffer + c->prompt_index,
   1386 				    (size + 1 - c->prompt_index) *
   1387 				    sizeof *c->prompt_buffer);
   1388 				c->prompt_index--;
   1389 			}
   1390 			goto changed;
   1391 		}
   1392 		break;
   1393 	case KEYC_DC:
   1394 	case 'd'|KEYC_CTRL:
   1395 		if (c->prompt_index != size) {
   1396 			memmove(c->prompt_buffer + c->prompt_index,
   1397 			    c->prompt_buffer + c->prompt_index + 1,
   1398 			    (size + 1 - c->prompt_index) *
   1399 			    sizeof *c->prompt_buffer);
   1400 			goto changed;
   1401 		}
   1402 		break;
   1403 	case 'u'|KEYC_CTRL:
   1404 		c->prompt_buffer[0].size = 0;
   1405 		c->prompt_index = 0;
   1406 		goto changed;
   1407 	case 'k'|KEYC_CTRL:
   1408 		if (c->prompt_index < size) {
   1409 			c->prompt_buffer[c->prompt_index].size = 0;
   1410 			goto changed;
   1411 		}
   1412 		break;
   1413 	case 'w'|KEYC_CTRL:
   1414 		separators = options_get_string(oo, "word-separators");
   1415 		idx = c->prompt_index;
   1416 
   1417 		/* Find non-whitespace. */
   1418 		while (idx != 0) {
   1419 			idx--;
   1420 			if (!status_prompt_space(&c->prompt_buffer[idx]))
   1421 				break;
   1422 		}
   1423 		word_is_separators = status_prompt_in_list(separators,
   1424 		    &c->prompt_buffer[idx]);
   1425 
   1426 		/* Find the character before the beginning of the word. */
   1427 		while (idx != 0) {
   1428 			idx--;
   1429 			if (status_prompt_space(&c->prompt_buffer[idx]) ||
   1430 			    word_is_separators != status_prompt_in_list(
   1431 			    separators, &c->prompt_buffer[idx])) {
   1432 				/* Go back to the word. */
   1433 				idx++;
   1434 				break;
   1435 			}
   1436 		}
   1437 
   1438 		free(c->prompt_saved);
   1439 		c->prompt_saved = xcalloc(sizeof *c->prompt_buffer,
   1440 		    (c->prompt_index - idx) + 1);
   1441 		memcpy(c->prompt_saved, c->prompt_buffer + idx,
   1442 		    (c->prompt_index - idx) * sizeof *c->prompt_buffer);
   1443 
   1444 		memmove(c->prompt_buffer + idx,
   1445 		    c->prompt_buffer + c->prompt_index,
   1446 		    (size + 1 - c->prompt_index) *
   1447 		    sizeof *c->prompt_buffer);
   1448 		memset(c->prompt_buffer + size - (c->prompt_index - idx),
   1449 		    '\0', (c->prompt_index - idx) * sizeof *c->prompt_buffer);
   1450 		c->prompt_index = idx;
   1451 
   1452 		goto changed;
   1453 	case KEYC_RIGHT|KEYC_CTRL:
   1454 	case 'f'|KEYC_META:
   1455 		separators = options_get_string(oo, "word-separators");
   1456 		status_prompt_forward_word(c, size, 0, separators);
   1457 		goto changed;
   1458 	case 'E'|KEYC_VI:
   1459 		status_prompt_end_word(c, size, "");
   1460 		goto changed;
   1461 	case 'e'|KEYC_VI:
   1462 		separators = options_get_string(oo, "word-separators");
   1463 		status_prompt_end_word(c, size, separators);
   1464 		goto changed;
   1465 	case 'W'|KEYC_VI:
   1466 		status_prompt_forward_word(c, size, 1, "");
   1467 		goto changed;
   1468 	case 'w'|KEYC_VI:
   1469 		separators = options_get_string(oo, "word-separators");
   1470 		status_prompt_forward_word(c, size, 1, separators);
   1471 		goto changed;
   1472 	case 'B'|KEYC_VI:
   1473 		status_prompt_backward_word(c, "");
   1474 		goto changed;
   1475 	case KEYC_LEFT|KEYC_CTRL:
   1476 	case 'b'|KEYC_META:
   1477 		separators = options_get_string(oo, "word-separators");
   1478 		status_prompt_backward_word(c, separators);
   1479 		goto changed;
   1480 	case KEYC_UP:
   1481 	case 'p'|KEYC_CTRL:
   1482 		histstr = status_prompt_up_history(c->prompt_hindex,
   1483 		    c->prompt_type);
   1484 		if (histstr == NULL)
   1485 			break;
   1486 		free(c->prompt_buffer);
   1487 		c->prompt_buffer = utf8_fromcstr(histstr);
   1488 		c->prompt_index = utf8_strlen(c->prompt_buffer);
   1489 		goto changed;
   1490 	case KEYC_DOWN:
   1491 	case 'n'|KEYC_CTRL:
   1492 		histstr = status_prompt_down_history(c->prompt_hindex,
   1493 		    c->prompt_type);
   1494 		if (histstr == NULL)
   1495 			break;
   1496 		free(c->prompt_buffer);
   1497 		c->prompt_buffer = utf8_fromcstr(histstr);
   1498 		c->prompt_index = utf8_strlen(c->prompt_buffer);
   1499 		goto changed;
   1500 	case 'y'|KEYC_CTRL:
   1501 		if (status_prompt_paste(c))
   1502 			goto changed;
   1503 		break;
   1504 	case 't'|KEYC_CTRL:
   1505 		idx = c->prompt_index;
   1506 		if (idx < size)
   1507 			idx++;
   1508 		if (idx >= 2) {
   1509 			utf8_copy(&tmp, &c->prompt_buffer[idx - 2]);
   1510 			utf8_copy(&c->prompt_buffer[idx - 2],
   1511 			    &c->prompt_buffer[idx - 1]);
   1512 			utf8_copy(&c->prompt_buffer[idx - 1], &tmp);
   1513 			c->prompt_index = idx;
   1514 			goto changed;
   1515 		}
   1516 		break;
   1517 	case '\r':
   1518 	case '\n':
   1519 		s = utf8_tocstr(c->prompt_buffer);
   1520 		if (*s != '\0')
   1521 			status_prompt_add_history(s, c->prompt_type);
   1522 		if (c->prompt_inputcb(c, c->prompt_data, s, 1) == 0)
   1523 			status_prompt_clear(c);
   1524 		free(s);
   1525 		break;
   1526 	case '\033': /* Escape */
   1527 	case 'c'|KEYC_CTRL:
   1528 	case 'g'|KEYC_CTRL:
   1529 		if (c->prompt_inputcb(c, c->prompt_data, NULL, 1) == 0)
   1530 			status_prompt_clear(c);
   1531 		break;
   1532 	case 'r'|KEYC_CTRL:
   1533 		if (~c->prompt_flags & PROMPT_INCREMENTAL)
   1534 			break;
   1535 		if (c->prompt_buffer[0].size == 0) {
   1536 			prefix = '=';
   1537 			free(c->prompt_buffer);
   1538 			c->prompt_buffer = utf8_fromcstr(c->prompt_last);
   1539 			c->prompt_index = utf8_strlen(c->prompt_buffer);
   1540 		} else
   1541 			prefix = '-';
   1542 		goto changed;
   1543 	case 's'|KEYC_CTRL:
   1544 		if (~c->prompt_flags & PROMPT_INCREMENTAL)
   1545 			break;
   1546 		if (c->prompt_buffer[0].size == 0) {
   1547 			prefix = '=';
   1548 			free(c->prompt_buffer);
   1549 			c->prompt_buffer = utf8_fromcstr(c->prompt_last);
   1550 			c->prompt_index = utf8_strlen(c->prompt_buffer);
   1551 		} else
   1552 			prefix = '+';
   1553 		goto changed;
   1554 	case 'v'|KEYC_CTRL:
   1555 		c->prompt_flags |= PROMPT_QUOTENEXT;
   1556 		break;
   1557 	default:
   1558 		goto append_key;
   1559 	}
   1560 
   1561 	c->flags |= CLIENT_REDRAWSTATUS;
   1562 	return (0);
   1563 
   1564 append_key:
   1565 	if (key <= 0x7f) {
   1566 		utf8_set(&tmp, key);
   1567 		if (key <= 0x1f || key == 0x7f)
   1568 			tmp.width = 2;
   1569 	} else if (KEYC_IS_UNICODE(key))
   1570 		utf8_to_data(key, &tmp);
   1571 	else
   1572 		return (0);
   1573 
   1574 	c->prompt_buffer = xreallocarray(c->prompt_buffer, size + 2,
   1575 	    sizeof *c->prompt_buffer);
   1576 
   1577 	if (c->prompt_index == size) {
   1578 		utf8_copy(&c->prompt_buffer[c->prompt_index], &tmp);
   1579 		c->prompt_index++;
   1580 		c->prompt_buffer[c->prompt_index].size = 0;
   1581 	} else {
   1582 		memmove(c->prompt_buffer + c->prompt_index + 1,
   1583 		    c->prompt_buffer + c->prompt_index,
   1584 		    (size + 1 - c->prompt_index) *
   1585 		    sizeof *c->prompt_buffer);
   1586 		utf8_copy(&c->prompt_buffer[c->prompt_index], &tmp);
   1587 		c->prompt_index++;
   1588 	}
   1589 
   1590 	if (c->prompt_flags & PROMPT_SINGLE) {
   1591 		if (utf8_strlen(c->prompt_buffer) != 1)
   1592 			status_prompt_clear(c);
   1593 		else {
   1594 			s = utf8_tocstr(c->prompt_buffer);
   1595 			if (c->prompt_inputcb(c, c->prompt_data, s, 1) == 0)
   1596 				status_prompt_clear(c);
   1597 			free(s);
   1598 		}
   1599 	}
   1600 
   1601 changed:
   1602 	c->flags |= CLIENT_REDRAWSTATUS;
   1603 	if (c->prompt_flags & PROMPT_INCREMENTAL) {
   1604 		s = utf8_tocstr(c->prompt_buffer);
   1605 		xasprintf(&cp, "%c%s", prefix, s);
   1606 		c->prompt_inputcb(c, c->prompt_data, cp, 0);
   1607 		free(cp);
   1608 		free(s);
   1609 	}
   1610 	return (0);
   1611 }
   1612 
   1613 /* Get previous line from the history. */
   1614 static const char *
   1615 status_prompt_up_history(u_int *idx, u_int type)
   1616 {
   1617 	/*
   1618 	 * History runs from 0 to size - 1. Index is from 0 to size. Zero is
   1619 	 * empty.
   1620 	 */
   1621 
   1622 	if (status_prompt_hsize[type] == 0 ||
   1623 	    idx[type] == status_prompt_hsize[type])
   1624 		return (NULL);
   1625 	idx[type]++;
   1626 	return (status_prompt_hlist[type][status_prompt_hsize[type] - idx[type]]);
   1627 }
   1628 
   1629 /* Get next line from the history. */
   1630 static const char *
   1631 status_prompt_down_history(u_int *idx, u_int type)
   1632 {
   1633 	if (status_prompt_hsize[type] == 0 || idx[type] == 0)
   1634 		return ("");
   1635 	idx[type]--;
   1636 	if (idx[type] == 0)
   1637 		return ("");
   1638 	return (status_prompt_hlist[type][status_prompt_hsize[type] - idx[type]]);
   1639 }
   1640 
   1641 /* Add line to the history. */
   1642 static void
   1643 status_prompt_add_history(const char *line, u_int type)
   1644 {
   1645 	u_int	i, oldsize, newsize, freecount, hlimit, new = 1;
   1646 	size_t	movesize;
   1647 
   1648 	oldsize = status_prompt_hsize[type];
   1649 	if (oldsize > 0 &&
   1650 	    strcmp(status_prompt_hlist[type][oldsize - 1], line) == 0)
   1651 		new = 0;
   1652 
   1653 	hlimit = options_get_number(global_options, "prompt-history-limit");
   1654 	if (hlimit > oldsize) {
   1655 		if (new == 0)
   1656 			return;
   1657 		newsize = oldsize + new;
   1658 	} else {
   1659 		newsize = hlimit;
   1660 		freecount = oldsize + new - newsize;
   1661 		if (freecount > oldsize)
   1662 			freecount = oldsize;
   1663 		if (freecount == 0)
   1664 			return;
   1665 		for (i = 0; i < freecount; i++)
   1666 			free(status_prompt_hlist[type][i]);
   1667 		movesize = (oldsize - freecount) *
   1668 		    sizeof *status_prompt_hlist[type];
   1669 		if (movesize > 0) {
   1670 			memmove(&status_prompt_hlist[type][0],
   1671 			    &status_prompt_hlist[type][freecount], movesize);
   1672 		}
   1673 	}
   1674 
   1675 	if (newsize == 0) {
   1676 		free(status_prompt_hlist[type]);
   1677 		status_prompt_hlist[type] = NULL;
   1678 	} else if (newsize != oldsize) {
   1679 		status_prompt_hlist[type] =
   1680 		    xreallocarray(status_prompt_hlist[type], newsize,
   1681 			sizeof *status_prompt_hlist[type]);
   1682 	}
   1683 
   1684 	if (new == 1 && newsize > 0)
   1685 		status_prompt_hlist[type][newsize - 1] = xstrdup(line);
   1686 	status_prompt_hsize[type] = newsize;
   1687 }
   1688 
   1689 /* Add to completion list. */
   1690 static void
   1691 status_prompt_add_list(char ***list, u_int *size, const char *s)
   1692 {
   1693 	u_int	i;
   1694 
   1695 	for (i = 0; i < *size; i++) {
   1696 		if (strcmp((*list)[i], s) == 0)
   1697 			return;
   1698 	}
   1699 	*list = xreallocarray(*list, (*size) + 1, sizeof **list);
   1700 	(*list)[(*size)++] = xstrdup(s);
   1701 }
   1702 
   1703 /* Build completion list. */
   1704 static char **
   1705 status_prompt_complete_list(u_int *size, const char *s, int at_start)
   1706 {
   1707 	char					**list = NULL, *tmp;
   1708 	const char				**layout, *value, *cp;
   1709 	const struct cmd_entry			**cmdent;
   1710 	const struct options_table_entry	 *oe;
   1711 	size_t					  slen = strlen(s), valuelen;
   1712 	struct options_entry			 *o;
   1713 	struct options_array_item		 *a;
   1714 	const char				 *layouts[] = {
   1715 		"even-horizontal", "even-vertical",
   1716 		"main-horizontal", "main-horizontal-mirrored",
   1717 		"main-vertical", "main-vertical-mirrored", "tiled", NULL
   1718 	};
   1719 
   1720 	*size = 0;
   1721 	for (cmdent = cmd_table; *cmdent != NULL; cmdent++) {
   1722 		if (strncmp((*cmdent)->name, s, slen) == 0)
   1723 			status_prompt_add_list(&list, size, (*cmdent)->name);
   1724 		if ((*cmdent)->alias != NULL &&
   1725 		    strncmp((*cmdent)->alias, s, slen) == 0)
   1726 			status_prompt_add_list(&list, size, (*cmdent)->alias);
   1727 	}
   1728 	o = options_get_only(global_options, "command-alias");
   1729 	if (o != NULL) {
   1730 		a = options_array_first(o);
   1731 		while (a != NULL) {
   1732 			value = options_array_item_value(a)->string;
   1733 			if ((cp = strchr(value, '=')) == NULL)
   1734 				goto next;
   1735 			valuelen = cp - value;
   1736 			if (slen > valuelen || strncmp(value, s, slen) != 0)
   1737 				goto next;
   1738 
   1739 			xasprintf(&tmp, "%.*s", (int)valuelen, value);
   1740 			status_prompt_add_list(&list, size, tmp);
   1741 			free(tmp);
   1742 
   1743 		next:
   1744 			a = options_array_next(a);
   1745 		}
   1746 	}
   1747 	if (at_start)
   1748 		return (list);
   1749 	for (oe = options_table; oe->name != NULL; oe++) {
   1750 		if (strncmp(oe->name, s, slen) == 0)
   1751 			status_prompt_add_list(&list, size, oe->name);
   1752 	}
   1753 	for (layout = layouts; *layout != NULL; layout++) {
   1754 		if (strncmp(*layout, s, slen) == 0)
   1755 			status_prompt_add_list(&list, size, *layout);
   1756 	}
   1757 	return (list);
   1758 }
   1759 
   1760 /* Find longest prefix. */
   1761 static char *
   1762 status_prompt_complete_prefix(char **list, u_int size)
   1763 {
   1764 	char	 *out;
   1765 	u_int	  i;
   1766 	size_t	  j;
   1767 
   1768 	if (list == NULL || size == 0)
   1769 		return (NULL);
   1770 	out = xstrdup(list[0]);
   1771 	for (i = 1; i < size; i++) {
   1772 		j = strlen(list[i]);
   1773 		if (j > strlen(out))
   1774 			j = strlen(out);
   1775 		for (; j > 0; j--) {
   1776 			if (out[j - 1] != list[i][j - 1])
   1777 				out[j - 1] = '\0';
   1778 		}
   1779 	}
   1780 	return (out);
   1781 }
   1782 
   1783 /* Complete word menu callback. */
   1784 static void
   1785 status_prompt_menu_callback(__unused struct menu *menu, u_int idx, key_code key,
   1786     void *data)
   1787 {
   1788 	struct status_prompt_menu	*spm = data;
   1789 	struct client			*c = spm->c;
   1790 	u_int				 i;
   1791 	char				*s;
   1792 
   1793 	if (key != KEYC_NONE) {
   1794 		idx += spm->start;
   1795 		if (spm->flag == '\0')
   1796 			s = xstrdup(spm->list[idx]);
   1797 		else
   1798 			xasprintf(&s, "-%c%s", spm->flag, spm->list[idx]);
   1799 		if (c->prompt_type == PROMPT_TYPE_WINDOW_TARGET) {
   1800 			free(c->prompt_buffer);
   1801 			c->prompt_buffer = utf8_fromcstr(s);
   1802 			c->prompt_index = utf8_strlen(c->prompt_buffer);
   1803 			c->flags |= CLIENT_REDRAWSTATUS;
   1804 		} else if (status_prompt_replace_complete(c, s))
   1805 			c->flags |= CLIENT_REDRAWSTATUS;
   1806 		free(s);
   1807 	}
   1808 
   1809 	for (i = 0; i < spm->size; i++)
   1810 		free(spm->list[i]);
   1811 	free(spm->list);
   1812 }
   1813 
   1814 /* Show complete word menu. */
   1815 static int
   1816 status_prompt_complete_list_menu(struct client *c, char **list, u_int size,
   1817     u_int offset, char flag)
   1818 {
   1819 	struct menu			*menu;
   1820 	struct menu_item		 item;
   1821 	struct status_prompt_menu	*spm;
   1822 	u_int				 lines = status_line_size(c), height, i;
   1823 	u_int				 py;
   1824 
   1825 	if (size <= 1)
   1826 		return (0);
   1827 	if (c->tty.sy - lines < 3)
   1828 		return (0);
   1829 
   1830 	spm = xmalloc(sizeof *spm);
   1831 	spm->c = c;
   1832 	spm->size = size;
   1833 	spm->list = list;
   1834 	spm->flag = flag;
   1835 
   1836 	height = c->tty.sy - lines - 2;
   1837 	if (height > 10)
   1838 		height = 10;
   1839 	if (height > size)
   1840 		height = size;
   1841 	spm->start = size - height;
   1842 
   1843 	menu = menu_create("");
   1844 	for (i = spm->start; i < size; i++) {
   1845 		item.name = list[i];
   1846 		item.key = '0' + (i - spm->start);
   1847 		item.command = NULL;
   1848 		menu_add_item(menu, &item, NULL, c, NULL);
   1849 	}
   1850 
   1851 	if (options_get_number(c->session->options, "status-position") == 0)
   1852 		py = lines;
   1853 	else
   1854 		py = c->tty.sy - 3 - height;
   1855 	offset += utf8_cstrwidth(c->prompt_string);
   1856 	if (offset > 2)
   1857 		offset -= 2;
   1858 	else
   1859 		offset = 0;
   1860 
   1861 	if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset, py, c,
   1862 	    BOX_LINES_DEFAULT, NULL, NULL, NULL, NULL,
   1863 	    status_prompt_menu_callback, spm) != 0) {
   1864 		menu_free(menu);
   1865 		free(spm);
   1866 		return (0);
   1867 	}
   1868 	return (1);
   1869 }
   1870 
   1871 /* Show complete word menu. */
   1872 static char *
   1873 status_prompt_complete_window_menu(struct client *c, struct session *s,
   1874     const char *word, u_int offset, char flag)
   1875 {
   1876 	struct menu			 *menu;
   1877 	struct menu_item		  item;
   1878 	struct status_prompt_menu	 *spm;
   1879 	struct winlink			 *wl;
   1880 	char				**list = NULL, *tmp;
   1881 	u_int				  lines = status_line_size(c), height;
   1882 	u_int				  py, size = 0;
   1883 
   1884 	if (c->tty.sy - lines < 3)
   1885 		return (NULL);
   1886 
   1887 	spm = xmalloc(sizeof *spm);
   1888 	spm->c = c;
   1889 	spm->flag = flag;
   1890 
   1891 	height = c->tty.sy - lines - 2;
   1892 	if (height > 10)
   1893 		height = 10;
   1894 	spm->start = 0;
   1895 
   1896 	menu = menu_create("");
   1897 	RB_FOREACH(wl, winlinks, &s->windows) {
   1898 		if (word != NULL && *word != '\0') {
   1899 			xasprintf(&tmp, "%d", wl->idx);
   1900 			if (strncmp(tmp, word, strlen(word)) != 0) {
   1901 				free(tmp);
   1902 				continue;
   1903 			}
   1904 			free(tmp);
   1905 		}
   1906 
   1907 		list = xreallocarray(list, size + 1, sizeof *list);
   1908 		if (c->prompt_type == PROMPT_TYPE_WINDOW_TARGET) {
   1909 			xasprintf(&tmp, "%d (%s)", wl->idx, wl->window->name);
   1910 			xasprintf(&list[size++], "%d", wl->idx);
   1911 		} else {
   1912 			xasprintf(&tmp, "%s:%d (%s)", s->name, wl->idx,
   1913 			    wl->window->name);
   1914 			xasprintf(&list[size++], "%s:%d", s->name, wl->idx);
   1915 		}
   1916 		item.name = tmp;
   1917 		item.key = '0' + size - 1;
   1918 		item.command = NULL;
   1919 		menu_add_item(menu, &item, NULL, c, NULL);
   1920 		free(tmp);
   1921 
   1922 		if (size == height)
   1923 			break;
   1924 	}
   1925 	if (size == 0) {
   1926 		menu_free(menu);
   1927 		free(spm);
   1928 		return (NULL);
   1929 	}
   1930 	if (size == 1) {
   1931 		menu_free(menu);
   1932 		if (flag != '\0') {
   1933 			xasprintf(&tmp, "-%c%s", flag, list[0]);
   1934 			free(list[0]);
   1935 		} else
   1936 			tmp = list[0];
   1937 		free(list);
   1938 		free(spm);
   1939 		return (tmp);
   1940 	}
   1941 	if (height > size)
   1942 		height = size;
   1943 
   1944 	spm->size = size;
   1945 	spm->list = list;
   1946 
   1947 	if (options_get_number(c->session->options, "status-position") == 0)
   1948 		py = lines;
   1949 	else
   1950 		py = c->tty.sy - 3 - height;
   1951 	offset += utf8_cstrwidth(c->prompt_string);
   1952 	if (offset > 2)
   1953 		offset -= 2;
   1954 	else
   1955 		offset = 0;
   1956 
   1957 	if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset, py, c,
   1958 	    BOX_LINES_DEFAULT, NULL, NULL, NULL, NULL,
   1959 	    status_prompt_menu_callback, spm) != 0) {
   1960 		menu_free(menu);
   1961 		free(spm);
   1962 		return (NULL);
   1963 	}
   1964 	return (NULL);
   1965 }
   1966 
   1967 /* Sort complete list. */
   1968 static int
   1969 status_prompt_complete_sort(const void *a, const void *b)
   1970 {
   1971 	const char **aa = __UNCONST(a), **bb = __UNCONST(b);
   1972 
   1973 	return (strcmp(*aa, *bb));
   1974 }
   1975 
   1976 /* Complete a session. */
   1977 static char *
   1978 status_prompt_complete_session(char ***list, u_int *size, const char *s,
   1979     char flag)
   1980 {
   1981 	struct session	*loop;
   1982 	char		*out, *tmp, n[11];
   1983 
   1984 	RB_FOREACH(loop, sessions, &sessions) {
   1985 		if (*s == '\0' || strncmp(loop->name, s, strlen(s)) == 0) {
   1986 			*list = xreallocarray(*list, (*size) + 2,
   1987 			    sizeof **list);
   1988 			xasprintf(&(*list)[(*size)++], "%s:", loop->name);
   1989 		} else if (*s == '$') {
   1990 			xsnprintf(n, sizeof n, "%u", loop->id);
   1991 			if (s[1] == '\0' ||
   1992 			    strncmp(n, s + 1, strlen(s) - 1) == 0) {
   1993 				*list = xreallocarray(*list, (*size) + 2,
   1994 				    sizeof **list);
   1995 				xasprintf(&(*list)[(*size)++], "$%s:", n);
   1996 			}
   1997 		}
   1998 	}
   1999 	out = status_prompt_complete_prefix(*list, *size);
   2000 	if (out != NULL && flag != '\0') {
   2001 		xasprintf(&tmp, "-%c%s", flag, out);
   2002 		free(out);
   2003 		out = tmp;
   2004 	}
   2005 	return (out);
   2006 }
   2007 
   2008 /* Complete word. */
   2009 static char *
   2010 status_prompt_complete(struct client *c, const char *word, u_int offset)
   2011 {
   2012 	struct session	 *session;
   2013 	const char	 *s, *colon;
   2014 	char		**list = NULL, *copy = NULL, *out = NULL;
   2015 	char		  flag = '\0';
   2016 	u_int		  size = 0, i;
   2017 
   2018 	if (*word == '\0' &&
   2019 	    c->prompt_type != PROMPT_TYPE_TARGET &&
   2020 	    c->prompt_type != PROMPT_TYPE_WINDOW_TARGET)
   2021 		return (NULL);
   2022 
   2023 	if (c->prompt_type != PROMPT_TYPE_TARGET &&
   2024 	    c->prompt_type != PROMPT_TYPE_WINDOW_TARGET &&
   2025 	    strncmp(word, "-t", 2) != 0 &&
   2026 	    strncmp(word, "-s", 2) != 0) {
   2027 		list = status_prompt_complete_list(&size, word, offset == 0);
   2028 		if (size == 0)
   2029 			out = NULL;
   2030 		else if (size == 1)
   2031 			xasprintf(&out, "%s ", list[0]);
   2032 		else
   2033 			out = status_prompt_complete_prefix(list, size);
   2034 		goto found;
   2035 	}
   2036 
   2037 	if (c->prompt_type == PROMPT_TYPE_TARGET ||
   2038 	    c->prompt_type == PROMPT_TYPE_WINDOW_TARGET) {
   2039 		s = word;
   2040 		flag = '\0';
   2041 	} else {
   2042 		s = word + 2;
   2043 		flag = word[1];
   2044 		offset += 2;
   2045 	}
   2046 
   2047 	/* If this is a window completion, open the window menu. */
   2048 	if (c->prompt_type == PROMPT_TYPE_WINDOW_TARGET) {
   2049 		out = status_prompt_complete_window_menu(c, c->session, s,
   2050 		    offset, '\0');
   2051 		goto found;
   2052 	}
   2053 	colon = strchr(s, ':');
   2054 
   2055 	/* If there is no colon, complete as a session. */
   2056 	if (colon == NULL) {
   2057 		out = status_prompt_complete_session(&list, &size, s, flag);
   2058 		goto found;
   2059 	}
   2060 
   2061 	/* If there is a colon but no period, find session and show a menu. */
   2062 	if (strchr(colon + 1, '.') == NULL) {
   2063 		if (*s == ':')
   2064 			session = c->session;
   2065 		else {
   2066 			copy = xstrdup(s);
   2067 			*strchr(copy, ':') = '\0';
   2068 			session = session_find(copy);
   2069 			free(copy);
   2070 			if (session == NULL)
   2071 				goto found;
   2072 		}
   2073 		out = status_prompt_complete_window_menu(c, session, colon + 1,
   2074 		    offset, flag);
   2075 		if (out == NULL)
   2076 			return (NULL);
   2077 	}
   2078 
   2079 found:
   2080 	if (size != 0) {
   2081 		qsort(list, size, sizeof *list, status_prompt_complete_sort);
   2082 		for (i = 0; i < size; i++)
   2083 			log_debug("complete %u: %s", i, list[i]);
   2084 	}
   2085 
   2086 	if (out != NULL && strcmp(word, out) == 0) {
   2087 		free(out);
   2088 		out = NULL;
   2089 	}
   2090 	if (out != NULL ||
   2091 	    !status_prompt_complete_list_menu(c, list, size, offset, flag)) {
   2092 		for (i = 0; i < size; i++)
   2093 			free(list[i]);
   2094 		free(list);
   2095 	}
   2096 	return (out);
   2097 }
   2098 
   2099 /* Return the type of the prompt as an enum. */
   2100 enum prompt_type
   2101 status_prompt_type(const char *type)
   2102 {
   2103 	u_int	i;
   2104 
   2105 	for (i = 0; i < PROMPT_NTYPES; i++) {
   2106 		if (strcmp(type, status_prompt_type_string(i)) == 0)
   2107 			return (i);
   2108 	}
   2109 	return (PROMPT_TYPE_INVALID);
   2110 }
   2111 
   2112 /* Accessor for prompt_type_strings. */
   2113 const char *
   2114 status_prompt_type_string(u_int type)
   2115 {
   2116 	if (type >= PROMPT_NTYPES)
   2117 		return ("invalid");
   2118 	return (prompt_type_strings[type]);
   2119 }
   2120