From 2ee0d851d92c00c13998c112618feb84df323ad2 Mon Sep 17 00:00:00 2001 From: Tiago Cunha Date: Tue, 31 Jan 2012 12:01:43 +0000 Subject: [PATCH] Sync OpenBSD patchset 1017: Give each window a unique id, like panes but prefixed with @. Based on work from George Nachman. --- cmd-list-windows.c | 4 +-- cmd.c | 73 ++++++++++++++++++++++++++++++++++------------ format.c | 1 + tmux.1 | 5 ++-- tmux.h | 3 ++ window.c | 32 ++++++++++++++++++-- 6 files changed, 94 insertions(+), 24 deletions(-) diff --git a/cmd-list-windows.c b/cmd-list-windows.c index ba187b12..e648fec3 100644 --- a/cmd-list-windows.c +++ b/cmd-list-windows.c @@ -87,14 +87,14 @@ cmd_list_windows_session( template = "#{window_index}: " "#{window_name} " "[#{window_width}x#{window_height}] " - "[layout #{window_layout}]" + "[layout #{window_layout}] #{window_id} " "#{?window_active, (active),}"; break; case 1: template = "#{session_name}:#{window_index}: " "#{window_name} " "[#{window_width}x#{window_height}] " - "[layout #{window_layout}]" + "[layout #{window_layout}] #{window_id} " "#{?window_active, (active),}"; break; } diff --git a/cmd.c b/cmd.c index 9fcdfde7..3c9aeeee 100644 --- a/cmd.c +++ b/cmd.c @@ -119,8 +119,10 @@ struct session *cmd_lookup_session(const char *, int *); struct winlink *cmd_lookup_window(struct session *, const char *, int *); int cmd_lookup_index(struct session *, const char *, int *); struct window_pane *cmd_lookup_paneid(const char *); -struct session *cmd_pane_session(struct cmd_ctx *, - struct window_pane *, struct winlink **); +struct winlink *cmd_lookup_winlink_windowid(struct session *, const char *); +struct window *cmd_lookup_windowid(const char *); +struct session *cmd_window_session(struct cmd_ctx *, + struct window *, struct winlink **); struct winlink *cmd_find_window_offset(const char *, struct session *, int *); int cmd_find_index_offset(const char *, struct session *, int *); struct window_pane *cmd_find_pane_offset(const char *, struct winlink *); @@ -586,6 +588,10 @@ cmd_lookup_window(struct session *s, const char *name, int *ambiguous) *ambiguous = 0; + /* Try as a window id. */ + if ((wl = cmd_lookup_winlink_windowid(s, name)) != NULL) + return (wl); + /* First see if this is a valid window index in this session. */ idx = strtonum(name, 0, INT_MAX, &errstr); if (errstr == NULL) { @@ -648,10 +654,7 @@ cmd_lookup_index(struct session *s, const char *name, int *ambiguous) return (-1); } -/* - * Lookup pane id. An initial % means a pane id. sp must already point to the - * current session. - */ +/* Lookup pane id. An initial % means a pane id. */ struct window_pane * cmd_lookup_paneid(const char *arg) { @@ -667,19 +670,50 @@ cmd_lookup_paneid(const char *arg) return (window_pane_find_by_id(paneid)); } -/* Find session and winlink for pane. */ +/* Lookup window id in a session. An initial @ means a window id. */ +struct winlink * +cmd_lookup_winlink_windowid(struct session *s, const char *arg) +{ + const char *errstr; + u_int windowid; + + if (*arg != '@') + return (NULL); + + windowid = strtonum(arg + 1, 0, UINT_MAX, &errstr); + if (errstr != NULL) + return (NULL); + return (winlink_find_by_window_id(&s->windows, windowid)); +} + +/* Lookup window id. An initial @ means a window id. */ +struct window * +cmd_lookup_windowid(const char *arg) +{ + const char *errstr; + u_int windowid; + + if (*arg != '@') + return (NULL); + + windowid = strtonum(arg + 1, 0, UINT_MAX, &errstr); + if (errstr != NULL) + return (NULL); + return (window_find_by_id(windowid)); +} + +/* Find session and winlink for window. */ struct session * -cmd_pane_session(struct cmd_ctx *ctx, struct window_pane *wp, - struct winlink **wlp) +cmd_window_session(struct cmd_ctx *ctx, struct window *w, struct winlink **wlp) { struct session *s; struct sessionslist ss; struct winlink *wl; - /* If this pane is in the current session, return that winlink. */ + /* If this window is in the current session, return that winlink. */ s = cmd_current_session(ctx, 0); if (s != NULL) { - wl = winlink_find_by_window(&s->windows, wp->window); + wl = winlink_find_by_window(&s->windows, w); if (wl != NULL) { if (wlp != NULL) *wlp = wl; @@ -687,16 +721,16 @@ cmd_pane_session(struct cmd_ctx *ctx, struct window_pane *wp, } } - /* Otherwise choose from all sessions with this pane. */ + /* Otherwise choose from all sessions with this window. */ ARRAY_INIT(&ss); RB_FOREACH(s, sessions, &sessions) { - if (winlink_find_by_window(&s->windows, wp->window) != NULL) + if (winlink_find_by_window(&s->windows, w) != NULL) ARRAY_ADD(&ss, s); } s = cmd_choose_session_list(&ss); ARRAY_FREE(&ss); if (wlp != NULL) - *wlp = winlink_find_by_window(&s->windows, wp->window); + *wlp = winlink_find_by_window(&s->windows, w); return (s); } @@ -706,6 +740,7 @@ cmd_find_session(struct cmd_ctx *ctx, const char *arg, int prefer_unattached) { struct session *s; struct window_pane *wp; + struct window *w; struct client *c; char *tmparg; size_t arglen; @@ -715,9 +750,11 @@ cmd_find_session(struct cmd_ctx *ctx, const char *arg, int prefer_unattached) if (arg == NULL) return (cmd_current_session(ctx, prefer_unattached)); - /* Lookup as pane id. */ + /* Lookup as pane id or window id. */ if ((wp = cmd_lookup_paneid(arg)) != NULL) - return (cmd_pane_session(ctx, wp, NULL)); + return (cmd_window_session(ctx, wp->window, NULL)); + if ((w = cmd_lookup_windowid(arg)) != NULL) + return (cmd_window_session(ctx, w, NULL)); /* Trim a single trailing colon if any. */ tmparg = xstrdup(arg); @@ -779,7 +816,7 @@ cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp) /* Lookup as pane id. */ if ((wp = cmd_lookup_paneid(arg)) != NULL) { - s = cmd_pane_session(ctx, wp, &wl); + s = cmd_window_session(ctx, wp->window, &wl); if (sp != NULL) *sp = s; return (wl); @@ -1080,7 +1117,7 @@ cmd_find_pane(struct cmd_ctx *ctx, /* Lookup as pane id. */ if ((*wpp = cmd_lookup_paneid(arg)) != NULL) { - s = cmd_pane_session(ctx, *wpp, &wl); + s = cmd_window_session(ctx, (*wpp)->window, &wl); if (sp != NULL) *sp = s; return (wl); diff --git a/format.c b/format.c index 713c9528..af675ce5 100644 --- a/format.c +++ b/format.c @@ -341,6 +341,7 @@ format_winlink(struct format_tree *ft, struct session *s, struct winlink *wl) layout = layout_dump(w); flags = window_printable_flags(s, wl); + format_add(ft, "window_id", "@%u", w->id); format_add(ft, "window_index", "%d", wl->idx); format_add(ft, "window_name", "%s", w->name); format_add(ft, "window_width", "%u", w->sx); diff --git a/tmux.1 b/tmux.1 index c84d5039..68b0cf60 100644 --- a/tmux.1 +++ b/tmux.1 @@ -389,8 +389,9 @@ follows the same rules as for .Ar target-session , and .Em window -is looked for in order: as a window index, for example mysession:1; as an exact -window name, such as mysession:mywindow; then as an +is looked for in order: as a window index, for example mysession:1; +as a window id, such as @1; +as an exact window name, such as mysession:mywindow; then as an .Xr fnmatch 3 pattern or the start of a window name, such as mysession:mywin* or mysession:mywin. diff --git a/tmux.h b/tmux.h index 069c53ef..270a0d95 100644 --- a/tmux.h +++ b/tmux.h @@ -844,6 +844,7 @@ RB_HEAD(window_pane_tree, window_pane); /* Window structure. */ struct window { + u_int id; char *name; struct event name_timer; struct timeval silence_timer; @@ -1901,6 +1902,7 @@ int window_pane_cmp(struct window_pane *, struct window_pane *); RB_PROTOTYPE(window_pane_tree, window_pane, tree_entry, window_pane_cmp); struct winlink *winlink_find_by_index(struct winlinks *, int); struct winlink *winlink_find_by_window(struct winlinks *, struct window *); +struct winlink *winlink_find_by_window_id(struct winlinks *, u_int); int winlink_next_index(struct winlinks *, int); u_int winlink_count(struct winlinks *); struct winlink *winlink_add(struct winlinks *, int); @@ -1915,6 +1917,7 @@ struct winlink *winlink_previous_by_number(struct winlink *, struct session *, void winlink_stack_push(struct winlink_stack *, struct winlink *); void winlink_stack_remove(struct winlink_stack *, struct winlink *); int window_index(struct window *, u_int *); +struct window *window_find_by_id(u_int); struct window *window_create1(u_int, u_int); struct window *window_create(const char *, const char *, const char *, const char *, struct environ *, struct termios *, diff --git a/window.c b/window.c index 111eb9c1..7c427f9e 100644 --- a/window.c +++ b/window.c @@ -55,7 +55,8 @@ struct windows windows; /* Global panes tree. */ struct window_pane_tree all_window_panes; -u_int next_window_pane; +u_int next_window_pane_id; +u_int next_window_id; void window_pane_read_callback(struct bufferevent *, void *); void window_pane_error_callback(struct bufferevent *, short, void *); @@ -101,6 +102,18 @@ winlink_find_by_index(struct winlinks *wwl, int idx) return (RB_FIND(winlinks, wwl, &wl)); } +struct winlink * +winlink_find_by_window_id(struct winlinks *wwl, u_int id) +{ + struct winlink *wl; + + RB_FOREACH(wl, winlinks, wwl) { + if (wl->window->id == id) + return (wl); + } + return NULL; +} + int winlink_next_index(struct winlinks *wwl, int idx) { @@ -245,6 +258,20 @@ window_index(struct window *s, u_int *i) return (-1); } +struct window * +window_find_by_id(u_int id) +{ + struct window *w; + u_int i; + + for (i = 0; i < ARRAY_LENGTH(&windows); i++) { + w = ARRAY_ITEM(&windows, i); + if (w->id == id) + return (w); + } + return NULL; +} + struct window * window_create1(u_int sx, u_int sy) { @@ -252,6 +279,7 @@ window_create1(u_int sx, u_int sy) u_int i; w = xcalloc(1, sizeof *w); + w->id = next_window_id++; w->name = NULL; w->flags = 0; @@ -568,7 +596,7 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit) wp = xcalloc(1, sizeof *wp); wp->window = w; - wp->id = next_window_pane++; + wp->id = next_window_pane_id++; RB_INSERT(window_pane_tree, &all_window_panes, wp); wp->cmd = NULL;