summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c5
-rw-r--r--node.c53
-rw-r--r--ted.c1
-rw-r--r--ted.h1
4 files changed, 49 insertions, 11 deletions
diff --git a/main.c b/main.c
index 76b17a7..e5b36c2 100644
--- a/main.c
+++ b/main.c
@@ -1,5 +1,5 @@
// @TODO:
-// - get ctrl+w to work properly
+// - Ctrl+j = :join
// - split depth limit
// - resize split (i.e. change split_pos)
@@ -332,7 +332,6 @@ int main(int argc, char **argv) {
u16 node_index = (u16)ted_new_node(ted);
assert(node_index == 0);
Node *node = ted->active_node = &ted->nodes[node_index];
- ted->root = node;
node->tabs = NULL;
arr_add(node->tabs, 0);
@@ -611,7 +610,7 @@ int main(int argc, char **argv) {
if (ted->active_node) {
float const padding = settings->padding;
float x1 = padding, y = window_height-padding, x2 = window_width-padding;
- Node *node = ted->root;
+ Node *node = &ted->nodes[0];
if (ted->find) {
float y2 = y;
y -= find_menu_height(ted);
diff --git a/node.c b/node.c
index f30cb42..810b657 100644
--- a/node.c
+++ b/node.c
@@ -32,8 +32,24 @@ static void node_free(Node *node) {
memset(node, 0, sizeof *node);
}
-static void node_close(Ted *ted, Node *node) {
- // @TODO(split)
+// returns index of parent in ted->nodes, or -1 if this is the root node.
+static i32 node_parent(Ted *ted, u16 node_idx) {
+ for (u16 i = 0; i < TED_MAX_NODES; ++i) {
+ if (ted->nodes_used[i]) {
+ Node *node = &ted->nodes[i];
+ if (!node->tabs) {
+ if (node->split_a == node_idx || node->split_b == node_idx)
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+static void node_close(Ted *ted, u16 node_idx) {
+ assert(node_idx < TED_MAX_NODES);
+ assert(ted->nodes_used[node_idx]);
+ Node *node = &ted->nodes[node_idx];
// delete all associated buffers
arr_foreach_ptr(node->tabs, u16, tab) {
@@ -42,12 +58,35 @@ static void node_close(Ted *ted, Node *node) {
}
node_free(node);
+ ted->nodes_used[node_idx] = false;
- u16 node_index = (u16)(node - ted->nodes);
- assert(node_index < TED_MAX_NODES);
- ted->nodes_used[node_index] = false;
- if (ted->active_node == node) {
+ i32 parent_idx = node_parent(ted, node_idx);
+ if (parent_idx < 0) {
+ // no parent; this must be the root node
ted->active_node = NULL;
+ } else {
+ // turn parent from split node into tab node
+ Node *parent = &ted->nodes[parent_idx];
+ assert(!parent->tabs);
+ u16 other_side;
+ if (node_idx == parent->split_a) {
+ other_side = parent->split_b;
+ } else {
+ assert(node_idx == parent->split_b);
+ other_side = parent->split_a;
+ }
+ // replace parent with other side of split
+ *parent = ted->nodes[other_side];
+
+ ted->nodes_used[other_side] = false;
+ if (ted->active_node == node) {
+ Node *new_active_node = parent;
+ // make sure we don't set the active node to a split
+ while (!new_active_node->tabs)
+ new_active_node = &ted->nodes[new_active_node->split_a];
+ ted->active_node = new_active_node;
+ ted->active_buffer = &ted->buffers[ted->active_node->tabs[ted->active_node->active_tab]];
+ }
}
}
@@ -58,7 +97,7 @@ static bool node_tab_close(Ted *ted, Node *node, u16 index) {
assert(index < ntabs);
if (ntabs == 1) {
// only 1 tab left, just close the node
- node_close(ted, node);
+ node_close(ted, (u16)(node - ted->nodes));
return false;
} else {
u16 buffer_index = node->tabs[index];
diff --git a/ted.c b/ted.c
index e12ae0d..5ad3f82 100644
--- a/ted.c
+++ b/ted.c
@@ -119,6 +119,7 @@ static i32 ted_new_node(Ted *ted) {
bool *nodes_used = ted->nodes_used;
for (i32 i = 0; i < TED_MAX_NODES; ++i) {
if (!nodes_used[i]) {
+ memset(&ted->nodes[i], 0, sizeof ted->nodes[i]); // zero new node
nodes_used[i] = true;
return i;
}
diff --git a/ted.h b/ted.h
index 9f6c582..3c31ab0 100644
--- a/ted.h
+++ b/ted.h
@@ -236,7 +236,6 @@ typedef struct Ted {
// while a menu or something is open, there is no active buffer. when the menu is closed,
// the old active buffer needs to be restored. that's what this stores.
TextBuffer *prev_active_buffer;
- Node *root;
Node *active_node;
Settings settings;
float window_width, window_height;