Use a floating pane for the buffer mode editor instead of a popup.

This commit is contained in:
nicm
2026-06-19 18:37:10 +00:00
parent c93e2f2332
commit d04b1ffca5
4 changed files with 275 additions and 11 deletions

View File

@@ -87,6 +87,8 @@ struct window_buffer_modedata {
struct cmd_find_state fs;
struct mode_tree_data *data;
struct spawn_editor_state *editor;
struct window_buffer_editdata *edit;
char *command;
char *format;
char *key_format;
@@ -99,8 +101,12 @@ struct window_buffer_editdata {
u_int wp_id;
char *name;
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[] = {
SORT_CREATION,
SORT_NAME,
@@ -394,6 +400,11 @@ window_buffer_free(struct window_mode_entry *wme)
if (data == NULL)
return;
if (data->editor != NULL) {
spawn_cancel_editor(data->editor);
window_buffer_finish_edit(data->edit);
}
mode_tree_free(data->data);
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_draw(data->data);
window_buffer_draw_waiting(data);
data->wp->flags |= PANE_REDRAW;
}
@@ -466,6 +478,49 @@ window_buffer_finish_edit(struct window_buffer_editdata *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
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_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) {
window_buffer_finish_edit(ed);
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);
if (wp != NULL) {
wme = TAILQ_FIRST(&wp->modes);
if (wme->mode == &window_buffer_mode) {
if (wme != NULL && wme->mode == &window_buffer_mode) {
data = wme->data;
mode_tree_build(data->data);
mode_tree_draw(data->data);
window_buffer_draw_waiting(data);
}
wp->flags |= PANE_REDRAW;
}
@@ -518,6 +586,8 @@ window_buffer_start_edit(struct window_buffer_modedata *data,
size_t len;
struct window_buffer_editdata *ed;
if (data->editor != NULL)
return;
if ((pb = paste_get_name(item->name)) == NULL)
return;
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->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);
else {
data->editor = ed->editor;
data->edit = ed;
}
}
static void
@@ -546,6 +621,13 @@ window_buffer_key(struct window_mode_entry *wme, struct client *c,
finished = 1;
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);
switch (key) {
@@ -579,6 +661,7 @@ out:
window_pane_reset_mode(wp);
else {
mode_tree_draw(mtd);
window_buffer_draw_waiting(data);
wp->flags |= PANE_REDRAW;
}
}