Drop support for popups where the content is provided directly to tmux

(which does not have many practical uses) and only support running a
program in the popup. display-popup is now simpler and can accept
multiple arguments to avoid escaping problems (like the other commands).
This commit is contained in:
nicm
2021-03-02 10:56:45 +00:00
parent de3a898e8a
commit c44750792a
10 changed files with 97 additions and 310 deletions

View File

@@ -18,6 +18,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <paths.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -50,10 +51,10 @@ const struct cmd_entry cmd_display_popup_entry = {
.name = "display-popup", .name = "display-popup",
.alias = "popup", .alias = "popup",
.args = { "CEKc:d:h:R:t:w:x:y:", 0, -1 }, .args = { "Cc:d:Eh:t:w:x:y:", 0, -1 },
.usage = "[-CEK] [-c target-client] [-d start-directory] [-h height] " .usage = "[-CE] [-c target-client] [-d start-directory] [-h height] "
"[-R shell-command] " CMD_TARGET_PANE_USAGE " [-w width] " CMD_TARGET_PANE_USAGE " [-w width] "
"[-x position] [-y position] [command line ...]", "[-x position] [-y position] [command]",
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },
@@ -325,13 +326,14 @@ cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = cmd_get_args(self); struct args *args = cmd_get_args(self);
struct cmd_find_state *target = cmdq_get_target(item); struct cmd_find_state *target = cmdq_get_target(item);
struct session *s = target->s;
struct client *tc = cmdq_get_target_client(item); struct client *tc = cmdq_get_target_client(item);
struct tty *tty = &tc->tty; struct tty *tty = &tc->tty;
const char *value, *cmd = NULL, **lines = NULL; const char *value, *shell[] = { NULL, NULL };
const char *shellcmd = NULL; const char *shellcmd = NULL;
char *cwd, *cause; char *cwd, *cause, **argv = args->argv;
int flags = 0; int flags = 0, argc = args->argc;
u_int px, py, w, h, nlines = 0; u_int px, py, w, h;
if (args_has(args, 'C')) { if (args_has(args, 'C')) {
server_client_clear_overlay(tc); server_client_clear_overlay(tc);
@@ -340,16 +342,6 @@ cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item)
if (tc->overlay_draw != NULL) if (tc->overlay_draw != NULL)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
if (args->argc >= 1)
cmd = args->argv[0];
if (args->argc >= 2) {
lines = (const char **)args->argv + 1;
nlines = args->argc - 1;
}
if (nlines != 0)
h = popup_height(nlines, lines) + 2;
else
h = tty->sy / 2; h = tty->sy / 2;
if (args_has(args, 'h')) { if (args_has(args, 'h')) {
h = args_percentage(args, 'h', 1, tty->sy, tty->sy, &cause); h = args_percentage(args, 'h', 1, tty->sy, tty->sy, &cause);
@@ -360,9 +352,6 @@ cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item)
} }
} }
if (nlines != 0)
w = popup_width(item, nlines, lines, tc, target) + 2;
else
w = tty->sx / 2; w = tty->sx / 2;
if (args_has(args, 'w')) { if (args_has(args, 'w')) {
w = args_percentage(args, 'w', 1, tty->sx, tty->sx, &cause); w = args_percentage(args, 'w', 1, tty->sx, tty->sx, &cause);
@@ -384,20 +373,26 @@ cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item)
if (value != NULL) if (value != NULL)
cwd = format_single_from_target(item, value); cwd = format_single_from_target(item, value);
else else
cwd = xstrdup(server_client_get_cwd(tc, target->s)); cwd = xstrdup(server_client_get_cwd(tc, s));
if (argc == 0)
shellcmd = options_get_string(s->options, "default-command");
else if (argc == 1)
shellcmd = argv[0];
if (argc <= 1 && (shellcmd == NULL || *shellcmd == '\0')) {
shellcmd = NULL;
shell[0] = options_get_string(s->options, "default-shell");
if (!checkshell(shell[0]))
shell[0] = _PATH_BSHELL;
argc = 1;
argv = (char**)shell;
}
value = args_get(args, 'R');
if (value != NULL)
shellcmd = format_single_from_target(item, value);
if (args_has(args, 'K'))
flags |= POPUP_WRITEKEYS;
if (args_has(args, 'E') > 1) if (args_has(args, 'E') > 1)
flags |= POPUP_CLOSEEXITZERO; flags |= POPUP_CLOSEEXITZERO;
else if (args_has(args, 'E')) else if (args_has(args, 'E'))
flags |= POPUP_CLOSEEXIT; flags |= POPUP_CLOSEEXIT;
if (popup_display(flags, item, px, py, w, h, nlines, lines, shellcmd, if (popup_display(flags, item, px, py, w, h, shellcmd, argc, argv, cwd,
cmd, cwd, tc, target, NULL, NULL) != 0) tc, s, NULL, NULL) != 0)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
return (CMD_RETURN_WAIT); return (CMD_RETURN_WAIT);
} }

View File

@@ -128,7 +128,7 @@ cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item)
cdata->input.c->references++; cdata->input.c->references++;
cmd_find_copy_state(&cdata->input.fs, target); cmd_find_copy_state(&cdata->input.fs, target);
if (job_run(shellcmd, s, if (job_run(shellcmd, 0, NULL, s,
server_client_get_cwd(cmdq_get_client(item), s), NULL, server_client_get_cwd(cmdq_get_client(item), s), NULL,
cmd_if_shell_callback, cmd_if_shell_free, cdata, 0, -1, cmd_if_shell_callback, cmd_if_shell_free, cdata, 0, -1,
-1) == NULL) { -1) == NULL) {

View File

@@ -174,7 +174,7 @@ cmd_run_shell_timer(__unused int fd, __unused short events, void* arg)
enum cmd_parse_status status; enum cmd_parse_status status;
if (cmd != NULL && cdata->shell) { if (cmd != NULL && cdata->shell) {
if (job_run(cmd, cdata->s, cdata->cwd, NULL, if (job_run(cmd, 0, NULL, cdata->s, cdata->cwd, NULL,
cmd_run_shell_callback, cmd_run_shell_free, cdata, cmd_run_shell_callback, cmd_run_shell_free, cdata,
cdata->flags, -1, -1) == NULL) cdata->flags, -1, -1) == NULL)
cmd_run_shell_free(cdata); cmd_run_shell_free(cdata);

View File

@@ -394,7 +394,7 @@ format_job_get(struct format_expand_state *es, const char *cmd)
if (force && fj->job != NULL) if (force && fj->job != NULL)
job_free(fj->job); job_free(fj->job);
if (force || (fj->job == NULL && fj->last != t)) { if (force || (fj->job == NULL && fj->last != t)) {
fj->job = job_run(expanded, NULL, fj->job = job_run(expanded, 0, NULL, NULL,
server_client_get_cwd(ft->client, NULL), format_job_update, server_client_get_cwd(ft->client, NULL), format_job_update,
format_job_complete, NULL, fj, JOB_NOWAIT, -1, -1); format_job_complete, NULL, fj, JOB_NOWAIT, -1, -1);
if (fj->job == NULL) { if (fj->job == NULL) {

26
job.c
View File

@@ -68,11 +68,11 @@ struct job {
/* All jobs list. */ /* All jobs list. */
static LIST_HEAD(joblist, job) all_jobs = LIST_HEAD_INITIALIZER(all_jobs); static LIST_HEAD(joblist, job) all_jobs = LIST_HEAD_INITIALIZER(all_jobs);
/* Start a job running, if it isn't already. */ /* Start a job running. */
struct job * struct job *
job_run(const char *cmd, struct session *s, const char *cwd, job_run(const char *cmd, int argc, char **argv, struct session *s,
job_update_cb updatecb, job_complete_cb completecb, job_free_cb freecb, const char *cwd, job_update_cb updatecb, job_complete_cb completecb,
void *data, int flags, int sx, int sy) job_free_cb freecb, void *data, int flags, int sx, int sy)
{ {
struct job *job; struct job *job;
struct environ *env; struct environ *env;
@@ -81,6 +81,7 @@ job_run(const char *cmd, struct session *s, const char *cwd,
const char *home; const char *home;
sigset_t set, oldset; sigset_t set, oldset;
struct winsize ws; struct winsize ws;
char **argvp;
/* /*
* Do not set TERM during .tmux.conf, it is nice to be able to use * Do not set TERM during .tmux.conf, it is nice to be able to use
@@ -101,7 +102,13 @@ job_run(const char *cmd, struct session *s, const char *cwd,
goto fail; goto fail;
pid = fork(); pid = fork();
} }
log_debug("%s: cmd=%s, cwd=%s", __func__, cmd, cwd == NULL ? "" : cwd); if (cmd == NULL) {
cmd_log_argv(argc, argv, "%s:", __func__);
log_debug("%s: cwd=%s", __func__, cwd == NULL ? "" : cwd);
} else {
log_debug("%s: cmd=%s, cwd=%s", __func__, cmd,
cwd == NULL ? "" : cwd);
}
switch (pid) { switch (pid) {
case -1: case -1:
@@ -141,8 +148,14 @@ job_run(const char *cmd, struct session *s, const char *cwd,
} }
closefrom(STDERR_FILENO + 1); closefrom(STDERR_FILENO + 1);
if (cmd != NULL) {
execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL); execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL);
fatal("execl failed"); fatal("execl failed");
} else {
argvp = cmd_copy_argv(argc, argv);
execvp(argvp[0], argvp);
fatal("execvp failed");
}
} }
sigprocmask(SIG_SETMASK, &oldset, NULL); sigprocmask(SIG_SETMASK, &oldset, NULL);
@@ -152,7 +165,10 @@ job_run(const char *cmd, struct session *s, const char *cwd,
job->state = JOB_RUNNING; job->state = JOB_RUNNING;
job->flags = flags; job->flags = flags;
if (cmd != NULL)
job->cmd = xstrdup(cmd); job->cmd = xstrdup(cmd);
else
job->cmd = cmd_stringify_argv(argc, argv);
job->pid = pid; job->pid = pid;
job->status = 0; job->status = 0;

197
popup.c
View File

@@ -32,13 +32,7 @@ struct popup_data {
struct cmdq_item *item; struct cmdq_item *item;
int flags; int flags;
char **lines;
u_int nlines;
char *cmd;
struct cmd_find_state fs;
struct screen s; struct screen s;
struct job *job; struct job *job;
struct input_ctx *ictx; struct input_ctx *ictx;
int status; int status;
@@ -105,54 +99,11 @@ popup_init_ctx_cb(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx)
ttyctx->arg = pd; ttyctx->arg = pd;
} }
static void
popup_write_screen(struct client *c, struct popup_data *pd)
{
struct cmdq_item *item = pd->item;
struct screen_write_ctx ctx;
char *copy, *next, *loop, *tmp;
struct format_tree *ft;
u_int i, y;
ft = format_create(c, item, FORMAT_NONE, 0);
if (cmd_find_valid_state(&pd->fs))
format_defaults(ft, c, pd->fs.s, pd->fs.wl, pd->fs.wp);
else
format_defaults(ft, c, NULL, NULL, NULL);
screen_write_start(&ctx, &pd->s);
screen_write_clearscreen(&ctx, 8);
y = 0;
for (i = 0; i < pd->nlines; i++) {
if (y == pd->sy - 2)
break;
copy = next = xstrdup(pd->lines[i]);
while ((loop = strsep(&next, "\n")) != NULL) {
if (y == pd->sy - 2)
break;
tmp = format_expand(ft, loop);
screen_write_cursormove(&ctx, 0, y, 0);
format_draw(&ctx, &grid_default_cell, pd->sx - 2, tmp,
NULL);
free(tmp);
y++;
}
free(copy);
}
format_free(ft);
screen_write_cursormove(&ctx, 0, y, 0);
screen_write_stop(&ctx);
}
static struct screen * static struct screen *
popup_mode_cb(struct client *c, u_int *cx, u_int *cy) popup_mode_cb(struct client *c, u_int *cx, u_int *cy)
{ {
struct popup_data *pd = c->overlay_data; struct popup_data *pd = c->overlay_data;
if (pd->ictx == NULL)
return (0);
*cx = pd->px + 1 + pd->s.cx; *cx = pd->px + 1 + pd->s.cx;
*cy = pd->py + 1 + pd->s.cy; *cy = pd->py + 1 + pd->s.cy;
return (&pd->s); return (&pd->s);
@@ -200,14 +151,12 @@ popup_free_cb(struct client *c)
{ {
struct popup_data *pd = c->overlay_data; struct popup_data *pd = c->overlay_data;
struct cmdq_item *item = pd->item; struct cmdq_item *item = pd->item;
u_int i;
if (pd->cb != NULL) if (pd->cb != NULL)
pd->cb(pd->status, pd->arg); pd->cb(pd->status, pd->arg);
if (item != NULL) { if (item != NULL) {
if (pd->ictx != NULL && if (cmdq_get_client(item) != NULL &&
cmdq_get_client(item) != NULL &&
cmdq_get_client(item)->session == NULL) cmdq_get_client(item)->session == NULL)
cmdq_get_client(item)->retval = pd->status; cmdq_get_client(item)->retval = pd->status;
cmdq_continue(item); cmdq_continue(item);
@@ -216,15 +165,9 @@ popup_free_cb(struct client *c)
if (pd->job != NULL) if (pd->job != NULL)
job_free(pd->job); job_free(pd->job);
if (pd->ictx != NULL)
input_free(pd->ictx); input_free(pd->ictx);
for (i = 0; i < pd->nlines; i++)
free(pd->lines[i]);
free(pd->lines);
screen_free(&pd->s); screen_free(&pd->s);
free(pd->cmd);
free(pd); free(pd);
} }
@@ -263,9 +206,7 @@ popup_handle_drag(struct client *c, struct popup_data *pd,
pd->sy = m->y - pd->py; pd->sy = m->y - pd->py;
screen_resize(&pd->s, pd->sx - 2, pd->sy - 2, 0); screen_resize(&pd->s, pd->sx - 2, pd->sy - 2, 0);
if (pd->ictx == NULL) if (pd->job != NULL)
popup_write_screen(c, pd);
else if (pd->job != NULL)
job_resize(pd->job, pd->sx - 2, pd->sy - 2); job_resize(pd->job, pd->sx - 2, pd->sy - 2);
server_redraw_client(c); server_redraw_client(c);
} }
@@ -276,13 +217,8 @@ popup_key_cb(struct client *c, struct key_event *event)
{ {
struct popup_data *pd = c->overlay_data; struct popup_data *pd = c->overlay_data;
struct mouse_event *m = &event->m; struct mouse_event *m = &event->m;
struct cmd_find_state *fs = &pd->fs; const char *buf;
struct format_tree *ft;
const char *cmd, *buf;
size_t len; size_t len;
struct cmdq_state *state;
enum cmd_parse_status status;
char *error;
if (KEYC_IS_MOUSE(event->key)) { if (KEYC_IS_MOUSE(event->key)) {
if (pd->dragging != OFF) { if (pd->dragging != OFF) {
@@ -314,13 +250,11 @@ popup_key_cb(struct client *c, struct key_event *event)
} }
} }
if (pd->ictx != NULL && (pd->flags & POPUP_WRITEKEYS)) { if ((((pd->flags & (POPUP_CLOSEEXIT|POPUP_CLOSEEXITZERO)) == 0) ||
if (((pd->flags & (POPUP_CLOSEEXIT|POPUP_CLOSEEXITZERO)) == 0 ||
pd->job == NULL) && pd->job == NULL) &&
(event->key == '\033' || event->key == '\003')) (event->key == '\033' || event->key == '\003'))
return (1); return (1);
if (pd->job == NULL) if (pd->job != NULL) {
return (0);
if (KEYC_IS_MOUSE(event->key)) { if (KEYC_IS_MOUSE(event->key)) {
/* Must be inside, checked already. */ /* Must be inside, checked already. */
if (!input_key_get_mouse(&pd->s, m, m->x - pd->px - 1, if (!input_key_get_mouse(&pd->s, m, m->x - pd->px - 1,
@@ -330,40 +264,8 @@ popup_key_cb(struct client *c, struct key_event *event)
return (0); return (0);
} }
input_key(&pd->s, job_get_event(pd->job), event->key); input_key(&pd->s, job_get_event(pd->job), event->key);
}
return (0); return (0);
}
if (pd->cmd == NULL)
return (1);
ft = format_create(NULL, pd->item, FORMAT_NONE, 0);
if (cmd_find_valid_state(fs))
format_defaults(ft, c, fs->s, fs->wl, fs->wp);
else
format_defaults(ft, c, NULL, NULL, NULL);
format_add(ft, "popup_key", "%s", key_string_lookup_key(event->key, 0));
if (KEYC_IS_MOUSE(event->key)) {
format_add(ft, "popup_mouse", "1");
format_add(ft, "popup_mouse_x", "%u", m->x - pd->px);
format_add(ft, "popup_mouse_y", "%u", m->y - pd->py);
}
cmd = format_expand(ft, pd->cmd);
format_free(ft);
if (pd->item != NULL)
event = cmdq_get_event(pd->item);
else
event = NULL;
state = cmdq_new_state(&pd->fs, event, 0);
status = cmd_parse_and_append(cmd, NULL, c, state, &error);
if (status == CMD_PARSE_ERROR) {
cmdq_append(c, cmdq_get_error(error));
free(error);
}
cmdq_free_state(state);
return (1);
out: out:
pd->lx = m->x; pd->lx = m->x;
@@ -416,62 +318,12 @@ popup_job_complete_cb(struct job *job)
server_client_clear_overlay(pd->c); server_client_clear_overlay(pd->c);
} }
u_int
popup_height(u_int nlines, const char **lines)
{
char *copy, *next, *loop;
u_int i, height = 0;
for (i = 0; i < nlines; i++) {
copy = next = xstrdup(lines[i]);
while ((loop = strsep(&next, "\n")) != NULL)
height++;
free(copy);
}
return (height);
}
u_int
popup_width(struct cmdq_item *item, u_int nlines, const char **lines,
struct client *c, struct cmd_find_state *fs)
{
char *copy, *next, *loop, *tmp;
struct format_tree *ft;
u_int i, width = 0, tmpwidth;
ft = format_create(cmdq_get_client(item), item, FORMAT_NONE, 0);
if (fs != NULL && cmd_find_valid_state(fs))
format_defaults(ft, c, fs->s, fs->wl, fs->wp);
else
format_defaults(ft, c, NULL, NULL, NULL);
for (i = 0; i < nlines; i++) {
copy = next = xstrdup(lines[i]);
while ((loop = strsep(&next, "\n")) != NULL) {
tmp = format_expand(ft, loop);
tmpwidth = format_width(tmp);
if (tmpwidth > width)
width = tmpwidth;
free(tmp);
}
free(copy);
}
format_free(ft);
return (width);
}
int int
popup_display(int flags, struct cmdq_item *item, u_int px, u_int py, u_int sx, popup_display(int flags, struct cmdq_item *item, u_int px, u_int py, u_int sx,
u_int sy, u_int nlines, const char **lines, const char *shellcmd, u_int sy, const char *shellcmd, int argc, char **argv, const char *cwd,
const char *cmd, const char *cwd, struct client *c, struct client *c, struct session *s, popup_close_cb cb, void *arg)
struct cmd_find_state *fs, popup_close_cb cb, void *arg)
{ {
struct popup_data *pd; struct popup_data *pd;
u_int i;
struct session *s;
int jobflags;
if (sx < 3 || sy < 3) if (sx < 3 || sy < 3)
return (-1); return (-1);
@@ -489,39 +341,17 @@ popup_display(int flags, struct cmdq_item *item, u_int px, u_int py, u_int sx,
pd->arg = arg; pd->arg = arg;
pd->status = 128 + SIGHUP; pd->status = 128 + SIGHUP;
if (fs != NULL)
cmd_find_copy_state(&pd->fs, fs);
screen_init(&pd->s, sx - 2, sy - 2, 0); screen_init(&pd->s, sx - 2, sy - 2, 0);
if (cmd != NULL)
pd->cmd = xstrdup(cmd);
pd->px = px; pd->px = px;
pd->py = py; pd->py = py;
pd->sx = sx; pd->sx = sx;
pd->sy = sy; pd->sy = sy;
pd->nlines = nlines; pd->job = job_run(shellcmd, argc, argv, s, cwd,
if (pd->nlines != 0) popup_job_update_cb, popup_job_complete_cb, NULL, pd,
pd->lines = xreallocarray(NULL, pd->nlines, sizeof *pd->lines); JOB_NOWAIT|JOB_PTY|JOB_KEEPWRITE, pd->sx - 2, pd->sy - 2);
for (i = 0; i < pd->nlines; i++)
pd->lines[i] = xstrdup(lines[i]);
popup_write_screen(c, pd);
if (shellcmd != NULL) {
if (fs != NULL)
s = fs->s;
else
s = NULL;
jobflags = JOB_NOWAIT|JOB_PTY;
if (flags & POPUP_WRITEKEYS)
jobflags |= JOB_KEEPWRITE;
pd->job = job_run(shellcmd, s, cwd, popup_job_update_cb,
popup_job_complete_cb, NULL, pd, jobflags, pd->sx - 2,
pd->sy - 2);
pd->ictx = input_init(NULL, job_get_event(pd->job)); pd->ictx = input_init(NULL, job_get_event(pd->job));
}
server_client_set_overlay(c, 0, popup_check_cb, popup_mode_cb, server_client_set_overlay(c, 0, popup_check_cb, popup_mode_cb,
popup_draw_cb, popup_key_cb, popup_free_cb, pd); popup_draw_cb, popup_key_cb, popup_free_cb, pd);
@@ -607,9 +437,8 @@ popup_editor(struct client *c, const char *buf, size_t len,
py = (c->tty.sy / 2) - (sy / 2); py = (c->tty.sy / 2) - (sy / 2);
xasprintf(&cmd, "%s %s", editor, path); xasprintf(&cmd, "%s %s", editor, path);
if (popup_display(POPUP_WRITEKEYS|POPUP_CLOSEEXIT, NULL, px, py, sx, sy, if (popup_display(POPUP_CLOSEEXIT, NULL, px, py, sx, sy, cmd, 0, NULL,
0, NULL, cmd, NULL, _PATH_TMP, c, NULL, popup_editor_close_cb, _PATH_TMP, c, NULL, popup_editor_close_cb, pe) != 0) {
pe) != 0) {
popup_editor_free(pe); popup_editor_free(pe);
free(cmd); free(cmd);
return (-1); return (-1);

View File

@@ -265,8 +265,9 @@ spawn_pane(struct spawn_context *sc, char **cause)
} }
/* /*
* Now we have a pane with nothing running in it ready for the new process. * Now we have a pane with nothing running in it ready for the new
* Work out the command and arguments and store the working directory. * process. Work out the command and arguments and store the working
* directory.
*/ */
if (sc->argc == 0 && (~sc->flags & SPAWN_RESPAWN)) { if (sc->argc == 0 && (~sc->flags & SPAWN_RESPAWN)) {
cmd = options_get_string(s->options, "default-command"); cmd = options_get_string(s->options, "default-command");

61
tmux.1
View File

@@ -4923,9 +4923,6 @@ The following variables are available, where appropriate:
.It Li "pane_tty" Ta "" Ta "Pseudo terminal of pane" .It Li "pane_tty" Ta "" Ta "Pseudo terminal of pane"
.It Li "pane_width" Ta "" Ta "Width of pane" .It Li "pane_width" Ta "" Ta "Width of pane"
.It Li "pid" Ta "" Ta "Server PID" .It Li "pid" Ta "" Ta "Server PID"
.It Li "popup_key" Ta "" Ta "Key pressed in popup"
.It Li "popup_mouse_x" Ta "" Ta "Mouse X position in popup"
.It Li "popup_mouse_y" Ta "" Ta "Mouse Y position in popup"
.It Li "rectangle_toggle" Ta "" Ta "1 if rectangle selection is activated" .It Li "rectangle_toggle" Ta "" Ta "1 if rectangle selection is activated"
.It Li "scroll_position" Ta "" Ta "Scroll position in copy mode" .It Li "scroll_position" Ta "" Ta "Scroll position in copy mode"
.It Li "scroll_region_lower" Ta "" Ta "Bottom of scroll region in pane" .It Li "scroll_region_lower" Ta "" Ta "Bottom of scroll region in pane"
@@ -5584,58 +5581,24 @@ lists the format variables and their values.
forwards any input read from stdin to the empty pane given by forwards any input read from stdin to the empty pane given by
.Ar target-pane . .Ar target-pane .
.It Xo Ic display-popup .It Xo Ic display-popup
.Op Fl CEK .Op Fl CE
.Op Fl c Ar target-client .Op Fl c Ar target-client
.Op Fl d Ar start-directory .Op Fl d Ar start-directory
.Op Fl h Ar height .Op Fl h Ar height
.Op Fl R Ar shell-command
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
.Op Fl w Ar width .Op Fl w Ar width
.Op Fl x Ar position .Op Fl x Ar position
.Op Fl y Ar position .Op Fl y Ar position
.Op Ar command Ar line Ar ... .Op Ar shell-command
.Xc .Xc
.D1 (alias: Ic popup ) .D1 (alias: Ic popup )
Display a popup on Display a popup running
.Ar shell-command
on
.Ar target-client . .Ar target-client .
A popup is a rectangular box drawn over the top of any panes. A popup is a rectangular box drawn over the top of any panes.
Panes are not updated while a popup is present. Panes are not updated while a popup is present.
The popup content may be given in two ways:
.Bl -enum -offset Ds
.It
A set of lines as arguments.
Each line is a format which is expanded using
.Ar target-pane
as the target.
If a line contains newlines it is split into multiple lines.
Lines may use styles, see the
.Sx STYLES
section.
.It
A shell command given by
.Fl R
which is run and any output shown in the pane.
.El
.Pp .Pp
The first argument,
.Ar command ,
is a
.Nm
command which is run when a key is pressed.
The key is available in the
.Ql popup_key
format.
After
.Ar command
is run, the popup is closed.
It may be empty to discard any key presses.
If
.Fl K
is given together with
.Fl R ,
key presses are instead passed to the
.Fl R
shell command.
.Fl E .Fl E
closes the popup automatically when closes the popup automatically when
.Ar shell-command .Ar shell-command
@@ -5645,14 +5608,6 @@ Two
closes the popup only if closes the popup only if
.Ar shell-command .Ar shell-command
exited with success. exited with success.
With
.Fl K ,
.Ql Escape
and
.Ql C-c
close the popup unless
.Fl E
is also given.
.Pp .Pp
.Fl x .Fl x
and and
@@ -5665,11 +5620,7 @@ and
.Fl h .Fl h
give the width and height - both may be a percentage (followed by give the width and height - both may be a percentage (followed by
.Ql % ) . .Ql % ) .
If omitted, without If omitted, half of the terminal size is used.
.Fl R
they are calculated from the given lines and with
.Fl R
they use half the terminal size.
.Pp .Pp
The The
.Fl C .Fl C

19
tmux.h
View File

@@ -2067,9 +2067,9 @@ typedef void (*job_free_cb) (void *);
#define JOB_NOWAIT 0x1 #define JOB_NOWAIT 0x1
#define JOB_KEEPWRITE 0x2 #define JOB_KEEPWRITE 0x2
#define JOB_PTY 0x4 #define JOB_PTY 0x4
struct job *job_run(const char *, struct session *, const char *, struct job *job_run(const char *, int, char **, struct session *,
job_update_cb, job_complete_cb, job_free_cb, void *, int, const char *, job_update_cb, job_complete_cb, job_free_cb,
int, int); void *, int, int, int);
void job_free(struct job *); void job_free(struct job *);
void job_resize(struct job *, u_int, u_int); void job_resize(struct job *, u_int, u_int);
void job_check_died(pid_t, int); void job_check_died(pid_t, int);
@@ -3038,18 +3038,13 @@ int menu_display(struct menu *, int, struct cmdq_item *, u_int,
menu_choice_cb, void *); menu_choice_cb, void *);
/* popup.c */ /* popup.c */
#define POPUP_WRITEKEYS 0x1 #define POPUP_CLOSEEXIT 0x1
#define POPUP_CLOSEEXIT 0x2 #define POPUP_CLOSEEXITZERO 0x2
#define POPUP_CLOSEEXITZERO 0x4
typedef void (*popup_close_cb)(int, void *); typedef void (*popup_close_cb)(int, void *);
typedef void (*popup_finish_edit_cb)(char *, size_t, void *); typedef void (*popup_finish_edit_cb)(char *, size_t, void *);
u_int popup_width(struct cmdq_item *, u_int, const char **,
struct client *, struct cmd_find_state *);
u_int popup_height(u_int, const char **);
int popup_display(int, struct cmdq_item *, u_int, u_int, u_int, int popup_display(int, struct cmdq_item *, u_int, u_int, u_int,
u_int, u_int, const char **, const char *, const char *, u_int, const char *, int, char **, const char *,
const char *, struct client *, struct cmd_find_state *, struct client *, struct session *, popup_close_cb, void *);
popup_close_cb, void *);
int popup_editor(struct client *, const char *, size_t, int popup_editor(struct client *, const char *, size_t,
popup_finish_edit_cb, void *); popup_finish_edit_cb, void *);

View File

@@ -3963,8 +3963,8 @@ window_copy_pipe_run(struct window_mode_entry *wme, struct session *s,
if (cmd == NULL || *cmd == '\0') if (cmd == NULL || *cmd == '\0')
cmd = options_get_string(global_options, "copy-command"); cmd = options_get_string(global_options, "copy-command");
if (cmd != NULL && *cmd != '\0') { if (cmd != NULL && *cmd != '\0') {
job = job_run(cmd, s, NULL, NULL, NULL, NULL, NULL, JOB_NOWAIT, job = job_run(cmd, 0, NULL, s, NULL, NULL, NULL, NULL, NULL,
-1, -1); JOB_NOWAIT, -1, -1);
bufferevent_write(job_get_event(job), buf, *len); bufferevent_write(job_get_event(job), buf, *len);
} }
return (buf); return (buf);