mirror of
https://github.com/tmux/tmux.git
synced 2025-01-07 16:28:48 +00:00
Allow choose commands to be used outside tmux, so long as at least one
client is attached.
This commit is contained in:
parent
8903c1f167
commit
180faf73af
@ -29,9 +29,6 @@
|
|||||||
|
|
||||||
enum cmd_retval cmd_choose_buffer_exec(struct cmd *, struct cmd_ctx *);
|
enum cmd_retval cmd_choose_buffer_exec(struct cmd *, struct cmd_ctx *);
|
||||||
|
|
||||||
void cmd_choose_buffer_callback(struct window_choose_data *);
|
|
||||||
void cmd_choose_buffer_free(struct window_choose_data *);
|
|
||||||
|
|
||||||
const struct cmd_entry cmd_choose_buffer_entry = {
|
const struct cmd_entry cmd_choose_buffer_entry = {
|
||||||
"choose-buffer", NULL,
|
"choose-buffer", NULL,
|
||||||
"F:t:", 0, 1,
|
"F:t:", 0, 1,
|
||||||
@ -46,6 +43,7 @@ enum cmd_retval
|
|||||||
cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
|
cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct args *args = self->args;
|
struct args *args = self->args;
|
||||||
|
struct client *c;
|
||||||
struct window_choose_data *cdata;
|
struct window_choose_data *cdata;
|
||||||
struct winlink *wl;
|
struct winlink *wl;
|
||||||
struct paste_buffer *pb;
|
struct paste_buffer *pb;
|
||||||
@ -53,8 +51,8 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
const char *template;
|
const char *template;
|
||||||
u_int idx;
|
u_int idx;
|
||||||
|
|
||||||
if (ctx->curclient == NULL) {
|
if ((c = cmd_current_client(ctx)) == NULL) {
|
||||||
ctx->error(ctx, "must be run interactively");
|
ctx->error(ctx, "no client available");
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,9 +75,8 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
|
|
||||||
idx = 0;
|
idx = 0;
|
||||||
while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) {
|
while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) {
|
||||||
cdata = window_choose_data_create(ctx);
|
cdata = window_choose_data_create(TREE_OTHER, c, c->session);
|
||||||
cdata->idx = idx - 1;
|
cdata->idx = idx - 1;
|
||||||
cdata->client->references++;
|
|
||||||
|
|
||||||
cdata->ft_template = xstrdup(template);
|
cdata->ft_template = xstrdup(template);
|
||||||
format_add(cdata->ft, "line", "%u", idx - 1);
|
format_add(cdata->ft, "line", "%u", idx - 1);
|
||||||
@ -93,34 +90,7 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
}
|
}
|
||||||
free(action);
|
free(action);
|
||||||
|
|
||||||
window_choose_ready(wl->window->active,
|
window_choose_ready(wl->window->active, 0, NULL);
|
||||||
0, cmd_choose_buffer_callback, cmd_choose_buffer_free);
|
|
||||||
|
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
cmd_choose_buffer_callback(struct window_choose_data *cdata)
|
|
||||||
{
|
|
||||||
if (cdata == NULL)
|
|
||||||
return;
|
|
||||||
if (cdata->client->flags & CLIENT_DEAD)
|
|
||||||
return;
|
|
||||||
|
|
||||||
window_choose_ctx(cdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
cmd_choose_buffer_free(struct window_choose_data *data)
|
|
||||||
{
|
|
||||||
struct window_choose_data *cdata = data;
|
|
||||||
|
|
||||||
if (cdata == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cdata->client->references--;
|
|
||||||
|
|
||||||
free(cdata->command);
|
|
||||||
free(cdata->ft_template);
|
|
||||||
free(cdata);
|
|
||||||
}
|
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
enum cmd_retval cmd_choose_client_exec(struct cmd *, struct cmd_ctx *);
|
enum cmd_retval cmd_choose_client_exec(struct cmd *, struct cmd_ctx *);
|
||||||
|
|
||||||
void cmd_choose_client_callback(struct window_choose_data *);
|
void cmd_choose_client_callback(struct window_choose_data *);
|
||||||
void cmd_choose_client_free(struct window_choose_data *);
|
|
||||||
|
|
||||||
const struct cmd_entry cmd_choose_client_entry = {
|
const struct cmd_entry cmd_choose_client_entry = {
|
||||||
"choose-client", NULL,
|
"choose-client", NULL,
|
||||||
@ -50,15 +49,16 @@ enum cmd_retval
|
|||||||
cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
|
cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct args *args = self->args;
|
struct args *args = self->args;
|
||||||
|
struct client *c;
|
||||||
|
struct client *c1;
|
||||||
struct window_choose_data *cdata;
|
struct window_choose_data *cdata;
|
||||||
struct winlink *wl;
|
struct winlink *wl;
|
||||||
struct client *c;
|
|
||||||
const char *template;
|
const char *template;
|
||||||
char *action;
|
char *action;
|
||||||
u_int i, idx, cur;
|
u_int i, idx, cur;
|
||||||
|
|
||||||
if (ctx->curclient == NULL) {
|
if ((c = cmd_current_client(ctx)) == NULL) {
|
||||||
ctx->error(ctx, "must be run interactively");
|
ctx->error(ctx, "no client available");
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,30 +78,29 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
|
|
||||||
cur = idx = 0;
|
cur = idx = 0;
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||||
c = ARRAY_ITEM(&clients, i);
|
c1 = ARRAY_ITEM(&clients, i);
|
||||||
if (c == NULL || c->session == NULL)
|
if (c1 == NULL || c1->session == NULL)
|
||||||
continue;
|
continue;
|
||||||
if (c == ctx->curclient)
|
if (c1 == ctx->curclient)
|
||||||
cur = idx;
|
cur = idx;
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
cdata = window_choose_data_create(ctx);
|
cdata = window_choose_data_create(TREE_OTHER, c, c->session);
|
||||||
cdata->idx = i;
|
cdata->idx = i;
|
||||||
cdata->client->references++;
|
|
||||||
|
|
||||||
cdata->ft_template = xstrdup(template);
|
cdata->ft_template = xstrdup(template);
|
||||||
format_add(cdata->ft, "line", "%u", i);
|
format_add(cdata->ft, "line", "%u", i);
|
||||||
format_session(cdata->ft, c->session);
|
format_session(cdata->ft, c1->session);
|
||||||
format_client(cdata->ft, c);
|
format_client(cdata->ft, c1);
|
||||||
|
|
||||||
cdata->command = cmd_template_replace(action, c->tty.path, 1);
|
cdata->command = cmd_template_replace(action, c1->tty.path, 1);
|
||||||
|
|
||||||
window_choose_add(wl->window->active, cdata);
|
window_choose_add(wl->window->active, cdata);
|
||||||
}
|
}
|
||||||
free(action);
|
free(action);
|
||||||
|
|
||||||
window_choose_ready(wl->window->active,
|
window_choose_ready(wl->window->active, cur,
|
||||||
cur, cmd_choose_client_callback, cmd_choose_client_free);
|
cmd_choose_client_callback);
|
||||||
|
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
@ -113,7 +112,7 @@ cmd_choose_client_callback(struct window_choose_data *cdata)
|
|||||||
|
|
||||||
if (cdata == NULL)
|
if (cdata == NULL)
|
||||||
return;
|
return;
|
||||||
if (cdata->client->flags & CLIENT_DEAD)
|
if (cdata->start_client->flags & CLIENT_DEAD)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cdata->idx > ARRAY_LENGTH(&clients) - 1)
|
if (cdata->idx > ARRAY_LENGTH(&clients) - 1)
|
||||||
@ -122,19 +121,5 @@ cmd_choose_client_callback(struct window_choose_data *cdata)
|
|||||||
if (c == NULL || c->session == NULL)
|
if (c == NULL || c->session == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
window_choose_ctx(cdata);
|
window_choose_data_run(cdata);
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
cmd_choose_client_free(struct window_choose_data *cdata)
|
|
||||||
{
|
|
||||||
if (cdata == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cdata->client->references--;
|
|
||||||
|
|
||||||
free(cdata->ft_template);
|
|
||||||
free(cdata->command);
|
|
||||||
format_free(cdata->ft);
|
|
||||||
free(cdata);
|
|
||||||
}
|
}
|
||||||
|
@ -33,9 +33,6 @@
|
|||||||
|
|
||||||
enum cmd_retval cmd_choose_list_exec(struct cmd *, struct cmd_ctx *);
|
enum cmd_retval cmd_choose_list_exec(struct cmd *, struct cmd_ctx *);
|
||||||
|
|
||||||
void cmd_choose_list_callback(struct window_choose_data *);
|
|
||||||
void cmd_choose_list_free(struct window_choose_data *);
|
|
||||||
|
|
||||||
const struct cmd_entry cmd_choose_list_entry = {
|
const struct cmd_entry cmd_choose_list_entry = {
|
||||||
"choose-list", NULL,
|
"choose-list", NULL,
|
||||||
"l:t:", 0, 1,
|
"l:t:", 0, 1,
|
||||||
@ -50,13 +47,14 @@ enum cmd_retval
|
|||||||
cmd_choose_list_exec(struct cmd *self, struct cmd_ctx *ctx)
|
cmd_choose_list_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct args *args = self->args;
|
struct args *args = self->args;
|
||||||
|
struct client *c;
|
||||||
struct winlink *wl;
|
struct winlink *wl;
|
||||||
const char *list1;
|
const char *list1;
|
||||||
char *template, *item, *copy, *list;
|
char *template, *item, *copy, *list;
|
||||||
u_int idx;
|
u_int idx;
|
||||||
|
|
||||||
if (ctx->curclient == NULL) {
|
if ((c = cmd_current_client(ctx)) == NULL) {
|
||||||
ctx->error(ctx, "must be run interactively");
|
ctx->error(ctx, "no client available");
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +78,7 @@ cmd_choose_list_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
{
|
{
|
||||||
if (*item == '\0') /* no empty entries */
|
if (*item == '\0') /* no empty entries */
|
||||||
continue;
|
continue;
|
||||||
window_choose_add_item(wl->window->active, ctx, wl, item,
|
window_choose_add_item(wl->window->active, c, wl, item,
|
||||||
template, idx);
|
template, idx);
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
@ -92,32 +90,9 @@ cmd_choose_list_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
window_choose_ready(wl->window->active, 0, cmd_choose_list_callback,
|
window_choose_ready(wl->window->active, 0, NULL);
|
||||||
cmd_choose_list_free);
|
|
||||||
|
|
||||||
free(template);
|
free(template);
|
||||||
|
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
cmd_choose_list_callback(struct window_choose_data *cdata)
|
|
||||||
{
|
|
||||||
if (cdata == NULL || (cdata->client->flags & CLIENT_DEAD))
|
|
||||||
return;
|
|
||||||
|
|
||||||
window_choose_ctx(cdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
cmd_choose_list_free(struct window_choose_data *cdata)
|
|
||||||
{
|
|
||||||
cdata->session->references--;
|
|
||||||
cdata->client->references--;
|
|
||||||
|
|
||||||
free(cdata->ft_template);
|
|
||||||
free(cdata->command);
|
|
||||||
format_free(cdata->ft);
|
|
||||||
free(cdata);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -34,9 +34,6 @@
|
|||||||
|
|
||||||
enum cmd_retval cmd_choose_tree_exec(struct cmd *, struct cmd_ctx *);
|
enum cmd_retval cmd_choose_tree_exec(struct cmd *, struct cmd_ctx *);
|
||||||
|
|
||||||
void cmd_choose_tree_callback(struct window_choose_data *);
|
|
||||||
void cmd_choose_tree_free(struct window_choose_data *);
|
|
||||||
|
|
||||||
const struct cmd_entry cmd_choose_tree_entry = {
|
const struct cmd_entry cmd_choose_tree_entry = {
|
||||||
"choose-tree", NULL,
|
"choose-tree", NULL,
|
||||||
"S:W:swub:c:t:", 0, 1,
|
"S:W:swub:c:t:", 0, 1,
|
||||||
@ -74,6 +71,7 @@ cmd_choose_tree_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
struct args *args = self->args;
|
struct args *args = self->args;
|
||||||
struct winlink *wl, *wm;
|
struct winlink *wl, *wm;
|
||||||
struct session *s, *s2;
|
struct session *s, *s2;
|
||||||
|
struct client *c;
|
||||||
struct window_choose_data *wcd = NULL;
|
struct window_choose_data *wcd = NULL;
|
||||||
const char *ses_template, *win_template;
|
const char *ses_template, *win_template;
|
||||||
char *final_win_action, *cur_win_template;
|
char *final_win_action, *cur_win_template;
|
||||||
@ -86,12 +84,13 @@ cmd_choose_tree_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
ses_template = win_template = NULL;
|
ses_template = win_template = NULL;
|
||||||
ses_action = win_action = NULL;
|
ses_action = win_action = NULL;
|
||||||
|
|
||||||
if (ctx->curclient == NULL) {
|
if ((c = cmd_current_client(ctx)) == NULL) {
|
||||||
ctx->error(ctx, "must be run interactively");
|
ctx->error(ctx, "no client available");
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
s = ctx->curclient->session;
|
if ((s = c->session) == NULL)
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
|
|
||||||
if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
|
if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
@ -175,7 +174,7 @@ cmd_choose_tree_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
wcd = window_choose_add_session(wl->window->active,
|
wcd = window_choose_add_session(wl->window->active,
|
||||||
ctx, s2, ses_template, (char *)ses_action, idx_ses);
|
c, s2, ses_template, (char *)ses_action, idx_ses);
|
||||||
|
|
||||||
/* If we're just choosing sessions, skip choosing windows. */
|
/* If we're just choosing sessions, skip choosing windows. */
|
||||||
if (sflag && !wflag) {
|
if (sflag && !wflag) {
|
||||||
@ -213,7 +212,7 @@ windows_only:
|
|||||||
cur_win_template = final_win_template_last;
|
cur_win_template = final_win_template_last;
|
||||||
|
|
||||||
window_choose_add_window(wl->window->active,
|
window_choose_add_window(wl->window->active,
|
||||||
ctx, s2, wm, cur_win_template,
|
c, s2, wm, cur_win_template,
|
||||||
final_win_action,
|
final_win_action,
|
||||||
(wflag && !sflag) ? win_ses : idx_ses);
|
(wflag && !sflag) ? win_ses : idx_ses);
|
||||||
|
|
||||||
@ -230,35 +229,10 @@ windows_only:
|
|||||||
free(final_win_template_middle);
|
free(final_win_template_middle);
|
||||||
free(final_win_template_last);
|
free(final_win_template_last);
|
||||||
|
|
||||||
window_choose_ready(wl->window->active, cur_win,
|
window_choose_ready(wl->window->active, cur_win, NULL);
|
||||||
cmd_choose_tree_callback, cmd_choose_tree_free);
|
|
||||||
|
|
||||||
if (args_has(args, 'u'))
|
if (args_has(args, 'u'))
|
||||||
window_choose_expand_all(wl->window->active);
|
window_choose_expand_all(wl->window->active);
|
||||||
|
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
cmd_choose_tree_callback(struct window_choose_data *cdata)
|
|
||||||
{
|
|
||||||
if (cdata == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (cdata->client->flags & CLIENT_DEAD)
|
|
||||||
return;
|
|
||||||
|
|
||||||
window_choose_ctx(cdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
cmd_choose_tree_free(struct window_choose_data *cdata)
|
|
||||||
{
|
|
||||||
cdata->session->references--;
|
|
||||||
cdata->client->references--;
|
|
||||||
|
|
||||||
free(cdata->ft_template);
|
|
||||||
free(cdata->command);
|
|
||||||
format_free(cdata->ft);
|
|
||||||
free(cdata);
|
|
||||||
}
|
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
enum cmd_retval cmd_find_window_exec(struct cmd *, struct cmd_ctx *);
|
enum cmd_retval cmd_find_window_exec(struct cmd *, struct cmd_ctx *);
|
||||||
|
|
||||||
void cmd_find_window_callback(struct window_choose_data *);
|
void cmd_find_window_callback(struct window_choose_data *);
|
||||||
void cmd_find_window_free(struct window_choose_data *);
|
|
||||||
|
|
||||||
/* Flags for determining matching behavior. */
|
/* Flags for determining matching behavior. */
|
||||||
#define CMD_FIND_WINDOW_BY_TITLE 0x1
|
#define CMD_FIND_WINDOW_BY_TITLE 0x1
|
||||||
@ -131,6 +130,7 @@ enum cmd_retval
|
|||||||
cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
|
cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct args *args = self->args;
|
struct args *args = self->args;
|
||||||
|
struct client *c;
|
||||||
struct window_choose_data *cdata;
|
struct window_choose_data *cdata;
|
||||||
struct session *s;
|
struct session *s;
|
||||||
struct winlink *wl, *wm;
|
struct winlink *wl, *wm;
|
||||||
@ -139,11 +139,11 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
const char *template;
|
const char *template;
|
||||||
u_int i, match_flags;
|
u_int i, match_flags;
|
||||||
|
|
||||||
if (ctx->curclient == NULL) {
|
if ((c = cmd_current_client(ctx)) == NULL) {
|
||||||
ctx->error(ctx, "must be run interactively");
|
ctx->error(ctx, "no client available");
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
s = ctx->curclient->session;
|
s = c->session;
|
||||||
|
|
||||||
if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
|
if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
@ -180,9 +180,8 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
for (i = 0; i < ARRAY_LENGTH(&find_list); i++) {
|
for (i = 0; i < ARRAY_LENGTH(&find_list); i++) {
|
||||||
wm = ARRAY_ITEM(&find_list, i).wl;
|
wm = ARRAY_ITEM(&find_list, i).wl;
|
||||||
|
|
||||||
cdata = window_choose_data_create(ctx);
|
cdata = window_choose_data_create(TREE_OTHER, c, c->session);
|
||||||
cdata->idx = wm->idx;
|
cdata->idx = wm->idx;
|
||||||
cdata->client->references++;
|
|
||||||
cdata->wl = wm;
|
cdata->wl = wm;
|
||||||
|
|
||||||
cdata->ft_template = xstrdup(template);
|
cdata->ft_template = xstrdup(template);
|
||||||
@ -198,8 +197,7 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
window_choose_add(wl->window->active, cdata);
|
window_choose_add(wl->window->active, cdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
window_choose_ready(wl->window->active,
|
window_choose_ready(wl->window->active, 0, cmd_find_window_callback);
|
||||||
0, cmd_find_window_callback, cmd_find_window_free);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
ARRAY_FREE(&find_list);
|
ARRAY_FREE(&find_list);
|
||||||
@ -215,7 +213,7 @@ cmd_find_window_callback(struct window_choose_data *cdata)
|
|||||||
if (cdata == NULL)
|
if (cdata == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
s = cdata->session;
|
s = cdata->start_session;
|
||||||
if (!session_alive(s))
|
if (!session_alive(s))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -228,16 +226,3 @@ cmd_find_window_callback(struct window_choose_data *cdata)
|
|||||||
recalculate_sizes();
|
recalculate_sizes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
cmd_find_window_free(struct window_choose_data *cdata)
|
|
||||||
{
|
|
||||||
if (cdata == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cdata->session->references--;
|
|
||||||
|
|
||||||
free(cdata->ft_template);
|
|
||||||
format_free(cdata->ft);
|
|
||||||
free(cdata);
|
|
||||||
}
|
|
||||||
|
21
tmux.1
21
tmux.1
@ -1074,8 +1074,7 @@ For the meaning of the
|
|||||||
flag, see the
|
flag, see the
|
||||||
.Sx FORMATS
|
.Sx FORMATS
|
||||||
section.
|
section.
|
||||||
This command works only from inside
|
This command works only if at least one client is attached.
|
||||||
.Nm .
|
|
||||||
.It Xo
|
.It Xo
|
||||||
.Ic choose-list
|
.Ic choose-list
|
||||||
.Op Fl l Ar items
|
.Op Fl l Ar items
|
||||||
@ -1101,8 +1100,7 @@ also accepts format specifiers.
|
|||||||
For the meaning of this see the
|
For the meaning of this see the
|
||||||
.Sx FORMATS
|
.Sx FORMATS
|
||||||
section.
|
section.
|
||||||
This command works only from inside
|
This command works only if at least one client is attached.
|
||||||
.Nm .
|
|
||||||
.It Xo
|
.It Xo
|
||||||
.Ic choose-session
|
.Ic choose-session
|
||||||
.Op Fl F Ar format
|
.Op Fl F Ar format
|
||||||
@ -1124,8 +1122,7 @@ For the meaning of the
|
|||||||
flag, see the
|
flag, see the
|
||||||
.Sx FORMATS
|
.Sx FORMATS
|
||||||
section.
|
section.
|
||||||
This command works only from inside
|
This command works only if at least one client is attached.
|
||||||
.Nm .
|
|
||||||
.It Xo
|
.It Xo
|
||||||
.Ic choose-tree
|
.Ic choose-tree
|
||||||
.Op Fl s
|
.Op Fl s
|
||||||
@ -1189,8 +1186,7 @@ and
|
|||||||
options, see the
|
options, see the
|
||||||
.Sx FORMATS
|
.Sx FORMATS
|
||||||
section.
|
section.
|
||||||
This command only works from inside
|
This command works only if at least one client is attached.
|
||||||
.Nm .
|
|
||||||
.It Xo
|
.It Xo
|
||||||
.Ic choose-window
|
.Ic choose-window
|
||||||
.Op Fl F Ar format
|
.Op Fl F Ar format
|
||||||
@ -1212,8 +1208,7 @@ For the meaning of the
|
|||||||
flag, see the
|
flag, see the
|
||||||
.Sx FORMATS
|
.Sx FORMATS
|
||||||
section.
|
section.
|
||||||
This command works only from inside
|
This command works only if at least one client is attached.
|
||||||
.Nm .
|
|
||||||
.It Ic display-panes Op Fl t Ar target-client
|
.It Ic display-panes Op Fl t Ar target-client
|
||||||
.D1 (alias: Ic displayp)
|
.D1 (alias: Ic displayp)
|
||||||
Display a visible indicator of each pane shown by
|
Display a visible indicator of each pane shown by
|
||||||
@ -1257,8 +1252,7 @@ For the meaning of the
|
|||||||
flag, see the
|
flag, see the
|
||||||
.Sx FORMATS
|
.Sx FORMATS
|
||||||
section.
|
section.
|
||||||
This command only works from inside
|
This command works only if at least one client is attached.
|
||||||
.Nm .
|
|
||||||
.It Xo Ic join-pane
|
.It Xo Ic join-pane
|
||||||
.Op Fl bdhv
|
.Op Fl bdhv
|
||||||
.Oo Fl l
|
.Oo Fl l
|
||||||
@ -3306,8 +3300,7 @@ For the meaning of the
|
|||||||
flag, see the
|
flag, see the
|
||||||
.Sx FORMATS
|
.Sx FORMATS
|
||||||
section.
|
section.
|
||||||
This command works only from inside
|
This command works only if at least one client is attached.
|
||||||
.Nm .
|
|
||||||
.It Ic clear-history Op Fl t Ar target-pane
|
.It Ic clear-history Op Fl t Ar target-pane
|
||||||
.D1 (alias: Ic clearhist )
|
.D1 (alias: Ic clearhist )
|
||||||
Remove and free the history for the specified pane.
|
Remove and free the history for the specified pane.
|
||||||
|
35
tmux.h
35
tmux.h
@ -883,18 +883,24 @@ struct window_mode {
|
|||||||
|
|
||||||
/* Structures for choose mode. */
|
/* Structures for choose mode. */
|
||||||
struct window_choose_data {
|
struct window_choose_data {
|
||||||
struct client *client;
|
struct client *start_client;
|
||||||
struct session *session; /* Session of current client. */
|
struct session *start_session;
|
||||||
struct session *tree_session; /* Session of items in tree. */
|
|
||||||
struct format_tree *ft;
|
|
||||||
struct winlink *wl;
|
|
||||||
char *ft_template;
|
|
||||||
char *command;
|
|
||||||
u_int idx;
|
u_int idx;
|
||||||
int type;
|
int type;
|
||||||
|
#define TREE_OTHER 0x0
|
||||||
#define TREE_WINDOW 0x1
|
#define TREE_WINDOW 0x1
|
||||||
#define TREE_SESSION 0x2
|
#define TREE_SESSION 0x2
|
||||||
|
|
||||||
|
struct session *tree_session; /* session of items in tree */
|
||||||
|
|
||||||
|
struct winlink *wl;
|
||||||
int pane_id;
|
int pane_id;
|
||||||
|
|
||||||
|
char *ft_template;
|
||||||
|
struct format_tree *ft;
|
||||||
|
|
||||||
|
char *command;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct window_choose_mode_item {
|
struct window_choose_mode_item {
|
||||||
@ -2196,18 +2202,19 @@ extern const struct window_mode window_choose_mode;
|
|||||||
void window_choose_add(struct window_pane *,
|
void window_choose_add(struct window_pane *,
|
||||||
struct window_choose_data *);
|
struct window_choose_data *);
|
||||||
void window_choose_ready(struct window_pane *,
|
void window_choose_ready(struct window_pane *,
|
||||||
u_int, void (*)(struct window_choose_data *),
|
u_int, void (*)(struct window_choose_data *));
|
||||||
void (*)(struct window_choose_data *));
|
struct window_choose_data *window_choose_data_create (int,
|
||||||
struct window_choose_data *window_choose_data_create(struct cmd_ctx *);
|
struct client *, struct session *);
|
||||||
void window_choose_ctx(struct window_choose_data *);
|
void window_choose_data_free(struct window_choose_data *);
|
||||||
|
void window_choose_data_run(struct window_choose_data *);
|
||||||
struct window_choose_data *window_choose_add_window(struct window_pane *,
|
struct window_choose_data *window_choose_add_window(struct window_pane *,
|
||||||
struct cmd_ctx *, struct session *, struct winlink *,
|
struct client *, struct session *, struct winlink *,
|
||||||
const char *, char *, u_int);
|
const char *, char *, u_int);
|
||||||
struct window_choose_data *window_choose_add_session(struct window_pane *,
|
struct window_choose_data *window_choose_add_session(struct window_pane *,
|
||||||
struct cmd_ctx *, struct session *, const char *,
|
struct client *, struct session *, const char *,
|
||||||
char *, u_int);
|
char *, u_int);
|
||||||
struct window_choose_data *window_choose_add_item(struct window_pane *,
|
struct window_choose_data *window_choose_add_item(struct window_pane *,
|
||||||
struct cmd_ctx *, struct winlink *, const char *,
|
struct client *, struct winlink *, const char *,
|
||||||
char *, u_int);
|
char *, u_int);
|
||||||
void window_choose_expand_all(struct window_pane *);
|
void window_choose_expand_all(struct window_pane *);
|
||||||
|
|
||||||
|
192
window-choose.c
192
window-choose.c
@ -31,6 +31,8 @@ void window_choose_key(struct window_pane *, struct session *, int);
|
|||||||
void window_choose_mouse(
|
void window_choose_mouse(
|
||||||
struct window_pane *, struct session *, struct mouse_event *);
|
struct window_pane *, struct session *, struct mouse_event *);
|
||||||
|
|
||||||
|
void window_choose_default_callback(struct window_choose_data *);
|
||||||
|
|
||||||
void window_choose_fire_callback(
|
void window_choose_fire_callback(
|
||||||
struct window_pane *, struct window_choose_data *);
|
struct window_pane *, struct window_choose_data *);
|
||||||
void window_choose_redraw_screen(struct window_pane *);
|
void window_choose_redraw_screen(struct window_pane *);
|
||||||
@ -101,8 +103,7 @@ window_choose_add(struct window_pane *wp, struct window_choose_data *wcd)
|
|||||||
|
|
||||||
void
|
void
|
||||||
window_choose_ready(struct window_pane *wp, u_int cur,
|
window_choose_ready(struct window_pane *wp, u_int cur,
|
||||||
void (*callbackfn)(struct window_choose_data *),
|
void (*callbackfn)(struct window_choose_data *))
|
||||||
void (*freefn)(struct window_choose_data *))
|
|
||||||
{
|
{
|
||||||
struct window_choose_mode_data *data = wp->modedata;
|
struct window_choose_mode_data *data = wp->modedata;
|
||||||
struct screen *s = &data->screen;
|
struct screen *s = &data->screen;
|
||||||
@ -112,7 +113,8 @@ window_choose_ready(struct window_pane *wp, u_int cur,
|
|||||||
data->top = ARRAY_LENGTH(&data->list) - screen_size_y(s);
|
data->top = ARRAY_LENGTH(&data->list) - screen_size_y(s);
|
||||||
|
|
||||||
data->callbackfn = callbackfn;
|
data->callbackfn = callbackfn;
|
||||||
data->freefn = freefn;
|
if (data->callbackfn == NULL)
|
||||||
|
data->callbackfn = window_choose_default_callback;
|
||||||
|
|
||||||
ARRAY_CONCAT(&data->old_list, &data->list);
|
ARRAY_CONCAT(&data->old_list, &data->list);
|
||||||
|
|
||||||
@ -154,24 +156,95 @@ window_choose_init(struct window_pane *wp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct window_choose_data *
|
struct window_choose_data *
|
||||||
window_choose_data_create(struct cmd_ctx *ctx)
|
window_choose_data_create(int type, struct client *c, struct session *s)
|
||||||
{
|
{
|
||||||
struct window_choose_data *wcd;
|
struct window_choose_data *wcd;
|
||||||
|
|
||||||
wcd = xmalloc(sizeof *wcd);
|
wcd = xmalloc(sizeof *wcd);
|
||||||
|
wcd->type = type;
|
||||||
|
|
||||||
wcd->ft = format_create();
|
wcd->ft = format_create();
|
||||||
wcd->ft_template = NULL;
|
wcd->ft_template = NULL;
|
||||||
|
|
||||||
wcd->command = NULL;
|
wcd->command = NULL;
|
||||||
|
|
||||||
wcd->wl = NULL;
|
wcd->wl = NULL;
|
||||||
wcd->tree_session = NULL;
|
wcd->pane_id = -1;
|
||||||
wcd->client = ctx->curclient;
|
|
||||||
wcd->session = ctx->curclient->session;
|
|
||||||
wcd->idx = -1;
|
wcd->idx = -1;
|
||||||
wcd->type = 0;
|
|
||||||
|
wcd->tree_session = NULL;
|
||||||
|
|
||||||
|
wcd->start_client = c;
|
||||||
|
wcd->start_client->references++;
|
||||||
|
wcd->start_session = s;
|
||||||
|
wcd->start_session->references++;
|
||||||
|
|
||||||
return (wcd);
|
return (wcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
window_choose_data_free(struct window_choose_data *wcd)
|
||||||
|
{
|
||||||
|
wcd->start_client->references--;
|
||||||
|
wcd->start_session->references--;
|
||||||
|
|
||||||
|
if (wcd->tree_session != NULL)
|
||||||
|
wcd->tree_session->references--;
|
||||||
|
|
||||||
|
free(wcd->ft_template);
|
||||||
|
format_free(wcd->ft);
|
||||||
|
|
||||||
|
free(wcd->command);
|
||||||
|
free(wcd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
window_choose_data_run(struct window_choose_data *cdata)
|
||||||
|
{
|
||||||
|
struct cmd_ctx ctx;
|
||||||
|
struct cmd_list *cmdlist;
|
||||||
|
char *cause;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The command template will have already been replaced. But if it's
|
||||||
|
* NULL, bail here.
|
||||||
|
*/
|
||||||
|
if (cdata->command == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (cmd_string_parse(cdata->command, &cmdlist, &cause) != 0) {
|
||||||
|
if (cause != NULL) {
|
||||||
|
*cause = toupper((u_char) *cause);
|
||||||
|
status_message_set(cdata->start_client, "%s", cause);
|
||||||
|
free(cause);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.msgdata = NULL;
|
||||||
|
ctx.curclient = cdata->start_client;
|
||||||
|
|
||||||
|
ctx.error = key_bindings_error;
|
||||||
|
ctx.print = key_bindings_print;
|
||||||
|
ctx.info = key_bindings_info;
|
||||||
|
|
||||||
|
ctx.cmdclient = NULL;
|
||||||
|
|
||||||
|
cmd_list_exec(cmdlist, &ctx);
|
||||||
|
cmd_list_free(cmdlist);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
window_choose_default_callback(struct window_choose_data *wcd)
|
||||||
|
{
|
||||||
|
if (wcd == NULL)
|
||||||
|
return;
|
||||||
|
if (wcd->start_client->flags & CLIENT_DEAD)
|
||||||
|
return;
|
||||||
|
|
||||||
|
window_choose_data_run(wcd);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_choose_free(struct window_pane *wp)
|
window_choose_free(struct window_pane *wp)
|
||||||
{
|
{
|
||||||
@ -181,8 +254,7 @@ window_choose_free(struct window_pane *wp)
|
|||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&data->old_list); i++) {
|
for (i = 0; i < ARRAY_LENGTH(&data->old_list); i++) {
|
||||||
item = &ARRAY_ITEM(&data->old_list, i);
|
item = &ARRAY_ITEM(&data->old_list, i);
|
||||||
if (data->freefn != NULL && item->wcd != NULL)
|
window_choose_data_free(item->wcd);
|
||||||
data->freefn(item->wcd);
|
|
||||||
free(item->name);
|
free(item->name);
|
||||||
}
|
}
|
||||||
ARRAY_FREE(&data->list);
|
ARRAY_FREE(&data->list);
|
||||||
@ -209,7 +281,7 @@ window_choose_resize(struct window_pane *wp, u_int sx, u_int sy)
|
|||||||
|
|
||||||
void
|
void
|
||||||
window_choose_fire_callback(
|
window_choose_fire_callback(
|
||||||
struct window_pane *wp, struct window_choose_data *wcd)
|
struct window_pane *wp, struct window_choose_data *wcd)
|
||||||
{
|
{
|
||||||
struct window_choose_mode_data *data = wp->modedata;
|
struct window_choose_mode_data *data = wp->modedata;
|
||||||
const struct window_mode *oldmode;
|
const struct window_mode *oldmode;
|
||||||
@ -299,7 +371,7 @@ window_choose_collapse_all(struct window_pane *wp)
|
|||||||
struct session *s, *chosen;
|
struct session *s, *chosen;
|
||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
chosen = ARRAY_ITEM(&data->list, data->selected).wcd->session;
|
chosen = ARRAY_ITEM(&data->list, data->selected).wcd->start_session;
|
||||||
|
|
||||||
RB_FOREACH(s, sessions, &sessions)
|
RB_FOREACH(s, sessions, &sessions)
|
||||||
window_choose_collapse(wp, s);
|
window_choose_collapse(wp, s);
|
||||||
@ -790,58 +862,23 @@ window_choose_scroll_down(struct window_pane *wp)
|
|||||||
screen_write_stop(&ctx);
|
screen_write_stop(&ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
window_choose_ctx(struct window_choose_data *cdata)
|
|
||||||
{
|
|
||||||
struct cmd_ctx ctx;
|
|
||||||
struct cmd_list *cmdlist;
|
|
||||||
char *cause;
|
|
||||||
|
|
||||||
/* The command template will have already been replaced. But if it's
|
|
||||||
* NULL, bail here.
|
|
||||||
*/
|
|
||||||
if (cdata->command == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (cmd_string_parse(cdata->command, &cmdlist, &cause) != 0) {
|
|
||||||
if (cause != NULL) {
|
|
||||||
*cause = toupper((u_char) *cause);
|
|
||||||
status_message_set(cdata->client, "%s", cause);
|
|
||||||
free(cause);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.msgdata = NULL;
|
|
||||||
ctx.curclient = cdata->client;
|
|
||||||
|
|
||||||
ctx.error = key_bindings_error;
|
|
||||||
ctx.print = key_bindings_print;
|
|
||||||
ctx.info = key_bindings_info;
|
|
||||||
|
|
||||||
ctx.cmdclient = NULL;
|
|
||||||
|
|
||||||
cmd_list_exec(cmdlist, &ctx);
|
|
||||||
cmd_list_free(cmdlist);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct window_choose_data *
|
struct window_choose_data *
|
||||||
window_choose_add_session(struct window_pane *wp, struct cmd_ctx *ctx,
|
window_choose_add_session(struct window_pane *wp, struct client *c,
|
||||||
struct session *s, const char *template, char *action, u_int idx)
|
struct session *s, const char *template, char *action, u_int idx)
|
||||||
{
|
{
|
||||||
struct window_choose_data *wcd;
|
struct window_choose_data *wcd;
|
||||||
|
|
||||||
wcd = window_choose_data_create(ctx);
|
wcd = window_choose_data_create(TREE_SESSION, c, c->session);
|
||||||
wcd->idx = s->idx;
|
wcd->idx = s->idx;
|
||||||
|
|
||||||
wcd->tree_session = s;
|
wcd->tree_session = s;
|
||||||
wcd->type = TREE_SESSION;
|
wcd->tree_session->references++;
|
||||||
wcd->command = cmd_template_replace(action, s->name, 1);
|
|
||||||
wcd->ft_template = xstrdup(template);
|
wcd->ft_template = xstrdup(template);
|
||||||
format_add(wcd->ft, "line", "%u", idx);
|
format_add(wcd->ft, "line", "%u", idx);
|
||||||
format_session(wcd->ft, s);
|
format_session(wcd->ft, s);
|
||||||
|
|
||||||
wcd->client->references++;
|
wcd->command = cmd_template_replace(action, s->name, 1);
|
||||||
wcd->session->references++;
|
|
||||||
|
|
||||||
window_choose_add(wp, wcd);
|
window_choose_add(wp, wcd);
|
||||||
|
|
||||||
@ -849,63 +886,60 @@ window_choose_add_session(struct window_pane *wp, struct cmd_ctx *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct window_choose_data *
|
struct window_choose_data *
|
||||||
window_choose_add_item(struct window_pane *wp, struct cmd_ctx *ctx,
|
window_choose_add_item(struct window_pane *wp, struct client *c,
|
||||||
struct winlink *wl, const char *template, char *action, u_int idx)
|
struct winlink *wl, const char *template, char *action, u_int idx)
|
||||||
{
|
{
|
||||||
struct window_choose_data *wcd;
|
struct window_choose_data *wcd;
|
||||||
char *action_data;
|
char *expanded;
|
||||||
|
|
||||||
wcd = window_choose_data_create(ctx);
|
wcd = window_choose_data_create(TREE_OTHER, c, c->session);
|
||||||
wcd->idx = wl->idx;
|
wcd->idx = wl->idx;
|
||||||
|
|
||||||
wcd->ft_template = xstrdup(template);
|
wcd->ft_template = xstrdup(template);
|
||||||
format_add(wcd->ft, "line", "%u", idx);
|
format_add(wcd->ft, "line", "%u", idx);
|
||||||
format_session(wcd->ft, wcd->session);
|
format_session(wcd->ft, wcd->start_session);
|
||||||
format_winlink(wcd->ft, wcd->session, wl);
|
format_winlink(wcd->ft, wcd->start_session, wl);
|
||||||
format_window_pane(wcd->ft, wl->window->active);
|
format_window_pane(wcd->ft, wl->window->active);
|
||||||
|
|
||||||
wcd->client->references++;
|
/*
|
||||||
wcd->session->references++;
|
* Interpolate action here, since the data we pass back is the expanded
|
||||||
|
* template itself.
|
||||||
|
*/
|
||||||
|
xasprintf(&expanded, "%s", format_expand(wcd->ft, wcd->ft_template));
|
||||||
|
wcd->command = cmd_template_replace(action, expanded, 1);
|
||||||
|
free(expanded);
|
||||||
|
|
||||||
window_choose_add(wp, wcd);
|
window_choose_add(wp, wcd);
|
||||||
|
|
||||||
/*
|
|
||||||
* Interpolate action_data here, since the data we pass back is the
|
|
||||||
* expanded template itself.
|
|
||||||
*/
|
|
||||||
xasprintf(&action_data, "%s", format_expand(wcd->ft, wcd->ft_template));
|
|
||||||
wcd->command = cmd_template_replace(action, action_data, 1);
|
|
||||||
free(action_data);
|
|
||||||
|
|
||||||
return (wcd);
|
return (wcd);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct window_choose_data *
|
struct window_choose_data *
|
||||||
window_choose_add_window(struct window_pane *wp, struct cmd_ctx *ctx,
|
window_choose_add_window(struct window_pane *wp, struct client *c,
|
||||||
struct session *s, struct winlink *wl, const char *template,
|
struct session *s, struct winlink *wl, const char *template,
|
||||||
char *action, u_int idx)
|
char *action, u_int idx)
|
||||||
{
|
{
|
||||||
struct window_choose_data *wcd;
|
struct window_choose_data *wcd;
|
||||||
char *action_data;
|
char *expanded;
|
||||||
|
|
||||||
wcd = window_choose_data_create(ctx);
|
|
||||||
|
|
||||||
xasprintf(&action_data, "%s:%d", s->name, wl->idx);
|
|
||||||
wcd->command = cmd_template_replace(action, action_data, 1);
|
|
||||||
free(action_data);
|
|
||||||
|
|
||||||
|
wcd = window_choose_data_create(TREE_WINDOW, c, c->session);
|
||||||
wcd->idx = wl->idx;
|
wcd->idx = wl->idx;
|
||||||
|
|
||||||
wcd->wl = wl;
|
wcd->wl = wl;
|
||||||
|
|
||||||
wcd->tree_session = s;
|
wcd->tree_session = s;
|
||||||
wcd->type = TREE_WINDOW;
|
wcd->tree_session->references++;
|
||||||
|
|
||||||
wcd->ft_template = xstrdup(template);
|
wcd->ft_template = xstrdup(template);
|
||||||
format_add(wcd->ft, "line", "%u", idx);
|
format_add(wcd->ft, "line", "%u", idx);
|
||||||
format_session(wcd->ft, s);
|
format_session(wcd->ft, s);
|
||||||
format_winlink(wcd->ft, s, wl);
|
format_winlink(wcd->ft, s, wl);
|
||||||
format_window_pane(wcd->ft, wl->window->active);
|
format_window_pane(wcd->ft, wl->window->active);
|
||||||
|
|
||||||
wcd->client->references++;
|
xasprintf(&expanded, "%s:%d", s->name, wl->idx);
|
||||||
wcd->session->references++;
|
wcd->command = cmd_template_replace(action, expanded, 1);
|
||||||
|
free(expanded);
|
||||||
|
|
||||||
window_choose_add(wp, wcd);
|
window_choose_add(wp, wcd);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user