When adding a list with multiple commands to the queue, the next item to

insert after needs to be the last one added, not the first. Reported by
Jason Kim in GitHub issue 2023.
This commit is contained in:
nicm 2019-12-19 09:22:33 +00:00
parent ef54a08080
commit 1764f66b7d
6 changed files with 26 additions and 18 deletions

8
cfg.c
View File

@ -185,9 +185,9 @@ load_cfg(const char *path, struct client *c, struct cmdq_item *item, int flags,
new_item0 = cmdq_get_command(pr->cmdlist, NULL, NULL, 0); new_item0 = cmdq_get_command(pr->cmdlist, NULL, NULL, 0);
if (item != NULL) if (item != NULL)
cmdq_insert_after(item, new_item0); new_item0 = cmdq_insert_after(item, new_item0);
else else
cmdq_append(NULL, new_item0); new_item0 = cmdq_append(NULL, new_item0);
cmd_list_free(pr->cmdlist); cmd_list_free(pr->cmdlist);
if (new_item != NULL) if (new_item != NULL)
@ -231,9 +231,9 @@ load_cfg_from_buffer(const void *buf, size_t len, const char *path,
new_item0 = cmdq_get_command(pr->cmdlist, NULL, NULL, 0); new_item0 = cmdq_get_command(pr->cmdlist, NULL, NULL, 0);
if (item != NULL) if (item != NULL)
cmdq_insert_after(item, new_item0); new_item0 = cmdq_insert_after(item, new_item0);
else else
cmdq_append(NULL, new_item0); new_item0 = cmdq_append(NULL, new_item0);
cmd_list_free(pr->cmdlist); cmd_list_free(pr->cmdlist);
if (new_item != NULL) if (new_item != NULL)

View File

@ -53,12 +53,16 @@ cmdq_get(struct client *c)
} }
/* Append an item. */ /* Append an item. */
void struct cmdq_item *
cmdq_append(struct client *c, struct cmdq_item *item) cmdq_append(struct client *c, struct cmdq_item *item)
{ {
struct cmdq_list *queue = cmdq_get(c); struct cmdq_list *queue = cmdq_get(c);
struct cmdq_item *next; struct cmdq_item *next;
TAILQ_FOREACH(next, queue, entry) {
log_debug("%s %s: queue %s (%u)", __func__, cmdq_name(c),
next->name, next->group);
}
do { do {
next = item->next; next = item->next;
item->next = NULL; item->next = NULL;
@ -73,16 +77,21 @@ cmdq_append(struct client *c, struct cmdq_item *item)
item = next; item = next;
} while (item != NULL); } while (item != NULL);
return (TAILQ_LAST(queue, cmdq_list));
} }
/* Insert an item. */ /* Insert an item. */
void struct cmdq_item *
cmdq_insert_after(struct cmdq_item *after, struct cmdq_item *item) cmdq_insert_after(struct cmdq_item *after, struct cmdq_item *item)
{ {
struct client *c = after->client; struct client *c = after->client;
struct cmdq_list *queue = after->queue; struct cmdq_list *queue = after->queue;
struct cmdq_item *next; struct cmdq_item *next;
TAILQ_FOREACH(next, queue, entry) {
log_debug("%s %s: queue %s (%u)", __func__, cmdq_name(c),
next->name, next->group);
}
do { do {
next = item->next; next = item->next;
item->next = after->next; item->next = after->next;
@ -100,6 +109,7 @@ cmdq_insert_after(struct cmdq_item *after, struct cmdq_item *item)
after = item; after = item;
item = next; item = next;
} while (item != NULL); } while (item != NULL);
return (after);
} }
/* Insert a hook. */ /* Insert a hook. */
@ -143,11 +153,10 @@ cmdq_insert_hook(struct session *s, struct cmdq_item *item,
new_item = cmdq_get_command(cmdlist, fs, NULL, CMDQ_NOHOOKS); new_item = cmdq_get_command(cmdlist, fs, NULL, CMDQ_NOHOOKS);
cmdq_format(new_item, "hook", "%s", name); cmdq_format(new_item, "hook", "%s", name);
if (item != NULL) { if (item != NULL)
cmdq_insert_after(item, new_item); item = cmdq_insert_after(item, new_item);
item = new_item; else
} else item = cmdq_append(NULL, new_item);
cmdq_append(NULL, new_item);
a = options_array_next(a); a = options_array_next(a);
} }

View File

@ -114,6 +114,7 @@ cmd_source_file_done(struct client *c, const char *path, int error,
static void static void
cmd_source_file_add(struct cmd_source_file_data *cdata, const char *path) cmd_source_file_add(struct cmd_source_file_data *cdata, const char *path)
{ {
log_debug("%s: %s", __func__, path);
cdata->files = xreallocarray(cdata->files, cdata->nfiles + 1, cdata->files = xreallocarray(cdata->files, cdata->nfiles + 1,
sizeof *cdata->files); sizeof *cdata->files);
cdata->files[cdata->nfiles++] = xstrdup(path); cdata->files[cdata->nfiles++] = xstrdup(path);

View File

@ -520,8 +520,8 @@ key_bindings_dispatch(struct key_binding *bd, struct cmdq_item *item,
new_item->shared->flags |= CMDQ_SHARED_REPEAT; new_item->shared->flags |= CMDQ_SHARED_REPEAT;
} }
if (item != NULL) if (item != NULL)
cmdq_insert_after(item, new_item); new_item = cmdq_insert_after(item, new_item);
else else
cmdq_append(c, new_item); new_item = cmdq_append(c, new_item);
return (new_item); return (new_item);
} }

View File

@ -90,9 +90,7 @@ notify_insert_hook(struct cmdq_item *item, struct notify_entry *ne)
new_item = cmdq_get_command(cmdlist, &fs, NULL, CMDQ_NOHOOKS); new_item = cmdq_get_command(cmdlist, &fs, NULL, CMDQ_NOHOOKS);
cmdq_format(new_item, "hook", "%s", ne->name); cmdq_format(new_item, "hook", "%s", ne->name);
notify_hook_formats(new_item, s, w, ne->pane); notify_hook_formats(new_item, s, w, ne->pane);
item = cmdq_insert_after(item, new_item);
cmdq_insert_after(item, new_item);
item = new_item;
a = options_array_next(a); a = options_array_next(a);
} }

4
tmux.h
View File

@ -2134,8 +2134,8 @@ struct cmdq_item *cmdq_get_command(struct cmd_list *, struct cmd_find_state *,
#define cmdq_get_callback(cb, data) cmdq_get_callback1(#cb, cb, data) #define cmdq_get_callback(cb, data) cmdq_get_callback1(#cb, cb, data)
struct cmdq_item *cmdq_get_callback1(const char *, cmdq_cb, void *); struct cmdq_item *cmdq_get_callback1(const char *, cmdq_cb, void *);
struct cmdq_item *cmdq_get_error(const char *); struct cmdq_item *cmdq_get_error(const char *);
void cmdq_insert_after(struct cmdq_item *, struct cmdq_item *); struct cmdq_item *cmdq_insert_after(struct cmdq_item *, struct cmdq_item *);
void cmdq_append(struct client *, struct cmdq_item *); struct cmdq_item *cmdq_append(struct client *, struct cmdq_item *);
void cmdq_insert_hook(struct session *, struct cmdq_item *, void cmdq_insert_hook(struct session *, struct cmdq_item *,
struct cmd_find_state *, const char *, ...); struct cmd_find_state *, const char *, ...);
void cmdq_continue(struct cmdq_item *); void cmdq_continue(struct cmdq_item *);