summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@openbsd.org>2012-01-30 09:39:34 +0000
committerNicholas Marriott <nicm@openbsd.org>2012-01-30 09:39:34 +0000
commit0e59bc75fd90c09e3ea936fd58a5a13e69208253 (patch)
tree9e2779f478fb48c50ad633030dc7e385fafb0601
parent937173ff110601d7ff44254ec57b4389d5c24994 (diff)
Give each window a unique id, like panes but prefixed with @. Based on
work from George Nachman.
-rw-r--r--cmd-list-windows.c4
-rw-r--r--cmd.c73
-rw-r--r--format.c1
-rw-r--r--tmux.15
-rw-r--r--tmux.h3
-rw-r--r--window.c32
6 files changed, 94 insertions, 24 deletions
diff --git a/cmd-list-windows.c b/cmd-list-windows.c
index 0c3a9e64..a012dce2 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 f5d863d7..9656ae4f 100644
--- a/cmd.c
+++ b/cmd.c
@@ -120,8 +120,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 *);
@@ -587,6 +589,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) {
@@ -649,10 +655,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)
{
@@ -668,19 +671,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;
@@ -688,16 +722,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);
}
@@ -707,6 +741,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;
@@ -716,9 +751,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);
@@ -780,7 +817,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);
@@ -1081,7 +1118,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 3c8aea6e..c8502bdd 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 36e4719b..1d6d4c24 100644
--- a/tmux.1
+++ b/tmux.1
@@ -385,8 +385,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 73353b65..a52edf6f 100644
--- a/tmux.h
+++ b/tmux.h
@@ -848,6 +848,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;
@@ -1905,6 +1906,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);
@@ -1919,6 +1921,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 9a735dd6..1664999c 100644
--- a/window.c
+++ b/window.c
@@ -58,7 +58,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 *);
@@ -104,6 +105,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)
{
@@ -249,12 +262,27 @@ window_index(struct window *s, u_int *i)
}
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)
{
struct window *w;
u_int i;
w = xcalloc(1, sizeof *w);
+ w->id = next_window_id++;
w->name = NULL;
w->flags = 0;
@@ -571,7 +599,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;