aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ui-curses.c31
-rw-r--r--ui.h1
-rw-r--r--vis-cmds.c6
-rw-r--r--vis.c29
-rw-r--r--vis.h2
5 files changed, 68 insertions, 1 deletions
diff --git a/ui-curses.c b/ui-curses.c
index d335995..f5b1194 100644
--- a/ui-curses.c
+++ b/ui-curses.c
@@ -929,6 +929,36 @@ static enum UiOption ui_window_options_get(UiWin *w) {
return win->options;
}
+static void ui_window_swap(UiWin *aw, UiWin *bw) {
+ UiCursesWin *a = (UiCursesWin*)aw;
+ UiCursesWin *b = (UiCursesWin*)bw;
+ if (a == b || !a || !b)
+ return;
+ UiCurses *ui = a->ui;
+ UiCursesWin *tmp = a->next;
+ a->next = b->next;
+ b->next = tmp;
+ if (a->next)
+ a->next->prev = a;
+ if (b->next)
+ b->next->prev = b;
+ tmp = a->prev;
+ a->prev = b->prev;
+ b->prev = tmp;
+ if (a->prev)
+ a->prev->next = a;
+ if (b->prev)
+ b->prev->next = b;
+ if (ui->windows == a)
+ ui->windows = b;
+ else if (ui->windows == b)
+ ui->windows = a;
+ if (ui->selwin == a)
+ ui_window_focus(bw);
+ else if (ui->selwin == b)
+ ui_window_focus(aw);
+}
+
static UiWin *ui_window_new(Ui *ui, View *view, File *file, enum UiOption options) {
UiCurses *uic = (UiCurses*)ui;
UiCursesWin *win = calloc(1, sizeof(UiCursesWin));
@@ -1115,6 +1145,7 @@ Ui *ui_curses_new(void) {
.window_new = ui_window_new,
.window_free = ui_window_free,
.window_focus = ui_window_focus,
+ .window_swap = ui_window_swap,
.draw = ui_draw,
.redraw = ui_redraw,
.arrange = ui_arrange,
diff --git a/ui.h b/ui.h
index 2e471e9..de1b948 100644
--- a/ui.h
+++ b/ui.h
@@ -52,6 +52,7 @@ struct Ui {
UiWin* (*window_new)(Ui*, View*, File*, enum UiOption);
void (*window_free)(UiWin*);
void (*window_focus)(UiWin*);
+ void (*window_swap)(UiWin*, UiWin*);
void (*die)(Ui*, const char *msg, va_list ap) __attribute__((noreturn));
void (*info)(Ui*, const char *msg, va_list ap);
void (*info_hide)(Ui*);
diff --git a/vis-cmds.c b/vis-cmds.c
index 2455f52..2277ffe 100644
--- a/vis-cmds.c
+++ b/vis-cmds.c
@@ -319,8 +319,12 @@ static bool cmd_edit(Vis *vis, Win *win, Command *cmd, const char *argv[], Curso
return vis_window_reload(oldwin);
if (!openfiles(vis, &argv[1]))
return false;
- if (vis->win != oldwin)
+ if (vis->win != oldwin) {
+ Win *newwin = vis->win;
+ vis_window_swap(oldwin, newwin);
vis_window_close(oldwin);
+ vis_window_focus(newwin);
+ }
return vis->win != oldwin;
}
diff --git a/vis.c b/vis.c
index e1f14ff..730763b 100644
--- a/vis.c
+++ b/vis.c
@@ -292,6 +292,35 @@ bool vis_window_closable(Win *win) {
return win->file->refcount > 1;
}
+void vis_window_swap(Win *a, Win *b) {
+ if (a == b || !a || !b)
+ return;
+ Vis *vis = a->vis;
+ Win *tmp = a->next;
+ a->next = b->next;
+ b->next = tmp;
+ if (a->next)
+ a->next->prev = a;
+ if (b->next)
+ b->next->prev = b;
+ tmp = a->prev;
+ a->prev = b->prev;
+ b->prev = tmp;
+ if (a->prev)
+ a->prev->next = a;
+ if (b->prev)
+ b->prev->next = b;
+ if (vis->windows == a)
+ vis->windows = b;
+ else if (vis->windows == b)
+ vis->windows = a;
+ vis->ui->window_swap(a->ui, b->ui);
+ if (vis->win == a)
+ vis_window_focus(b);
+ else if (vis->win == b)
+ vis_window_focus(a);
+}
+
void vis_window_close(Win *win) {
Vis *vis = win->vis;
if (vis->event && vis->event->win_close)
diff --git a/vis.h b/vis.h
index d0486cc..5e7f338 100644
--- a/vis.h
+++ b/vis.h
@@ -83,6 +83,8 @@ void vis_window_next(Vis*);
void vis_window_prev(Vis*);
/* change currently focused window, receiving user input */
void vis_window_focus(Win*);
+/* swap location of two windows */
+void vis_window_swap(Win*, Win*);
/* display a user prompt with a certain title and default text */
void vis_prompt_show(Vis*, const char *title);