diff --git a/CHANGES b/CHANGES index 78565e60..d088c958 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,7 @@ 18 January 2009 +* -a flag to next-window and previous-window to select the next or previous + window with activity or bell. Bound to M-n and M-p. * find-window command to search window names, titles and visible content (but not history) for a string. If only one is found, the window is selected otherwise a choice list is shown. This (as with the other choice commands) @@ -955,7 +957,7 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.218 2009-01-18 17:20:52 nicm Exp $ +$Id: CHANGES,v 1.219 2009-01-18 18:31:45 nicm Exp $ LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms diff --git a/cmd-next-window.c b/cmd-next-window.c index 6b44ec80..72c0f033 100644 --- a/cmd-next-window.c +++ b/cmd-next-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-next-window.c,v 1.13 2009-01-14 22:13:30 nicm Exp $ */ +/* $Id: cmd-next-window.c,v 1.14 2009-01-18 18:31:45 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -24,13 +24,14 @@ * Move to next window. */ +void cmd_next_window_init(struct cmd *, int); void cmd_next_window_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_next_window_entry = { "next-window", "next", CMD_TARGET_SESSION_USAGE, - CMD_CANREPEAT, - cmd_target_init, + CMD_CANREPEAT|CMD_AFLAG, + cmd_next_window_init, cmd_target_parse, cmd_next_window_exec, cmd_target_send, @@ -39,16 +40,33 @@ const struct cmd_entry cmd_next_window_entry = { cmd_target_print }; +void +cmd_next_window_init(struct cmd *self, int key) +{ + struct cmd_target_data *data; + + cmd_target_init(self, key); + data = self->data; + + if (key == KEYC_ADDESC('n')) + data->flags |= CMD_AFLAG; +} + void cmd_next_window_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_target_data *data = self->data; struct session *s; + int activity; if ((s = cmd_find_session(ctx, data->target)) == NULL) return; - if (session_next(s) == 0) + activity = 0; + if (data->flags & CMD_AFLAG) + activity = 1; + + if (session_next(s, activity) == 0) server_redraw_session(s); else ctx->error(ctx, "no next window"); diff --git a/cmd-previous-window.c b/cmd-previous-window.c index 67b94b11..1c4148df 100644 --- a/cmd-previous-window.c +++ b/cmd-previous-window.c @@ -1,4 +1,4 @@ -/* $Id: cmd-previous-window.c,v 1.13 2009-01-14 22:13:30 nicm Exp $ */ +/* $Id: cmd-previous-window.c,v 1.14 2009-01-18 18:31:45 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -24,13 +24,14 @@ * Move to previous window. */ +void cmd_previous_window_init(struct cmd *, int); void cmd_previous_window_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_previous_window_entry = { "previous-window", "prev", CMD_TARGET_SESSION_USAGE, - CMD_CANREPEAT, - cmd_target_init, + CMD_CANREPEAT|CMD_AFLAG, + cmd_previous_window_init, cmd_target_parse, cmd_previous_window_exec, cmd_target_send, @@ -39,16 +40,33 @@ const struct cmd_entry cmd_previous_window_entry = { cmd_target_print }; +void +cmd_previous_window_init(struct cmd *self, int key) +{ + struct cmd_target_data *data; + + cmd_target_init(self, key); + data = self->data; + + if (key == KEYC_ADDESC('p')) + data->flags |= CMD_AFLAG; +} + void cmd_previous_window_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_target_data *data = self->data; struct session *s; + int activity; if ((s = cmd_find_session(ctx, data->target)) == NULL) return; - if (session_previous(s) == 0) + activity = 0; + if (data->flags & CMD_AFLAG) + activity = 1; + + if (session_previous(s, activity) == 0) server_redraw_session(s); else ctx->error(ctx, "no previous window"); diff --git a/key-bindings.c b/key-bindings.c index 13aa54f8..5aae88fb 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -1,4 +1,4 @@ -/* $Id: key-bindings.c,v 1.56 2009-01-18 17:20:52 nicm Exp $ */ +/* $Id: key-bindings.c,v 1.57 2009-01-18 18:31:45 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -111,6 +111,8 @@ key_bindings_init(void) { 'w', &cmd_choose_window_entry }, { 'x', &cmd_kill_pane_entry, }, { '\032', &cmd_suspend_client_entry }, + { KEYC_ADDESC('n'), &cmd_next_window_entry }, + { KEYC_ADDESC('p'), &cmd_previous_window_entry }, { KEYC_UP, &cmd_up_pane_entry }, { KEYC_DOWN, &cmd_down_pane_entry }, { KEYC_ADDESC(KEYC_UP), &cmd_resize_pane_up_entry }, diff --git a/session.c b/session.c index 72dfec75..9d381f38 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $Id: session.c,v 1.50 2009-01-12 18:22:47 nicm Exp $ */ +/* $Id: session.c,v 1.51 2009-01-18 18:31:45 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -28,6 +28,9 @@ /* Global session list. */ struct sessions sessions; +struct winlink *session_next_activity(struct session *, struct winlink *); +struct winlink *session_previous_activity(struct session *, struct winlink *); + void session_alert_cancel(struct session *s, struct winlink *wl) { @@ -225,8 +228,9 @@ session_attach(struct session *s, struct window *w, int idx) int session_detach(struct session *s, struct winlink *wl) { - if (s->curw == wl && session_last(s) != 0 && session_previous(s) != 0) - session_next(s); + if (s->curw == wl && + session_last(s) != 0 && session_previous(s, 0) != 0) + session_next(s, 0); session_alert_cancel(s, wl); winlink_stack_remove(&s->lastw, wl); @@ -251,9 +255,22 @@ session_has(struct session *s, struct window *w) return (0); } +struct winlink * +session_next_activity(struct session *s, struct winlink *wl) +{ + while (wl != NULL) { + if (session_alert_has(s, wl, WINDOW_BELL)) + break; + if (session_alert_has(s, wl, WINDOW_ACTIVITY)) + break; + wl = winlink_next(&s->windows, wl); + } + return (wl); +} + /* Move session to next window. */ int -session_next(struct session *s) +session_next(struct session *s, int activity) { struct winlink *wl; @@ -261,8 +278,13 @@ session_next(struct session *s) return (-1); wl = winlink_next(&s->windows, s->curw); - if (wl == NULL) + if (activity) + wl = session_next_activity(s, wl); + if (wl == NULL) { wl = RB_MIN(winlinks, &s->windows); + if (activity && ((wl = session_next_activity(s, wl)) == NULL)) + return (-1); + } if (wl == s->curw) return (1); winlink_stack_remove(&s->lastw, wl); @@ -272,9 +294,22 @@ session_next(struct session *s) return (0); } +struct winlink * +session_previous_activity(struct session *s, struct winlink *wl) +{ + while (wl != NULL) { + if (session_alert_has(s, wl, WINDOW_BELL)) + break; + if (session_alert_has(s, wl, WINDOW_ACTIVITY)) + break; + wl = winlink_previous(&s->windows, wl); + } + return (wl); +} + /* Move session to previous window. */ int -session_previous(struct session *s) +session_previous(struct session *s, int activity) { struct winlink *wl; @@ -282,8 +317,13 @@ session_previous(struct session *s) return (-1); wl = winlink_previous(&s->windows, s->curw); - if (wl == NULL) + if (activity) + wl = session_previous_activity(s, wl); + if (wl == NULL) { wl = RB_MAX(winlinks, &s->windows); + if (activity && (wl = session_previous_activity(s, wl)) == NULL) + return (-1); + } if (wl == s->curw) return (1); winlink_stack_remove(&s->lastw, wl); diff --git a/tmux.h b/tmux.h index 9f7c0865..556be9bd 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.239 2009-01-18 17:20:52 nicm Exp $ */ +/* $Id: tmux.h,v 1.240 2009-01-18 18:31:45 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -727,7 +727,7 @@ struct tty { #define TTY_FREEZE 0x2 #define TTY_ESCAPE 0x4 #define TTY_UTF8 0x8 - int flags; + int flags; int term_flags; @@ -1479,8 +1479,8 @@ struct winlink *session_new(struct session *, struct winlink *session_attach(struct session *, struct window *, int); int session_detach(struct session *, struct winlink *); int session_has(struct session *, struct window *); -int session_next(struct session *); -int session_previous(struct session *); +int session_next(struct session *, int); +int session_previous(struct session *, int); int session_select(struct session *, int); int session_last(struct session *); diff --git a/window.c b/window.c index 64082b23..9289a727 100644 --- a/window.c +++ b/window.c @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.58 2009-01-14 19:29:32 nicm Exp $ */ +/* $Id: window.c,v 1.59 2009-01-18 18:31:45 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -160,22 +160,7 @@ winlink_next(unused struct winlinks *wwl, struct winlink *wl) struct winlink * winlink_previous(unused struct winlinks *wwl, struct winlink *wl) { -#ifdef RB_PREV return (RB_PREV(winlinks, wwl, wl)); -#else - struct winlink *wk; - int idx = wl->idx; - - wk = NULL; - wl = RB_MIN(winlinks, wwl); - while (wl != NULL && wl->idx < idx) { - wk = wl; - wl = RB_NEXT(winlinks, wwl, wl); - } - if (wl == NULL) - return (NULL); - return (wk); -#endif } void