mirror of
https://github.com/tmux/tmux.git
synced 2026-06-20 17:25:57 +00:00
Merge branch 'obsd-master'
This commit is contained in:
132
popup.c
132
popup.c
@@ -75,12 +75,6 @@ struct popup_data {
|
|||||||
u_int lb;
|
u_int lb;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct popup_editor {
|
|
||||||
char *path;
|
|
||||||
popup_finish_edit_cb cb;
|
|
||||||
void *arg;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct menu_item popup_menu_items[] = {
|
static const struct menu_item popup_menu_items[] = {
|
||||||
{ "Close", 'q', NULL },
|
{ "Close", 'q', NULL },
|
||||||
{ "#{?buffer_name,Paste #[underscore]#{buffer_name},}", 'p', NULL },
|
{ "#{?buffer_name,Paste #[underscore]#{buffer_name},}", 'p', NULL },
|
||||||
@@ -94,15 +88,6 @@ static const struct menu_item popup_menu_items[] = {
|
|||||||
{ NULL, KEYC_NONE, NULL }
|
{ NULL, KEYC_NONE, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct menu_item popup_internal_menu_items[] = {
|
|
||||||
{ "Close", 'q', NULL },
|
|
||||||
{ "", KEYC_NONE, NULL },
|
|
||||||
{ "Fill Space", 'F', NULL },
|
|
||||||
{ "Centre", 'C', NULL },
|
|
||||||
|
|
||||||
{ NULL, KEYC_NONE, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
popup_free(struct popup_data *pd)
|
popup_free(struct popup_data *pd)
|
||||||
{
|
{
|
||||||
@@ -650,10 +635,6 @@ popup_key_cb(struct client *c, void *data, struct key_event *event)
|
|||||||
|
|
||||||
menu:
|
menu:
|
||||||
pd->menu = menu_create("");
|
pd->menu = menu_create("");
|
||||||
if (pd->flags & POPUP_INTERNAL) {
|
|
||||||
menu_add_items(pd->menu, popup_internal_menu_items, NULL, c,
|
|
||||||
NULL);
|
|
||||||
} else
|
|
||||||
menu_add_items(pd->menu, popup_menu_items, NULL, c, NULL);
|
menu_add_items(pd->menu, popup_menu_items, NULL, c, NULL);
|
||||||
if (m->x >= (pd->menu->width + 4) / 2)
|
if (m->x >= (pd->menu->width + 4) / 2)
|
||||||
x = m->x - (pd->menu->width + 4) / 2;
|
x = m->x - (pd->menu->width + 4) / 2;
|
||||||
@@ -861,9 +842,6 @@ popup_display(int flags, enum box_lines lines, struct cmdq_item *item, u_int px,
|
|||||||
pd->psx = sx;
|
pd->psx = sx;
|
||||||
pd->psy = sy;
|
pd->psy = sy;
|
||||||
|
|
||||||
if (flags & POPUP_NOJOB)
|
|
||||||
pd->ictx = input_init(NULL, NULL, &pd->palette, NULL);
|
|
||||||
else {
|
|
||||||
pd->job = job_run(shellcmd, argc, argv, env, s, cwd,
|
pd->job = job_run(shellcmd, argc, argv, env, s, cwd,
|
||||||
popup_job_update_cb, popup_job_complete_cb, NULL, pd,
|
popup_job_update_cb, popup_job_complete_cb, NULL, pd,
|
||||||
JOB_NOWAIT|JOB_PTY|JOB_KEEPWRITE|JOB_DEFAULTSHELL, jx, jy);
|
JOB_NOWAIT|JOB_PTY|JOB_KEEPWRITE|JOB_DEFAULTSHELL, jx, jy);
|
||||||
@@ -871,117 +849,9 @@ popup_display(int flags, enum box_lines lines, struct cmdq_item *item, u_int px,
|
|||||||
popup_free(pd);
|
popup_free(pd);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
pd->ictx = input_init(NULL, job_get_event(pd->job),
|
pd->ictx = input_init(NULL, job_get_event(pd->job), &pd->palette, c);
|
||||||
&pd->palette, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
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, popup_resize_cb, pd);
|
popup_draw_cb, popup_key_cb, popup_free_cb, popup_resize_cb, pd);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
popup_write(struct client *c, const char *data, size_t size)
|
|
||||||
{
|
|
||||||
struct popup_data *pd = c->overlay_data;
|
|
||||||
|
|
||||||
if (!popup_present(c))
|
|
||||||
return;
|
|
||||||
c->overlay_check = NULL;
|
|
||||||
c->overlay_data = NULL;
|
|
||||||
input_parse_screen(pd->ictx, &pd->s, popup_init_ctx_cb, pd, data, size);
|
|
||||||
c->overlay_check = popup_check_cb;
|
|
||||||
c->overlay_data = pd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
popup_editor_free(struct popup_editor *pe)
|
|
||||||
{
|
|
||||||
unlink(pe->path);
|
|
||||||
free(pe->path);
|
|
||||||
free(pe);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
popup_editor_close_cb(int status, void *arg)
|
|
||||||
{
|
|
||||||
struct popup_editor *pe = arg;
|
|
||||||
FILE *f;
|
|
||||||
char *buf = NULL;
|
|
||||||
off_t len = 0;
|
|
||||||
|
|
||||||
if (status != 0) {
|
|
||||||
pe->cb(NULL, 0, pe->arg);
|
|
||||||
popup_editor_free(pe);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
f = fopen(pe->path, "r");
|
|
||||||
if (f != NULL) {
|
|
||||||
fseeko(f, 0, SEEK_END);
|
|
||||||
len = ftello(f);
|
|
||||||
fseeko(f, 0, SEEK_SET);
|
|
||||||
|
|
||||||
if (len == 0 ||
|
|
||||||
(uintmax_t)len > (uintmax_t)SIZE_MAX ||
|
|
||||||
(buf = malloc(len)) == NULL ||
|
|
||||||
fread(buf, len, 1, f) != 1) {
|
|
||||||
free(buf);
|
|
||||||
buf = NULL;
|
|
||||||
len = 0;
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
pe->cb(buf, len, pe->arg); /* callback now owns buffer */
|
|
||||||
popup_editor_free(pe);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
popup_editor(struct client *c, const char *buf, size_t len,
|
|
||||||
popup_finish_edit_cb cb, void *arg)
|
|
||||||
{
|
|
||||||
struct popup_editor *pe;
|
|
||||||
int fd;
|
|
||||||
FILE *f;
|
|
||||||
char *cmd;
|
|
||||||
char path[] = _PATH_TMP "tmux.XXXXXXXX";
|
|
||||||
const char *editor;
|
|
||||||
u_int px, py, sx, sy;
|
|
||||||
|
|
||||||
editor = options_get_string(global_options, "editor");
|
|
||||||
if (*editor == '\0')
|
|
||||||
return (-1);
|
|
||||||
|
|
||||||
fd = mkstemp(path);
|
|
||||||
if (fd == -1)
|
|
||||||
return (-1);
|
|
||||||
f = fdopen(fd, "w");
|
|
||||||
if (f == NULL)
|
|
||||||
return (-1);
|
|
||||||
if (fwrite(buf, len, 1, f) != 1) {
|
|
||||||
fclose(f);
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
pe = xcalloc(1, sizeof *pe);
|
|
||||||
pe->path = xstrdup(path);
|
|
||||||
pe->cb = cb;
|
|
||||||
pe->arg = arg;
|
|
||||||
|
|
||||||
sx = c->tty.sx * 9 / 10;
|
|
||||||
sy = c->tty.sy * 9 / 10;
|
|
||||||
px = (c->tty.sx / 2) - (sx / 2);
|
|
||||||
py = (c->tty.sy / 2) - (sy / 2);
|
|
||||||
|
|
||||||
xasprintf(&cmd, "%s %s", editor, path);
|
|
||||||
if (popup_display(POPUP_INTERNAL|POPUP_CLOSEEXIT, BOX_LINES_DEFAULT,
|
|
||||||
NULL, px, py, sx, sy, NULL, cmd, 0, NULL, _PATH_TMP, NULL, c, NULL,
|
|
||||||
NULL, NULL, popup_editor_close_cb, pe) != 0) {
|
|
||||||
popup_editor_free(pe);
|
|
||||||
free(cmd);
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
free(cmd);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|||||||
1
server.c
1
server.c
@@ -498,6 +498,7 @@ server_child_exited(pid_t pid, int status)
|
|||||||
wp->flags |= PANE_EXITED;
|
wp->flags |= PANE_EXITED;
|
||||||
|
|
||||||
window_pane_wait_finish(wp);
|
window_pane_wait_finish(wp);
|
||||||
|
spawn_editor_finish(wp);
|
||||||
|
|
||||||
if (window_pane_destroy_ready(wp))
|
if (window_pane_destroy_ready(wp))
|
||||||
server_destroy_pane(wp, 1);
|
server_destroy_pane(wp, 1);
|
||||||
|
|||||||
195
spawn.c
195
spawn.c
@@ -17,9 +17,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -54,11 +56,10 @@ spawn_log(const char *from, struct spawn_context *sc)
|
|||||||
struct session *s = sc->s;
|
struct session *s = sc->s;
|
||||||
struct winlink *wl = sc->wl;
|
struct winlink *wl = sc->wl;
|
||||||
struct window_pane *wp0 = sc->wp0;
|
struct window_pane *wp0 = sc->wp0;
|
||||||
const char *name = cmdq_get_name(sc->item);
|
const char *name = (sc->name == NULL ? "none" : sc->name);
|
||||||
char tmp[128];
|
char tmp[128];
|
||||||
|
|
||||||
log_debug("%s: %s, flags=%#x", from, name, sc->flags);
|
log_debug("%s: name=%s, flags=%#x", from, name, sc->flags);
|
||||||
|
|
||||||
if (wl != NULL && wp0 != NULL)
|
if (wl != NULL && wp0 != NULL)
|
||||||
xsnprintf(tmp, sizeof tmp, "wl=%d wp0=%%%u", wl->idx, wp0->id);
|
xsnprintf(tmp, sizeof tmp, "wl=%d wp0=%%%u", wl->idx, wp0->id);
|
||||||
else if (wl != NULL)
|
else if (wl != NULL)
|
||||||
@@ -68,7 +69,6 @@ spawn_log(const char *from, struct spawn_context *sc)
|
|||||||
else
|
else
|
||||||
xsnprintf(tmp, sizeof tmp, "wl=none wp0=none");
|
xsnprintf(tmp, sizeof tmp, "wl=none wp0=none");
|
||||||
log_debug("%s: s=$%u %s idx=%d", from, s->id, tmp, sc->idx);
|
log_debug("%s: s=$%u %s idx=%d", from, s->id, tmp, sc->idx);
|
||||||
log_debug("%s: name=%s", from, sc->name == NULL ? "none" : sc->name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct winlink *
|
struct winlink *
|
||||||
@@ -201,9 +201,9 @@ struct window_pane *
|
|||||||
spawn_pane(struct spawn_context *sc, char **cause)
|
spawn_pane(struct spawn_context *sc, char **cause)
|
||||||
{
|
{
|
||||||
struct cmdq_item *item = sc->item;
|
struct cmdq_item *item = sc->item;
|
||||||
struct cmd_find_state *target = cmdq_get_target(item);
|
struct client *c;
|
||||||
struct client *c = cmdq_get_client(item);
|
|
||||||
struct session *s = sc->s;
|
struct session *s = sc->s;
|
||||||
|
struct session *ts;
|
||||||
struct window *w = sc->wl->window;
|
struct window *w = sc->wl->window;
|
||||||
struct window_pane *new_wp;
|
struct window_pane *new_wp;
|
||||||
struct environ *child;
|
struct environ *child;
|
||||||
@@ -220,6 +220,14 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
|||||||
sigset_t set, oldset;
|
sigset_t set, oldset;
|
||||||
key_code key;
|
key_code key;
|
||||||
|
|
||||||
|
if (item != NULL) {
|
||||||
|
ts = cmdq_get_target(item)->s;
|
||||||
|
c = cmdq_get_client(item);
|
||||||
|
} else {
|
||||||
|
ts = s;
|
||||||
|
c = sc->tc;
|
||||||
|
}
|
||||||
|
|
||||||
spawn_log(__func__, sc);
|
spawn_log(__func__, sc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -227,16 +235,19 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
|||||||
* the pane's stored one unless specified.
|
* the pane's stored one unless specified.
|
||||||
*/
|
*/
|
||||||
if (sc->cwd != NULL) {
|
if (sc->cwd != NULL) {
|
||||||
cwd = format_single(item, sc->cwd, c, target->s, NULL, NULL);
|
if (item != NULL)
|
||||||
|
cwd = format_single(item, sc->cwd, c, ts, NULL, NULL);
|
||||||
|
else
|
||||||
|
cwd = xstrdup(sc->cwd);
|
||||||
if (*cwd != '/') {
|
if (*cwd != '/') {
|
||||||
xasprintf(&new_cwd, "%s%s%s",
|
xasprintf(&new_cwd, "%s%s%s",
|
||||||
server_client_get_cwd(c, target->s),
|
server_client_get_cwd(c, ts),
|
||||||
*cwd != '\0' ? "/" : "", cwd);
|
*cwd != '\0' ? "/" : "", cwd);
|
||||||
free(cwd);
|
free(cwd);
|
||||||
cwd = new_cwd;
|
cwd = new_cwd;
|
||||||
}
|
}
|
||||||
} else if (~sc->flags & SPAWN_RESPAWN)
|
} else if (~sc->flags & SPAWN_RESPAWN)
|
||||||
cwd = xstrdup(server_client_get_cwd(c, target->s));
|
cwd = xstrdup(server_client_get_cwd(c, ts));
|
||||||
else
|
else
|
||||||
cwd = NULL;
|
cwd = NULL;
|
||||||
|
|
||||||
@@ -516,3 +527,169 @@ complete:
|
|||||||
notify_window("window-layout-changed", w);
|
notify_window("window-layout-changed", w);
|
||||||
return (new_wp);
|
return (new_wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct spawn_editor_state {
|
||||||
|
char *path;
|
||||||
|
pid_t pid;
|
||||||
|
spawn_finish_edit_cb cb;
|
||||||
|
void *arg;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
spawn_editor_free(struct spawn_editor_state *es)
|
||||||
|
{
|
||||||
|
unlink(es->path);
|
||||||
|
free(es->path);
|
||||||
|
free(es);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spawn_cancel_editor(struct spawn_editor_state *es)
|
||||||
|
{
|
||||||
|
if (es == NULL)
|
||||||
|
return;
|
||||||
|
es->cb = NULL;
|
||||||
|
es->arg = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t
|
||||||
|
spawn_get_editor_pid(struct spawn_editor_state *es)
|
||||||
|
{
|
||||||
|
if (es == NULL)
|
||||||
|
return (-1);
|
||||||
|
return (es->pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spawn_editor_finish(struct window_pane *wp)
|
||||||
|
{
|
||||||
|
struct spawn_editor_state *es = wp->editor;
|
||||||
|
FILE *f;
|
||||||
|
char *buf = NULL;
|
||||||
|
off_t len = 0;
|
||||||
|
int status = 128 + SIGHUP;
|
||||||
|
|
||||||
|
if (es == NULL)
|
||||||
|
return;
|
||||||
|
wp->editor = NULL;
|
||||||
|
|
||||||
|
if (wp->flags & PANE_STATUSREADY) {
|
||||||
|
if (WIFEXITED(wp->status))
|
||||||
|
status = WEXITSTATUS(wp->status);
|
||||||
|
else if (WIFSIGNALED(wp->status))
|
||||||
|
status = WTERMSIG(wp->status) + 128;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (es->cb == NULL) {
|
||||||
|
spawn_editor_free(es);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (status != 0) {
|
||||||
|
es->cb(NULL, 0, es->arg);
|
||||||
|
spawn_editor_free(es);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
f = fopen(es->path, "r");
|
||||||
|
if (f != NULL) {
|
||||||
|
if (fseeko(f, 0, SEEK_END) == 0) {
|
||||||
|
len = ftello(f);
|
||||||
|
if (len > 0 && (uintmax_t)len <= (uintmax_t)SIZE_MAX) {
|
||||||
|
if (fseeko(f, 0, SEEK_SET) == 0) {
|
||||||
|
buf = malloc(len);
|
||||||
|
if (buf != NULL &&
|
||||||
|
fread(buf, len, 1, f) != 1) {
|
||||||
|
free(buf);
|
||||||
|
buf = NULL;
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
es->cb(buf, len, es->arg);
|
||||||
|
spawn_editor_free(es);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct spawn_editor_state *
|
||||||
|
spawn_editor(struct client *c, const char *buf, size_t len,
|
||||||
|
spawn_finish_edit_cb cb, void *arg)
|
||||||
|
{
|
||||||
|
struct spawn_editor_state *es;
|
||||||
|
struct spawn_context sc = { 0 };
|
||||||
|
struct session *s = c->session;
|
||||||
|
struct winlink *wl = s->curw;
|
||||||
|
struct window *w = wl->window;
|
||||||
|
struct window_pane *wp;
|
||||||
|
struct layout_cell *lc;
|
||||||
|
struct environ *env;
|
||||||
|
FILE *f;
|
||||||
|
char *cmd, *cause = NULL;
|
||||||
|
char path[] = _PATH_TMP "tmux.XXXXXXXX";
|
||||||
|
const char *editor;
|
||||||
|
int fd;
|
||||||
|
u_int px, py, sx, sy;
|
||||||
|
|
||||||
|
editor = options_get_string(global_options, "editor");
|
||||||
|
fd = mkstemp(path);
|
||||||
|
if (fd == -1)
|
||||||
|
return (NULL);
|
||||||
|
f = fdopen(fd, "w");
|
||||||
|
if (f == NULL) {
|
||||||
|
close(fd);
|
||||||
|
unlink(path);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
if (fwrite(buf, len, 1, f) != 1) {
|
||||||
|
fclose(f);
|
||||||
|
unlink(path);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
es = xcalloc(1, sizeof *es);
|
||||||
|
es->path = xstrdup(path);
|
||||||
|
es->cb = cb;
|
||||||
|
es->arg = arg;
|
||||||
|
|
||||||
|
sx = w->sx * 9 / 10;
|
||||||
|
sy = w->sy * 9 / 10;
|
||||||
|
px = w->sx / 2 - sx / 2;
|
||||||
|
py = w->sy / 2 - sy / 2;
|
||||||
|
window_push_zoom(w, 1, 0);
|
||||||
|
lc = layout_floating_pane(w, sx, sy, px, py);
|
||||||
|
if (lc == NULL) {
|
||||||
|
spawn_editor_free(es);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
xasprintf(&cmd, "%s %s", editor, path);
|
||||||
|
env = environ_create();
|
||||||
|
sc.s = s;
|
||||||
|
sc.wl = wl;
|
||||||
|
sc.tc = c;
|
||||||
|
sc.wp0 = w->active;
|
||||||
|
sc.lc = lc;
|
||||||
|
sc.argc = 1;
|
||||||
|
sc.argv = &cmd;
|
||||||
|
sc.environ = env;
|
||||||
|
sc.idx = -1;
|
||||||
|
sc.cwd = _PATH_TMP;
|
||||||
|
sc.flags = SPAWN_FLOATING;
|
||||||
|
|
||||||
|
wp = spawn_pane(&sc, &cause);
|
||||||
|
free(cmd);
|
||||||
|
environ_free(env);
|
||||||
|
if (wp == NULL) {
|
||||||
|
free(cause);
|
||||||
|
spawn_editor_free(es);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
options_set_number(wp->options, "remain-on-exit", 0);
|
||||||
|
es->pid = wp->pid;
|
||||||
|
wp->editor = es;
|
||||||
|
return (es);
|
||||||
|
}
|
||||||
|
|||||||
15
tmux.h
15
tmux.h
@@ -1309,6 +1309,7 @@ struct window_pane {
|
|||||||
int status;
|
int status;
|
||||||
struct timeval dead_time;
|
struct timeval dead_time;
|
||||||
struct cmdq_item *wait_item; /* new-pane -W: waiting for pane exit */
|
struct cmdq_item *wait_item; /* new-pane -W: waiting for pane exit */
|
||||||
|
struct spawn_editor_state *editor;
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
struct bufferevent *event;
|
struct bufferevent *event;
|
||||||
@@ -3840,19 +3841,13 @@ int menu_key_cb(struct client *, void *, struct key_event *);
|
|||||||
/* popup.c */
|
/* popup.c */
|
||||||
#define POPUP_CLOSEEXIT 0x1
|
#define POPUP_CLOSEEXIT 0x1
|
||||||
#define POPUP_CLOSEEXITZERO 0x2
|
#define POPUP_CLOSEEXITZERO 0x2
|
||||||
#define POPUP_INTERNAL 0x4
|
#define POPUP_CLOSEANYKEY 0x4
|
||||||
#define POPUP_CLOSEANYKEY 0x8
|
|
||||||
#define POPUP_NOJOB 0x10
|
|
||||||
typedef void (*popup_close_cb)(int, void *);
|
typedef void (*popup_close_cb)(int, void *);
|
||||||
typedef void (*popup_finish_edit_cb)(char *, size_t, void *);
|
|
||||||
int popup_display(int, enum box_lines, struct cmdq_item *, u_int,
|
int popup_display(int, enum box_lines, struct cmdq_item *, u_int,
|
||||||
u_int, u_int, u_int, struct environ *, const char *, int,
|
u_int, u_int, u_int, struct environ *, const char *, int,
|
||||||
char **, const char *, const char *, struct client *,
|
char **, const char *, const char *, struct client *,
|
||||||
struct session *, const char *, const char *,
|
struct session *, const char *, const char *,
|
||||||
popup_close_cb, void *);
|
popup_close_cb, void *);
|
||||||
void popup_write(struct client *, const char *, size_t);
|
|
||||||
int popup_editor(struct client *, const char *, size_t,
|
|
||||||
popup_finish_edit_cb, void *);
|
|
||||||
int popup_present(struct client *);
|
int popup_present(struct client *);
|
||||||
int popup_modify(struct client *, const char *, const char *,
|
int popup_modify(struct client *, const char *, const char *,
|
||||||
const char *, enum box_lines, int);
|
const char *, enum box_lines, int);
|
||||||
@@ -3876,6 +3871,12 @@ struct style_range *style_ranges_get_range(struct style_ranges *, u_int);
|
|||||||
/* spawn.c */
|
/* spawn.c */
|
||||||
struct winlink *spawn_window(struct spawn_context *, char **);
|
struct winlink *spawn_window(struct spawn_context *, char **);
|
||||||
struct window_pane *spawn_pane(struct spawn_context *, char **);
|
struct window_pane *spawn_pane(struct spawn_context *, char **);
|
||||||
|
typedef void (*spawn_finish_edit_cb)(char *, size_t, void *);
|
||||||
|
struct spawn_editor_state *spawn_editor(struct client *, const char *, size_t,
|
||||||
|
spawn_finish_edit_cb, void *);
|
||||||
|
void spawn_cancel_editor(struct spawn_editor_state *);
|
||||||
|
pid_t spawn_get_editor_pid(struct spawn_editor_state *);
|
||||||
|
void spawn_editor_finish(struct window_pane *);
|
||||||
|
|
||||||
/* regsub.c */
|
/* regsub.c */
|
||||||
char *regsub(const char *, const char *, const char *, int);
|
char *regsub(const char *, const char *, const char *, int);
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ struct window_buffer_modedata {
|
|||||||
struct cmd_find_state fs;
|
struct cmd_find_state fs;
|
||||||
|
|
||||||
struct mode_tree_data *data;
|
struct mode_tree_data *data;
|
||||||
|
struct spawn_editor_state *editor;
|
||||||
|
struct window_buffer_editdata *edit;
|
||||||
char *command;
|
char *command;
|
||||||
char *format;
|
char *format;
|
||||||
char *key_format;
|
char *key_format;
|
||||||
@@ -99,8 +101,12 @@ struct window_buffer_editdata {
|
|||||||
u_int wp_id;
|
u_int wp_id;
|
||||||
char *name;
|
char *name;
|
||||||
struct paste_buffer *pb;
|
struct paste_buffer *pb;
|
||||||
|
struct spawn_editor_state *editor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void window_buffer_finish_edit(struct window_buffer_editdata *);
|
||||||
|
static void window_buffer_draw_waiting(struct window_buffer_modedata *);
|
||||||
|
|
||||||
static enum sort_order window_buffer_order_seq[] = {
|
static enum sort_order window_buffer_order_seq[] = {
|
||||||
SORT_CREATION,
|
SORT_CREATION,
|
||||||
SORT_NAME,
|
SORT_NAME,
|
||||||
@@ -394,6 +400,11 @@ window_buffer_free(struct window_mode_entry *wme)
|
|||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (data->editor != NULL) {
|
||||||
|
spawn_cancel_editor(data->editor);
|
||||||
|
window_buffer_finish_edit(data->edit);
|
||||||
|
}
|
||||||
|
|
||||||
mode_tree_free(data->data);
|
mode_tree_free(data->data);
|
||||||
|
|
||||||
for (i = 0; i < data->item_size; i++)
|
for (i = 0; i < data->item_size; i++)
|
||||||
@@ -422,6 +433,7 @@ window_buffer_update(struct window_mode_entry *wme)
|
|||||||
|
|
||||||
mode_tree_build(data->data);
|
mode_tree_build(data->data);
|
||||||
mode_tree_draw(data->data);
|
mode_tree_draw(data->data);
|
||||||
|
window_buffer_draw_waiting(data);
|
||||||
data->wp->flags |= PANE_REDRAW;
|
data->wp->flags |= PANE_REDRAW;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,6 +478,49 @@ window_buffer_finish_edit(struct window_buffer_editdata *ed)
|
|||||||
free(ed);
|
free(ed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
window_buffer_draw_waiting(struct window_buffer_modedata *data)
|
||||||
|
{
|
||||||
|
struct screen_write_ctx ctx;
|
||||||
|
struct screen *s = data->wp->screen;
|
||||||
|
struct grid_cell gc;
|
||||||
|
char text[128];
|
||||||
|
u_int sx, sy, box_w, box_h, x, y, text_x;
|
||||||
|
size_t textlen;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
if (data->editor == NULL)
|
||||||
|
return;
|
||||||
|
sx = screen_size_x(s);
|
||||||
|
sy = screen_size_y(s);
|
||||||
|
if (sx == 0 || sy == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pid = spawn_get_editor_pid(data->editor);
|
||||||
|
if (pid == -1)
|
||||||
|
xsnprintf(text, sizeof text, "WAITING FOR EDITOR");
|
||||||
|
else
|
||||||
|
xsnprintf(text, sizeof text, "WAITING FOR EDITOR (PID %ld)",
|
||||||
|
(long)pid);
|
||||||
|
|
||||||
|
textlen = strlen(text);
|
||||||
|
box_w = textlen + 4;
|
||||||
|
box_h = 3;
|
||||||
|
if (sx < box_w || sy < box_h)
|
||||||
|
return;
|
||||||
|
x = (sx - box_w) / 2;
|
||||||
|
y = (sy - box_h) / 2;
|
||||||
|
text_x = x + (box_w - textlen) / 2;
|
||||||
|
|
||||||
|
memcpy(&gc, &grid_default_cell, sizeof gc);
|
||||||
|
screen_write_start(&ctx, s);
|
||||||
|
screen_write_cursormove(&ctx, x, y, 0);
|
||||||
|
screen_write_box(&ctx, box_w, box_h, BOX_LINES_DEFAULT, &gc, NULL);
|
||||||
|
screen_write_cursormove(&ctx, text_x, y + 1, 0);
|
||||||
|
screen_write_nputs(&ctx, box_w - 2, &gc, "%s", text);
|
||||||
|
screen_write_stop(&ctx);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
window_buffer_edit_close_cb(char *buf, size_t len, void *arg)
|
window_buffer_edit_close_cb(char *buf, size_t len, void *arg)
|
||||||
{
|
{
|
||||||
@@ -477,6 +532,18 @@ window_buffer_edit_close_cb(char *buf, size_t len, void *arg)
|
|||||||
struct window_buffer_modedata *data;
|
struct window_buffer_modedata *data;
|
||||||
struct window_mode_entry *wme;
|
struct window_mode_entry *wme;
|
||||||
|
|
||||||
|
wp = window_pane_find_by_id(ed->wp_id);
|
||||||
|
if (wp != NULL) {
|
||||||
|
wme = TAILQ_FIRST(&wp->modes);
|
||||||
|
if (wme != NULL && wme->mode == &window_buffer_mode) {
|
||||||
|
data = wme->data;
|
||||||
|
if (data->editor == ed->editor) {
|
||||||
|
data->editor = NULL;
|
||||||
|
data->edit = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (buf == NULL || len == 0) {
|
if (buf == NULL || len == 0) {
|
||||||
window_buffer_finish_edit(ed);
|
window_buffer_finish_edit(ed);
|
||||||
return;
|
return;
|
||||||
@@ -499,10 +566,11 @@ window_buffer_edit_close_cb(char *buf, size_t len, void *arg)
|
|||||||
wp = window_pane_find_by_id(ed->wp_id);
|
wp = window_pane_find_by_id(ed->wp_id);
|
||||||
if (wp != NULL) {
|
if (wp != NULL) {
|
||||||
wme = TAILQ_FIRST(&wp->modes);
|
wme = TAILQ_FIRST(&wp->modes);
|
||||||
if (wme->mode == &window_buffer_mode) {
|
if (wme != NULL && wme->mode == &window_buffer_mode) {
|
||||||
data = wme->data;
|
data = wme->data;
|
||||||
mode_tree_build(data->data);
|
mode_tree_build(data->data);
|
||||||
mode_tree_draw(data->data);
|
mode_tree_draw(data->data);
|
||||||
|
window_buffer_draw_waiting(data);
|
||||||
}
|
}
|
||||||
wp->flags |= PANE_REDRAW;
|
wp->flags |= PANE_REDRAW;
|
||||||
}
|
}
|
||||||
@@ -518,6 +586,8 @@ window_buffer_start_edit(struct window_buffer_modedata *data,
|
|||||||
size_t len;
|
size_t len;
|
||||||
struct window_buffer_editdata *ed;
|
struct window_buffer_editdata *ed;
|
||||||
|
|
||||||
|
if (data->editor != NULL)
|
||||||
|
return;
|
||||||
if ((pb = paste_get_name(item->name)) == NULL)
|
if ((pb = paste_get_name(item->name)) == NULL)
|
||||||
return;
|
return;
|
||||||
buf = paste_buffer_data(pb, &len);
|
buf = paste_buffer_data(pb, &len);
|
||||||
@@ -527,8 +597,13 @@ window_buffer_start_edit(struct window_buffer_modedata *data,
|
|||||||
ed->name = xstrdup(paste_buffer_name(pb));
|
ed->name = xstrdup(paste_buffer_name(pb));
|
||||||
ed->pb = pb;
|
ed->pb = pb;
|
||||||
|
|
||||||
if (popup_editor(c, buf, len, window_buffer_edit_close_cb, ed) != 0)
|
ed->editor = spawn_editor(c, buf, len, window_buffer_edit_close_cb, ed);
|
||||||
|
if (ed->editor == NULL)
|
||||||
window_buffer_finish_edit(ed);
|
window_buffer_finish_edit(ed);
|
||||||
|
else {
|
||||||
|
data->editor = ed->editor;
|
||||||
|
data->edit = ed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -546,6 +621,13 @@ window_buffer_key(struct window_mode_entry *wme, struct client *c,
|
|||||||
finished = 1;
|
finished = 1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
if (data->editor != NULL) {
|
||||||
|
if (key == 'q' || key == '\033' || key == '\003')
|
||||||
|
finished = 1;
|
||||||
|
else
|
||||||
|
finished = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
finished = mode_tree_key(mtd, c, &key, m, NULL, NULL);
|
finished = mode_tree_key(mtd, c, &key, m, NULL, NULL);
|
||||||
switch (key) {
|
switch (key) {
|
||||||
@@ -579,6 +661,7 @@ out:
|
|||||||
window_pane_reset_mode(wp);
|
window_pane_reset_mode(wp);
|
||||||
else {
|
else {
|
||||||
mode_tree_draw(mtd);
|
mode_tree_draw(mtd);
|
||||||
|
window_buffer_draw_waiting(data);
|
||||||
wp->flags |= PANE_REDRAW;
|
wp->flags |= PANE_REDRAW;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,6 +131,8 @@ window_visible_ranges(struct window_pane *base_wp, int px, int py, u_int width,
|
|||||||
|
|
||||||
for (i = 0; i < r->used; i++) {
|
for (i = 0; i < r->used; i++) {
|
||||||
ri = &r->ranges[i];
|
ri = &r->ranges[i];
|
||||||
|
if (ri->nx == 0)
|
||||||
|
continue;
|
||||||
if (no_border) {
|
if (no_border) {
|
||||||
lb = wp->xoff;
|
lb = wp->xoff;
|
||||||
rb = wp->xoff + (int)wp->sx - 1;
|
rb = wp->xoff + (int)wp->sx - 1;
|
||||||
@@ -159,6 +161,8 @@ window_visible_ranges(struct window_pane *base_wp, int px, int py, u_int width,
|
|||||||
rb = w->sx - 1;
|
rb = w->sx - 1;
|
||||||
else if (!no_border && rb > (int)w->sx)
|
else if (!no_border && rb > (int)w->sx)
|
||||||
rb = w->sx - 1;
|
rb = w->sx - 1;
|
||||||
|
if (lb > rb)
|
||||||
|
continue;
|
||||||
|
|
||||||
sx = ri->px;
|
sx = ri->px;
|
||||||
ex = sx + ri->nx - 1;
|
ex = sx + ri->nx - 1;
|
||||||
|
|||||||
3
window.c
3
window.c
@@ -388,6 +388,8 @@ window_pane_destroy_ready(struct window_pane *wp)
|
|||||||
*/
|
*/
|
||||||
if (wp->wait_item != NULL && (~wp->flags & PANE_STATUSREADY))
|
if (wp->wait_item != NULL && (~wp->flags & PANE_STATUSREADY))
|
||||||
return (0);
|
return (0);
|
||||||
|
if (wp->editor != NULL && (~wp->flags & PANE_STATUSREADY))
|
||||||
|
return (0);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1131,6 +1133,7 @@ static void
|
|||||||
window_pane_destroy(struct window_pane *wp)
|
window_pane_destroy(struct window_pane *wp)
|
||||||
{
|
{
|
||||||
window_pane_wait_finish(wp);
|
window_pane_wait_finish(wp);
|
||||||
|
spawn_editor_finish(wp);
|
||||||
|
|
||||||
window_pane_reset_mode_all(wp);
|
window_pane_reset_mode_all(wp);
|
||||||
free(wp->searchstr);
|
free(wp->searchstr);
|
||||||
|
|||||||
Reference in New Issue
Block a user