From 52fd5e0c95da236fd14682ed8a7cfa34afbab2c0 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Sun, 28 Feb 2021 16:35:38 -0500 Subject: set active_node to NULL when line buffer is active --- command.c | 8 ++--- find.c | 4 +-- main.c | 106 ++++++++++++++++++++++++++++++++++++-------------------------- menu.c | 17 +++++----- node.c | 6 ++-- tags.c | 2 +- ted.c | 67 ++++++++++++++++++++++++--------------- 7 files changed, 121 insertions(+), 89 deletions(-) diff --git a/command.c b/command.c index 05f7c48..91819e4 100644 --- a/command.c +++ b/command.c @@ -99,7 +99,7 @@ void command_execute(Ted *ted, Command c, i64 argument) { case CMD_TAB: if (ted->replace && buffer == &ted->find_buffer) { - buffer = ted->active_buffer = &ted->replace_buffer; + ted_switch_to_buffer(ted, &ted->replace_buffer); buffer_select_all(buffer); } else if (buffer) { if (buffer->selection) @@ -110,7 +110,7 @@ void command_execute(Ted *ted, Command c, i64 argument) { break; case CMD_BACKTAB: if (ted->replace && buffer == &ted->replace_buffer) { - buffer = ted->active_buffer = &ted->find_buffer; + ted_switch_to_buffer(ted, &ted->find_buffer); buffer_select_all(buffer); } else if (buffer) { if (buffer->selection) @@ -315,10 +315,10 @@ void command_execute(Ted *ted, Command c, i64 argument) { } break; case CMD_SPLIT_JOIN: - node_join(ted, node); + if (node) node_join(ted, node); break; case CMD_SPLIT_SWAP: - node_split_swap(ted); + if (node) node_split_swap(ted); break; } } diff --git a/find.c b/find.c index 9298f53..509f1ac 100644 --- a/find.c +++ b/find.c @@ -429,7 +429,7 @@ static void find_menu_frame(Ted *ted, float x1, float y1, float x2, float y2) { static void find_open(Ted *ted, bool replace) { if (!ted->find && ted->active_buffer) { ted->prev_active_buffer = ted->active_buffer; - ted->active_buffer = &ted->find_buffer; + ted_switch_to_buffer(ted, &ted->find_buffer); ted->find = true; buffer_select_all(ted->active_buffer); } @@ -441,6 +441,6 @@ static void find_open(Ted *ted, bool replace) { static void find_close(Ted *ted) { ted->find = false; - ted->active_buffer = ted->prev_active_buffer; + ted_switch_to_buffer(ted, ted->prev_active_buffer); find_free_pattern(ted); } diff --git a/main.c b/main.c index 1bf3612..6a03b82 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,8 @@ // @TODO: -// - fix: ctrl+f something, then switch to another tab (hl rects still showing up) +// - fix: +// ctrl+f something, then switch to another tab (hl rects still showing up) +// ctrl+f something, then change buffer (e.g. make sure replace doesn't do something bad) +// - refresh find results by pressing Enter in find/replace buffer // - Windows installation // - on crash, output backtrace to log @@ -114,6 +117,51 @@ static void ted_update_window_dimensions(Ted *ted) { gl_window_height = ted->window_height = (float)h; } +// returns true if the buffer "used" this event +static bool handle_buffer_click(Ted *ted, TextBuffer *buffer, v2 click, u8 times) { + BufferPos buffer_pos; + if (buffer_pixels_to_pos(buffer, click, &buffer_pos)) { + // user clicked on buffer + if (!ted->menu) { + ted_switch_to_buffer(ted, buffer); + } + if (buffer == ted->active_buffer) { + switch (ted->key_modifier) { + case KEY_MODIFIER_SHIFT: + // select to position + buffer_select_to_pos(buffer, buffer_pos); + break; + case KEY_MODIFIER_CTRL: { + buffer_cursor_move_to_pos(buffer, buffer_pos); + String32 word = buffer_word_at_cursor(buffer); + if (word.len) { + char *tag = str32_to_utf8_cstr(word); + if (tag) { + tag_goto(buffer->ted, tag); + free(tag); + } + } + } break; + case 0: + buffer_cursor_move_to_pos(buffer, buffer_pos); + switch ((times - 1) % 3) { + case 0: break; // single-click + case 1: // double-click: select word + buffer_select_word(buffer); + break; + case 2: // triple-click: select line + buffer_select_line(buffer); + break; + } + ted->drag_buffer = buffer; + break; + } + return true; + } + } + return false; +} + #if _WIN32 INT WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow) { @@ -326,13 +374,14 @@ int main(int argc, char **argv) { assert(buffer_index == 1); TextBuffer *buffer = &ted->buffers[buffer_index]; buffer_create(buffer, ted); - ted->active_buffer = buffer; u16 node_index = (u16)ted_new_node(ted); assert(node_index == 0); - Node *node = ted->active_node = &ted->nodes[node_index]; + Node *node = &ted->nodes[node_index]; node->tabs = NULL; arr_add(node->tabs, buffer_index); + ted_switch_to_buffer(ted, buffer); + char path[TED_PATH_MAX]; if (starting_filename) { @@ -440,51 +489,18 @@ int main(int argc, char **argv) { Node *node = &ted->nodes[i]; if (node->tabs) { buffer = &ted->buffers[node->tabs[node->active_tab]]; - - BufferPos buffer_pos; - if (buffer_pixels_to_pos(buffer, pos, &buffer_pos)) { - // user clicked on buffer - if (!ted->menu) { - ted->active_buffer = buffer; - ted->active_node = node; - } - if (buffer == ted->active_buffer) { - add = false; - switch (ted->key_modifier) { - case KEY_MODIFIER_SHIFT: - // select to position - buffer_select_to_pos(buffer, buffer_pos); - break; - case KEY_MODIFIER_CTRL: { - buffer_cursor_move_to_pos(buffer, buffer_pos); - String32 word = buffer_word_at_cursor(buffer); - if (word.len) { - char *tag = str32_to_utf8_cstr(word); - if (tag) { - tag_goto(buffer->ted, tag); - free(tag); - } - } - } break; - case 0: - buffer_cursor_move_to_pos(buffer, buffer_pos); - switch ((times - 1) % 3) { - case 0: break; // single-click - case 1: // double-click: select word - buffer_select_word(buffer); - break; - case 2: // triple-click: select line - buffer_select_line(buffer); - break; - } - ted->drag_buffer = buffer; - break; - } - } + if (handle_buffer_click(ted, buffer, pos, times)) { + add = false; + break; } } } } + if (ted->find) { + add = add && !handle_buffer_click(ted, &ted->find_buffer, pos, times); + if (ted->replace) + add = add && !handle_buffer_click(ted, &ted->replace_buffer, pos, times); + } if (add) { ted->mouse_clicks[button][ted->nmouse_clicks[button]] = pos; ted->mouse_click_times[button][ted->nmouse_clicks[button]] = times; @@ -626,7 +642,7 @@ int main(int argc, char **argv) { strcpy(ted->window_title, "ted"); - if (ted->active_node) { + if (ted_anything_open(ted)) { float const padding = settings->padding; float x1 = padding, y = window_height-padding, x2 = window_width-padding; Node *node = &ted->nodes[0]; diff --git a/menu.c b/menu.c index 96c2ebc..19053ab 100644 --- a/menu.c +++ b/menu.c @@ -1,5 +1,6 @@ static void menu_close(Ted *ted) { - TextBuffer *buffer = ted->active_buffer = ted->prev_active_buffer; + ted_switch_to_buffer(ted, ted->prev_active_buffer); + TextBuffer *buffer = ted->active_buffer; ted->prev_active_buffer = NULL; if (buffer) { buffer->scroll_x = ted->prev_active_buffer_scroll.x; @@ -39,17 +40,17 @@ static void menu_open(Ted *ted, Menu menu) { if (prev_buf) ted->prev_active_buffer_scroll = V2D(prev_buf->scroll_x, prev_buf->scroll_y); - ted->active_buffer = NULL; + ted_switch_to_buffer(ted, NULL); *ted->warn_overwrite = 0; // clear warn_overwrite buffer_clear(&ted->line_buffer); switch (menu) { case MENU_NONE: assert(0); break; case MENU_OPEN: - ted->active_buffer = &ted->line_buffer; + ted_switch_to_buffer(ted, &ted->line_buffer); ted->file_selector.create_menu = false; break; case MENU_SAVE_AS: - ted->active_buffer = &ted->line_buffer; + ted_switch_to_buffer(ted, &ted->line_buffer); ted->file_selector.create_menu = true; break; case MENU_WARN_UNSAVED: @@ -63,7 +64,7 @@ static void menu_open(Ted *ted, Menu menu) { tag_selector_open(ted); break; case MENU_GOTO_LINE: - ted->active_buffer = &ted->line_buffer; + ted_switch_to_buffer(ted, &ted->line_buffer); break; } } @@ -72,7 +73,7 @@ static void menu_escape(Ted *ted) { if (*ted->warn_overwrite) { // just close "are you sure you want to overwrite?" *ted->warn_overwrite = 0; - ted->active_buffer = &ted->line_buffer; + ted_switch_to_buffer(ted, &ted->line_buffer); } else { menu_close(ted); } @@ -117,7 +118,7 @@ static void menu_update(Ted *ted) { case POPUP_NO: // back to the file selector *ted->warn_overwrite = '\0'; - ted->active_buffer = &ted->line_buffer; + ted_switch_to_buffer(ted, &ted->line_buffer); break; case POPUP_CANCEL: // close "save as" menu @@ -132,7 +133,7 @@ static void menu_update(Ted *ted) { if (fs_path_type(selected_file) != FS_NON_EXISTENT) { // file already exists! warn about overwriting it. strbuf_cpy(ted->warn_overwrite, selected_file); - ted->active_buffer = NULL; + ted_switch_to_buffer(ted, NULL); } else { // create the new file. buffer_save_as(buffer, selected_file); diff --git a/node.c b/node.c index 3a404cb..e6a2f97 100644 --- a/node.c +++ b/node.c @@ -4,7 +4,7 @@ static void node_switch_to_tab(Ted *ted, Node *node, u16 new_tab_index) { // switch active buffer assert(node->tabs); u16 buffer_idx = node->tabs[new_tab_index]; - ted->active_buffer = &ted->buffers[buffer_idx]; + ted_switch_to_buffer(ted, &ted->buffers[buffer_idx]); } } @@ -236,7 +236,7 @@ static void node_frame(Ted *ted, Node *node, Rect r) { ted->dragging_tab_node = NULL; // stop dragging // switch to this buffer - ted_switch_to_buffer(ted, tab); + ted_switch_to_buffer(ted, &ted->buffers[tab]); } } } @@ -252,7 +252,7 @@ static void node_frame(Ted *ted, Node *node, Rect r) { // close that tab if (buffer_unsaved_changes(buffer)) { // make sure unsaved changes dialog is opened - ted_switch_to_buffer(ted, buffer_idx); + ted_switch_to_buffer(ted, buffer); command_execute(ted, CMD_TAB_CLOSE, 1); } else { if (!node_tab_close(ted, node, tab_index)) { diff --git a/tags.c b/tags.c index 4412533..119a510 100644 --- a/tags.c +++ b/tags.c @@ -194,7 +194,7 @@ static void tag_selector_open(Ted *ted) { arr_add(ted->tag_selector_entries, strn_dup(line, len)); } } - ted->active_buffer = &ted->line_buffer; + ted_switch_to_buffer(ted, &ted->line_buffer); buffer_select_all(ted->active_buffer); ted->tag_selector.cursor = 0; diff --git a/ted.c b/ted.c index 17f2205..049ed92 100644 --- a/ted.c +++ b/ted.c @@ -22,6 +22,7 @@ void ted_clearerr(Ted *ted) { ted->error[0] = '\0'; } + static void ted_out_of_mem(Ted *ted) { ted_seterr(ted, "Out of memory."); } @@ -91,6 +92,33 @@ static void ted_load_fonts(Ted *ted) { ted_load_font(ted, "assets/font-bold.ttf", &ted->font_bold); } +// sets the active buffer to this buffer, and updates active_node, etc. accordingly +// you can pass NULL to buffer to make it so no buffer is active. +static void ted_switch_to_buffer(Ted *ted, TextBuffer *buffer) { + ted->active_buffer = buffer; + if (buffer >= ted->buffers && buffer < ted->buffers + TED_MAX_BUFFERS) { + u16 idx = (u16)(buffer - ted->buffers); + // now we need to figure out where this buffer is + bool *nodes_used = ted->nodes_used; + for (u16 i = 0; i < TED_MAX_NODES; ++i) { + if (nodes_used[i]) { + Node *node = &ted->nodes[i]; + arr_foreach_ptr(node->tabs, u16, tab) { + if (idx == *tab) { + node->active_tab = (u16)(tab - node->tabs); + ted->active_node = node; + return; + } + } + } + } + assert(0); + } else { + ted->active_node = NULL; + } +} + + // returns the index of an available buffer, or -1 if none are available static i32 ted_new_buffer(Ted *ted) { bool *buffers_used = ted->buffers_used; @@ -110,7 +138,7 @@ static i32 ted_new_buffer(Ted *ted) { static void ted_delete_buffer(Ted *ted, u16 index) { TextBuffer *buffer = &ted->buffers[index]; if (buffer == ted->active_buffer) - ted->active_buffer = NULL; // make sure we don't set the active buffer to something invalid + ted_switch_to_buffer(ted, NULL); // make sure we don't set the active buffer to something invalid buffer_free(buffer); ted->buffers_used[index] = false; } @@ -132,9 +160,8 @@ static i32 ted_new_node(Ted *ted) { // switch to this node static void ted_node_switch(Ted *ted, Node *node) { - ted->active_node = node; assert(node->tabs); - ted->active_buffer = &ted->buffers[node->tabs[node->active_tab]]; + ted_switch_to_buffer(ted, &ted->buffers[node->tabs[node->active_tab]]); } static bool node_tab_close(Ted *ted, Node *node, u16 index); @@ -159,10 +186,10 @@ static Status ted_open_buffer(Ted *ted, u16 *buffer_idx, u16 *tab) { if (arr_len(node->tabs) < TED_MAX_TABS) { arr_add(node->tabs, (u16)new_buffer_index); TextBuffer *new_buffer = &ted->buffers[new_buffer_index]; - ted->active_buffer = new_buffer; node->active_tab = (u16)(arr_len(node->tabs) - 1); *buffer_idx = (u16)new_buffer_index; *tab = node->active_tab; + ted_switch_to_buffer(ted, new_buffer); return true; } else { ted_seterr(ted, "Too many tabs."); @@ -174,26 +201,6 @@ static Status ted_open_buffer(Ted *ted, u16 *buffer_idx, u16 *tab) { } } -// sets the active buffer to this buffer, and updates active_node, etc. accordingly -static void ted_switch_to_buffer(Ted *ted, u16 buffer_idx) { - ted->active_buffer = &ted->buffers[buffer_idx]; - // now we need to figure out where this buffer is - bool *nodes_used = ted->nodes_used; - for (u16 i = 0; i < TED_MAX_NODES; ++i) { - if (nodes_used[i]) { - Node *node = &ted->nodes[i]; - arr_foreach_ptr(node->tabs, u16, tab) { - if (buffer_idx == *tab) { - node->active_tab = (u16)(tab - node->tabs); - ted->active_node = node; - return; - } - } - } - } - assert(0); -} - // Returns true on success static bool ted_open_file(Ted *ted, char const *filename) { @@ -204,7 +211,7 @@ static bool ted_open_file(Ted *ted, char const *filename) { if (buffers_used[i]) { if (streq(filename, buffer_get_filename(&buffers[i]))) { buffer_reload(&buffers[i]); // make sure buffer is up to date with the file - ted_switch_to_buffer(ted, i); + ted_switch_to_buffer(ted, &buffers[i]); return true; } } @@ -259,7 +266,7 @@ static bool ted_save_all(Ted *ted) { TextBuffer *buffer = &ted->buffers[i]; if (buffer_unsaved_changes(buffer)) { if (buffer->filename && buffer_is_untitled(buffer)) { - ted_switch_to_buffer(ted, i); + ted_switch_to_buffer(ted, buffer); menu_open(ted, MENU_SAVE_AS); success = false; // we haven't saved this buffer yet; we've just opened the "save as" menu. break; @@ -276,3 +283,11 @@ static bool ted_save_all(Ted *ted) { static void ted_full_path(Ted *ted, char const *relpath, char *abspath, size_t abspath_size) { path_full(ted->cwd, relpath, abspath, abspath_size); } + +// are any nodes open? +static bool ted_anything_open(Ted *ted) { + for (uint i = 0; i < TED_MAX_NODES; ++i) + if (ted->nodes_used[i]) + return true; + return false; +} -- cgit v1.2.3