=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/cmd-select-window.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- src/usr.bin/tmux/cmd-select-window.c 2011/01/04 00:42:47 1.5 +++ src/usr.bin/tmux/cmd-select-window.c 2011/01/04 02:03:41 1.6 @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-select-window.c,v 1.5 2011/01/04 00:42:47 nicm Exp $ */ +/* $OpenBSD: cmd-select-window.c,v 1.6 2011/01/04 02:03:41 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -31,23 +31,56 @@ const struct cmd_entry cmd_select_window_entry = { "select-window", "selectw", - "t:", 0, 0, - CMD_TARGET_WINDOW_USAGE, + "lnpt:", 0, 0, + "[-lnp] " CMD_TARGET_WINDOW_USAGE, 0, cmd_select_window_key_binding, NULL, cmd_select_window_exec }; +const struct cmd_entry cmd_next_window_entry = { + "next-window", "next", + "at:", 0, 0, + "[-a] " CMD_TARGET_SESSION_USAGE, + 0, + cmd_select_window_key_binding, + NULL, + cmd_select_window_exec +}; + +const struct cmd_entry cmd_previous_window_entry = { + "previous-window", "prev", + "at:", 0, 0, + "[-a] " CMD_TARGET_SESSION_USAGE, + 0, + cmd_select_window_key_binding, + NULL, + cmd_select_window_exec +}; + +const struct cmd_entry cmd_last_window_entry = { + "last-window", "last", + "t:", 0, 0, + CMD_TARGET_SESSION_USAGE, + 0, + NULL, + NULL, + cmd_select_window_exec +}; + void cmd_select_window_key_binding(struct cmd *self, int key) { char tmp[16]; - xsnprintf(tmp, sizeof tmp, ":%d", key - '0'); - self->args = args_create(0); - args_set(self->args, 't', tmp); + if (key >= '0' && key <= '9') { + xsnprintf(tmp, sizeof tmp, ":%d", key - '0'); + args_set(self->args, 't', tmp); + } + if (key == ('n' | KEYC_ESCAPE) || key == ('p' | KEYC_ESCAPE)) + args_set(self->args, 'a', NULL); } int @@ -56,12 +89,50 @@ struct args *args = self->args; struct winlink *wl; struct session *s; + int next, previous, last, activity; - if ((wl = cmd_find_window(ctx, args_get(args, 't'), &s)) == NULL) - return (-1); + next = self->entry == &cmd_next_window_entry; + if (args_has(self->args, 'n')) + next = 1; + previous = self->entry == &cmd_previous_window_entry; + if (args_has(self->args, 'p')) + previous = 1; + last = self->entry == &cmd_last_window_entry; + if (args_has(self->args, 'l')) + last = 1; - if (session_select(s, wl->idx) == 0) + if (next || previous || last) { + s = cmd_find_session(ctx, args_get(args, 't')); + if (s == NULL) + return (-1); + + activity = args_has(self->args, 'a'); + if (next) { + if (session_next(s, activity) != 0) { + ctx->error(ctx, "no next window"); + return (-1); + } + } else if (previous) { + if (session_previous(s, activity) != 0) { + ctx->error(ctx, "no previous window"); + return (-1); + } + } else { + if (session_last(s) != 0) { + ctx->error(ctx, "no last window"); + return (-1); + } + } + server_redraw_session(s); + } else { + wl = cmd_find_window(ctx, args_get(args, 't'), &s); + if (wl == NULL) + return (-1); + + if (session_select(s, wl->idx) == 0) + server_redraw_session(s); + } recalculate_sizes(); return (0);