summaryrefslogtreecommitdiff
path: root/src/dged/window.c
diff options
context:
space:
mode:
authorAlbert Cervin <albert@acervin.com>2024-03-26 10:59:06 +0100
committerAlbert Cervin <albert@acervin.com>2024-03-26 10:59:06 +0100
commit1b888cc723792ec0e49c7e5aaa78c3c5486a95b9 (patch)
treeda0b4f6fcdf394b155938472a0ca0d100effb2ef /src/dged/window.c
parent5b3234f34fd081a3fe81c95bd55f4bfc853568a5 (diff)
downloaddged-1b888cc723792ec0e49c7e5aaa78c3c5486a95b9.tar.gz
dged-1b888cc723792ec0e49c7e5aaa78c3c5486a95b9.tar.xz
dged-1b888cc723792ec0e49c7e5aaa78c3c5486a95b9.zip
Implement kill-buffer command
Can be killed with the command `kill-buffer`, the shortcut `C-x k` or from the buffer menu.
Diffstat (limited to 'src/dged/window.c')
-rw-r--r--src/dged/window.c95
1 files changed, 83 insertions, 12 deletions
diff --git a/src/dged/window.c b/src/dged/window.c
index 8fcd51c..20cb22f 100644
--- a/src/dged/window.c
+++ b/src/dged/window.c
@@ -2,6 +2,7 @@
#include "btree.h"
#include "buffer.h"
#include "buffer_view.h"
+#include "buffers.h"
#include "command.h"
#include "display.h"
#include "minibuffer.h"
@@ -21,7 +22,8 @@ struct window {
uint32_t height;
enum window_type type;
struct buffer_view buffer_view;
- struct buffer *prev_buffer;
+ struct buffer_view prev_buffer_view;
+ bool has_prev_buffer_view;
struct command_list *commands;
uint32_t relline;
uint32_t relcol;
@@ -40,13 +42,52 @@ static struct window g_minibuffer_window;
static struct window g_popup_window = {0};
static bool g_popup_visible = false;
+static void buffer_removed(struct buffer *buffer, void *userdata) {
+ struct window_node *n = BINTREE_ROOT(&g_windows.windows);
+ BINTREE_FIRST(n);
+ while (n != NULL) {
+ struct window *w = &BINTREE_VALUE(n);
+ if (window_prev_buffer_view(w)->buffer == buffer) {
+ buffer_view_destroy(&w->prev_buffer_view);
+ w->has_prev_buffer_view = false;
+ }
+
+ if (window_buffer(w) == buffer) {
+ if (window_has_prev_buffer_view(w)) {
+ window_set_buffer(w, window_prev_buffer_view(w)->buffer);
+ buffer_view_destroy(&w->prev_buffer_view);
+ w->has_prev_buffer_view = false;
+ } else {
+ struct buffers *buffers = (struct buffers *)userdata;
+ struct buffer *b = buffers_find(buffers, "*messages*");
+
+ if (b != NULL) {
+ window_set_buffer(w, b);
+ } else {
+ b = buffers_first(buffers);
+
+ // if there are no more buffers, not sure what to do?
+ if (b != NULL) {
+ window_set_buffer(w, b);
+ }
+ }
+ buffer_view_destroy(&w->prev_buffer_view);
+ w->has_prev_buffer_view = false;
+ }
+ }
+
+ BINTREE_NEXT(n);
+ }
+}
+
void windows_init(uint32_t height, uint32_t width,
- struct buffer *initial_buffer, struct buffer *minibuffer) {
+ struct buffer *initial_buffer, struct buffer *minibuffer,
+ struct buffers *buffers) {
BINTREE_INIT(&g_windows.windows);
g_minibuffer_window = (struct window){
.buffer_view = buffer_view_create(minibuffer, false, false),
- .prev_buffer = NULL,
+ .has_prev_buffer_view = false,
.x = 0,
.y = height - 1,
.height = 1,
@@ -55,7 +96,7 @@ void windows_init(uint32_t height, uint32_t width,
struct window root_window = (struct window){
.buffer_view = buffer_view_create(initial_buffer, true, true),
- .prev_buffer = NULL,
+ .has_prev_buffer_view = false,
.height = height - 1,
.width = width,
.x = 0,
@@ -63,6 +104,8 @@ void windows_init(uint32_t height, uint32_t width,
};
BINTREE_SET_ROOT(&g_windows.windows, root_window);
g_windows.active = &BINTREE_VALUE(BINTREE_ROOT(&g_windows.windows));
+
+ buffers_add_remove_hook(buffers, buffer_removed, buffers);
}
static void window_tree_clear_sub(struct window_node *root_node) {
@@ -72,6 +115,9 @@ static void window_tree_clear_sub(struct window_node *root_node) {
struct window *w = &BINTREE_VALUE(n);
if (w->type == Window_Buffer) {
buffer_view_destroy(&w->buffer_view);
+ if (w->has_prev_buffer_view) {
+ buffer_view_destroy(&w->prev_buffer_view);
+ }
}
BINTREE_NEXT(n);
}
@@ -377,8 +423,23 @@ void window_set_buffer(struct window *window, struct buffer *buffer) {
void window_set_buffer_e(struct window *window, struct buffer *buffer,
bool modeline, bool line_numbers) {
if (buffer != window->buffer_view.buffer) {
- window->prev_buffer = window->buffer_view.buffer;
- buffer_view_destroy(&window->buffer_view);
+ if (window->has_prev_buffer_view) {
+
+ if (window->prev_buffer_view.buffer == buffer) {
+
+ struct buffer_view tmp = window->prev_buffer_view;
+ window->prev_buffer_view = window->buffer_view;
+ window->has_prev_buffer_view = true;
+ window->buffer_view = tmp;
+ return;
+
+ } else {
+ buffer_view_destroy(&window->prev_buffer_view);
+ }
+ }
+
+ window->prev_buffer_view = window->buffer_view;
+ window->has_prev_buffer_view = true;
window->buffer_view = buffer_view_create(buffer, modeline, line_numbers);
}
}
@@ -391,12 +452,12 @@ struct buffer_view *window_buffer_view(struct window *window) {
return &window->buffer_view;
}
-struct buffer *window_prev_buffer(struct window *window) {
- return window->prev_buffer;
+struct buffer_view *window_prev_buffer_view(struct window *window) {
+ return &window->prev_buffer_view;
}
-bool window_has_prev_buffer(struct window *window) {
- return window->prev_buffer != NULL;
+bool window_has_prev_buffer_view(struct window *window) {
+ return window->has_prev_buffer_view;
}
void window_close(struct window *window) {
@@ -417,6 +478,7 @@ void window_close(struct window *window) {
: BINTREE_RIGHT(target);
buffer_view_destroy(&window->buffer_view);
+ buffer_view_destroy(&window->prev_buffer_view);
BINTREE_REMOVE(to_delete);
BINTREE_FREE_NODE(to_delete);
@@ -454,6 +516,11 @@ void window_close_others(struct window *window) {
new_root.x = 0;
new_root.y = 0;
new_root.buffer_view = buffer_view_clone(&window->buffer_view);
+ new_root.has_prev_buffer_view = false;
+ if (window->has_prev_buffer_view) {
+ new_root.has_prev_buffer_view = true;
+ new_root.prev_buffer_view = buffer_view_clone(&window->prev_buffer_view);
+ }
new_root.width = BINTREE_VALUE(root).width;
new_root.height = BINTREE_VALUE(root).height;
@@ -495,7 +562,9 @@ void window_hsplit(struct window *window, struct window **new_window_a,
buffer_view_goto(&new_window.buffer_view,
(struct location){.line = w.buffer_view.dot.line,
.col = w.buffer_view.dot.col});
- new_window.prev_buffer = w.prev_buffer;
+ if (w.has_prev_buffer_view) {
+ new_window.prev_buffer_view = buffer_view_clone(&w.prev_buffer_view);
+ }
new_window.x = w.x;
new_window.y = w.y + w.height;
new_window.width = w.width;
@@ -539,7 +608,9 @@ void window_vsplit(struct window *window, struct window **new_window_a,
(struct location){.line = w.buffer_view.dot.line,
.col = w.buffer_view.dot.col});
- new_window.prev_buffer = w.prev_buffer;
+ if (w.has_prev_buffer_view) {
+ new_window.prev_buffer_view = buffer_view_clone(&w.prev_buffer_view);
+ }
new_window.x = w.x + w.width;
new_window.y = w.y;
new_window.width = parent.width - w.width;