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);
if (item != NULL)
cmdq_insert_after(item, new_item0);
new_item0 = cmdq_insert_after(item, new_item0);
else
cmdq_append(NULL, new_item0);
new_item0 = cmdq_append(NULL, new_item0);
cmd_list_free(pr->cmdlist);
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);
if (item != NULL)
cmdq_insert_after(item, new_item0);
new_item0 = cmdq_insert_after(item, new_item0);
else
cmdq_append(NULL, new_item0);
new_item0 = cmdq_append(NULL, new_item0);
cmd_list_free(pr->cmdlist);
if (new_item != NULL)

View File

@ -53,12 +53,16 @@ cmdq_get(struct client *c)
}
/* Append an item. */
void
struct cmdq_item *
cmdq_append(struct client *c, struct cmdq_item *item)
{
struct cmdq_list *queue = cmdq_get(c);
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 {
next = item->next;
item->next = NULL;
@ -73,16 +77,21 @@ cmdq_append(struct client *c, struct cmdq_item *item)
item = next;
} while (item != NULL);
return (TAILQ_LAST(queue, cmdq_list));
}
/* Insert an item. */
void
struct cmdq_item *
cmdq_insert_after(struct cmdq_item *after, struct cmdq_item *item)
{
struct client *c = after->client;
struct cmdq_list *queue = after->queue;
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 {
next = item->next;
item->next = after->next;
@ -100,6 +109,7 @@ cmdq_insert_after(struct cmdq_item *after, struct cmdq_item *item)
after = item;
item = next;
} while (item != NULL);
return (after);
}
/* 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);
cmdq_format(new_item, "hook", "%s", name);
if (item != NULL) {
cmdq_insert_after(item, new_item);
item = new_item;
} else
cmdq_append(NULL, new_item);
if (item != NULL)
item = cmdq_insert_after(item, new_item);
else
item = cmdq_append(NULL, new_item);
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
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,
sizeof *cdata->files);
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;
}
if (item != NULL)
cmdq_insert_after(item, new_item);
new_item = cmdq_insert_after(item, new_item);
else
cmdq_append(c, new_item);
new_item = cmdq_append(c, 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);
cmdq_format(new_item, "hook", "%s", ne->name);
notify_hook_formats(new_item, s, w, ne->pane);
cmdq_insert_after(item, new_item);
item = new_item;
item = cmdq_insert_after(item, new_item);
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)
struct cmdq_item *cmdq_get_callback1(const char *, cmdq_cb, void *);
struct cmdq_item *cmdq_get_error(const char *);
void cmdq_insert_after(struct cmdq_item *, struct cmdq_item *);
void cmdq_append(struct client *, struct cmdq_item *);
struct cmdq_item *cmdq_insert_after(struct cmdq_item *, struct cmdq_item *);
struct cmdq_item *cmdq_append(struct client *, struct cmdq_item *);
void cmdq_insert_hook(struct session *, struct cmdq_item *,
struct cmd_find_state *, const char *, ...);
void cmdq_continue(struct cmdq_item *);