summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--command.c8
-rw-r--r--find.c4
-rw-r--r--main.c106
-rw-r--r--menu.c17
-rw-r--r--node.c6
-rw-r--r--tags.c2
-rw-r--r--ted.c67
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;
+}