From 1c68c64874fdc6a8e54603c9c315efb715e85653 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Wed, 24 Feb 2021 13:51:36 -0500 Subject: :split-join --- command.c | 3 +++ command.h | 2 ++ main.c | 2 +- node.c | 39 +++++++++++++++++++++++++++++++++++++-- ted.cfg | 2 ++ 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/command.c b/command.c index e9ffd75..5ee0302 100644 --- a/command.c +++ b/command.c @@ -337,5 +337,8 @@ void command_execute(Ted *ted, Command c, i64 argument) { } } break; + case CMD_SPLIT_JOIN: + node_join(ted, node); + break; } } diff --git a/command.h b/command.h index a74f42a..a8efe35 100644 --- a/command.h +++ b/command.h @@ -74,6 +74,7 @@ ENUM_U16 { CMD_SPLIT_HORIZONTAL, CMD_SPLIT_VERTICAL, + CMD_SPLIT_JOIN, CMD_ESCAPE, // by default this is the escape key. closes menus, etc. @@ -145,6 +146,7 @@ static CommandName const command_names[CMD_COUNT] = { {"goto-line", CMD_GOTO_LINE}, {"split-horizontal", CMD_SPLIT_HORIZONTAL}, {"split-vertical", CMD_SPLIT_VERTICAL}, + {"split-join", CMD_SPLIT_JOIN}, {"escape", CMD_ESCAPE}, }; diff --git a/main.c b/main.c index e5b36c2..d7dbc3c 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,7 @@ // @TODO: -// - Ctrl+j = :join // - split depth limit // - resize split (i.e. change split_pos) +// - move tabs between nodes // - Windows installation // - on crash, output backtrace to log diff --git a/node.c b/node.c index 810b657..f2ac41f 100644 --- a/node.c +++ b/node.c @@ -34,6 +34,7 @@ static void node_free(Node *node) { // returns index of parent in ted->nodes, or -1 if this is the root node. static i32 node_parent(Ted *ted, u16 node_idx) { + assert(node_idx < TED_MAX_NODES && ted->nodes_used[node_idx]); for (u16 i = 0; i < TED_MAX_NODES; ++i) { if (ted->nodes_used[i]) { Node *node = &ted->nodes[i]; @@ -46,9 +47,44 @@ static i32 node_parent(Ted *ted, u16 node_idx) { return -1; } +// join this node with its sibling +static void node_join(Ted *ted, Node *node) { + i32 parent_idx = node_parent(ted, (u16)(node - ted->nodes)); + if (parent_idx >= 0) { + Node *parent = &ted->nodes[parent_idx]; + Node *a = &ted->nodes[parent->split_a]; + Node *b = &ted->nodes[parent->split_b]; + if (a->tabs && b->tabs) { + if (ted->active_node == a || ted->active_node == b) { + ted->active_node = parent; + } + arr_foreach_ptr(a->tabs, u16, tab) { + arr_add(parent->tabs, *tab); + } + arr_foreach_ptr(b->tabs, u16, tab) { + arr_add(parent->tabs, *tab); + } + if (parent->tabs) { + if (node == a) { + parent->active_tab = a->active_tab; + } else { + parent->active_tab = (u16)arr_len(a->tabs) + b->active_tab; + } + node_free(a); + node_free(b); + ted->nodes_used[parent->split_a] = false; + ted->nodes_used[parent->split_b] = false; + } + } + } +} + static void node_close(Ted *ted, u16 node_idx) { assert(node_idx < TED_MAX_NODES); assert(ted->nodes_used[node_idx]); + i32 parent_idx = node_parent(ted, node_idx); + ted->nodes_used[node_idx] = false; + Node *node = &ted->nodes[node_idx]; // delete all associated buffers @@ -58,9 +94,7 @@ static void node_close(Ted *ted, u16 node_idx) { } node_free(node); - ted->nodes_used[node_idx] = false; - i32 parent_idx = node_parent(ted, node_idx); if (parent_idx < 0) { // no parent; this must be the root node ted->active_node = NULL; @@ -90,6 +124,7 @@ static void node_close(Ted *ted, u16 node_idx) { } } + // close tab, WITHOUT checking for unsaved changes! // returns true if the node is still open static bool node_tab_close(Ted *ted, Node *node, u16 index) { diff --git a/ted.cfg b/ted.cfg index da4a1a3..1d4e64e 100644 --- a/ted.cfg +++ b/ted.cfg @@ -123,6 +123,8 @@ Ctrl+g = :goto-line Ctrl+/ = :split-horizontal Ctrl+Shift+/ = :split-vertical +# unsplit +Ctrl+j = :split-join Escape = :escape -- cgit v1.2.3