summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2023-08-06 10:59:07 -0400
committerpommicket <pommicket@gmail.com>2023-08-06 10:59:07 -0400
commit413e8f4ba1c5937de40f6366a88c26f540cbb222 (patch)
tree2e4240cfd72bdd23c5ee85e5a94e97717af95a45
parent5891bf8f920be9cfa40cc03e86c16e6406943c20 (diff)
new menu system all done
-rw-r--r--ide-definitions.c21
-rw-r--r--ide-rename-symbol.c93
-rw-r--r--main.c4
-rw-r--r--menu.c199
-rw-r--r--ted-internal.h2
-rw-r--r--ted.h9
-rw-r--r--util.c28
-rw-r--r--util.h10
8 files changed, 202 insertions, 164 deletions
diff --git a/ide-definitions.c b/ide-definitions.c
index c37ae69..ea268e2 100644
--- a/ide-definitions.c
+++ b/ide-definitions.c
@@ -261,7 +261,7 @@ void definitions_send_request_if_needed(Ted *ted) {
defs->last_request_query = query;
}
-void definitions_selector_open(Ted *ted) {
+static void definitions_selector_open(Ted *ted) {
Definitions *defs = &ted->definitions;
definitions_clear_entries(defs);
LSP *lsp = ted->prev_active_buffer
@@ -279,15 +279,16 @@ void definitions_selector_open(Ted *ted) {
}
-void definitions_selector_close(Ted *ted) {
+static bool definitions_selector_close(Ted *ted) {
Definitions *defs = &ted->definitions;
definitions_clear_entries(defs);
ted_cancel_lsp_request(ted, &defs->last_request);
free(defs->last_request_query);
defs->last_request_query = NULL;
+ return true;
}
-void definitions_selector_update(Ted *ted) {
+static void definitions_selector_update(Ted *ted) {
Definitions *defs = &ted->definitions;
Selector *sel = &defs->selector;
sel->enable_cursor = true;
@@ -328,9 +329,21 @@ void definitions_selector_update(Ted *ted) {
}
}
-void definitions_selector_render(Ted *ted, Rect bounds) {
+static void definitions_selector_render(Ted *ted) {
+ Rect bounds = selection_menu_render_bg(ted);
Definitions *defs = &ted->definitions;
Selector *sel = &defs->selector;
sel->bounds = bounds;
selector_render(ted, sel);
}
+
+void definitions_init(Ted *ted) {
+ MenuInfo info = {
+ .open = definitions_selector_open,
+ .close = definitions_selector_close,
+ .render = definitions_selector_render,
+ .update = definitions_selector_update,
+ };
+ strbuf_cpy(info.name, MENU_GOTO_DEFINITION);
+ menu_register(ted, &info);
+}
diff --git a/ide-rename-symbol.c b/ide-rename-symbol.c
index b3ef52b..7d1e2ad 100644
--- a/ide-rename-symbol.c
+++ b/ide-rename-symbol.c
@@ -4,10 +4,6 @@ struct RenameSymbol {
LSPServerRequestID request_id;
};
-void rename_symbol_init(Ted *ted) {
- ted->rename_symbol = calloc(1, sizeof *ted->rename_symbol);
-}
-
void rename_symbol_quit(Ted *ted) {
rename_symbol_clear(ted);
free(ted->rename_symbol);
@@ -31,10 +27,6 @@ void rename_symbol_at_cursor(Ted *ted, TextBuffer *buffer, const char *new_name)
}
-bool rename_symbol_is_loading(Ted *ted) {
- return ted->rename_symbol->request_id.id != 0;
-}
-
void rename_symbol_clear(Ted *ted) {
RenameSymbol *rs = ted->rename_symbol;
ted_cancel_lsp_request(ted, &rs->request_id);
@@ -48,6 +40,79 @@ void rename_symbol_frame(Ted *ted) {
}
}
+static void rename_symbol_menu_open(Ted *ted) {
+ ted_switch_to_buffer(ted, &ted->line_buffer);
+}
+
+static void rename_symbol_menu_update(Ted *ted) {
+ TextBuffer *line_buffer = &ted->line_buffer;
+ if (line_buffer->line_buffer_submitted) {
+ char *new_name = str32_to_utf8_cstr(buffer_get_line(line_buffer, 0));
+ rename_symbol_at_cursor(ted, ted->prev_active_buffer, new_name);
+ free(new_name);
+ }
+}
+
+static void rename_symbol_menu_render(Ted *ted) {
+ RenameSymbol *rs = ted->rename_symbol;
+ // highlight symbol
+ TextBuffer *buffer = ted->prev_active_buffer;
+ if (!buffer) {
+ menu_close(ted);
+ return;
+ }
+ if (rs->request_id.id) {
+ // already entered a new name
+ return;
+ }
+ const Settings *settings = buffer_settings(buffer);
+ const float padding = settings->padding;
+ const u32 *colors = settings->colors;
+ const float line_buffer_height = ted_line_buffer_height(ted);
+
+ u32 sym_start=0, sym_end=0;
+ BufferPos cursor_pos = buffer->cursor_pos;
+ buffer_word_span_at_pos(buffer, cursor_pos, &sym_start, &sym_end);
+ BufferPos bpos0 = {
+ .line = cursor_pos.line,
+ .index = sym_start
+ };
+ BufferPos bpos1 = {
+ .line = cursor_pos.line,
+ .index = sym_end
+ };
+ // symbol should span from pos0 to pos1
+ vec2 p0 = buffer_pos_to_pixels(buffer, bpos0);
+ vec2 p1 = buffer_pos_to_pixels(buffer, bpos1);
+ p1.y += text_font_char_height(buffer_font(buffer));
+ Rect highlight = rect_endpoints(p0, p1);
+ gl_geometry_rect_border(highlight, settings->border_thickness, colors[COLOR_BORDER]);
+ gl_geometry_rect(highlight, colors[COLOR_HOVER_HL]);
+
+ const float width = ted_get_menu_width(ted);
+ const float height = line_buffer_height + 2 * padding;
+ Rect bounds = {
+ .pos = {(ted->window_width - width) / 2, padding},
+ .size = {width, height},
+ };
+ gl_geometry_rect(bounds, colors[COLOR_MENU_BG]);
+ gl_geometry_rect_border(bounds, settings->border_thickness, colors[COLOR_BORDER]);
+ gl_geometry_draw();
+ bounds = rect_shrink(bounds, padding);
+ const char *text = "Rename symbol to...";
+ text_utf8(ted->font_bold, text, bounds.pos.x, bounds.pos.y, colors[COLOR_TEXT]);
+ bounds = rect_shrink_left(bounds, text_get_size_vec2(ted->font_bold, text).x + padding);
+ text_render(ted->font_bold);
+
+ buffer_render(&ted->line_buffer, bounds);
+}
+
+static bool rename_symbol_menu_close(Ted *ted) {
+ rename_symbol_clear(ted);
+ buffer_clear(&ted->line_buffer);
+ return true;
+}
+
void rename_symbol_process_lsp_response(Ted *ted, const LSPResponse *response) {
RenameSymbol *rs = ted->rename_symbol;
if (response->request.type != LSP_REQUEST_RENAME
@@ -125,3 +190,15 @@ void rename_symbol_process_lsp_response(Ted *ted, const LSPResponse *response) {
if (menu_is_open(ted, MENU_RENAME_SYMBOL))
menu_close(ted);
}
+
+void rename_symbol_init(Ted *ted) {
+ ted->rename_symbol = calloc(1, sizeof *ted->rename_symbol);
+ MenuInfo menu = {
+ .open = rename_symbol_menu_open,
+ .close = rename_symbol_menu_close,
+ .update = rename_symbol_menu_update,
+ .render = rename_symbol_menu_render,
+ };
+ strbuf_cpy(menu.name, MENU_RENAME_SYMBOL);
+ menu_register(ted, &menu);
+}
diff --git a/main.c b/main.c
index 24a775e..5728bf1 100644
--- a/main.c
+++ b/main.c
@@ -1,8 +1,6 @@
/*
TODO:
-- rework menus
- deal with really long paths in file menus
-- internalize Autocomplete, SignatureHelp, etc.
FUTURE FEATURES:
- autodetect indentation (tabs vs spaces)
@@ -506,6 +504,7 @@ int main(int argc, char **argv) {
gl_geometry_init();
text_init();
menu_init(ted);
+ definitions_init(ted);
autocomplete_init(ted);
signature_help_init(ted);
usages_init(ted);
@@ -1228,7 +1227,6 @@ int main(int argc, char **argv) {
SDL_GL_DeleteContext(glctx);
SDL_DestroyWindow(window);
SDL_Quit();
- definitions_selector_close(ted);
for (u16 i = 0; i < TED_MAX_BUFFERS; ++i)
if (ted->buffers_used[i])
buffer_free(&ted->buffers[i]);
diff --git a/menu.c b/menu.c
index 8facbc5..b658086 100644
--- a/menu.c
+++ b/menu.c
@@ -20,11 +20,10 @@ void menu_close(Ted *ted) {
if (!menu_is_any_open(ted))
return;
const MenuInfo *menu = &ted->all_menus[ted->menu_open_idx];
- bool will_close = true;
- if (menu->close)
- will_close = menu->close(ted);
- if (!will_close)
- return;
+ if (menu->close) {
+ if (!menu->close(ted))
+ return;
+ }
ted_switch_to_buffer(ted, ted->prev_active_buffer);
TextBuffer *buffer = ted->active_buffer;
@@ -33,25 +32,14 @@ void menu_close(Ted *ted) {
buffer->scroll_x = ted->prev_active_buffer_scroll.x;
buffer->scroll_y = ted->prev_active_buffer_scroll.y;
}
- /*
- switch (ted->menu) {
- case MENU_GOTO_DEFINITION:
- definitions_selector_close(ted);
- break;
- case MENU_SHELL:
- buffer_clear(&ted->line_buffer);
- break;
- case MENU_RENAME_SYMBOL:
- rename_symbol_clear(ted);
- buffer_clear(&ted->line_buffer);
- break;
- }*/
ted->menu_open_idx = 0;
ted->menu_context = NULL;
ted->selector_open = NULL;
}
void menu_open_with_context(Ted *ted, const char *menu_name, void *context) {
+ if (menu_is_open(ted, menu_name))
+ return;
u32 menu_idx = U32_MAX;
if (*menu_name) {
for (u32 i = 0; i < arr_len(ted->all_menus); ++i) {
@@ -66,13 +54,8 @@ void menu_open_with_context(Ted *ted, const char *menu_name, void *context) {
return;
}
- if (menu_is_open(ted, menu_name))
- return;
-
if (menu_is_any_open(ted))
menu_close(ted);
-
-
if (ted->find) find_close(ted);
autocomplete_close(ted);
@@ -87,19 +70,6 @@ void menu_open_with_context(Ted *ted, const char *menu_name, void *context) {
*ted->warn_overwrite = 0; // clear warn_overwrite
buffer_clear(&ted->line_buffer);
if (info->open) info->open(ted);
- /*
- switch (menu) {
- case MENU_GOTO_DEFINITION:
- definitions_selector_open(ted);
- break;
- case MENU_SHELL:
- ted_switch_to_buffer(ted, &ted->line_buffer);
- ted->shell_history_pos = arr_len(ted->shell_history);
- break;
- case MENU_RENAME_SYMBOL:
- ted_switch_to_buffer(ted, &ted->line_buffer);
- break;
- }*/
}
void menu_open(Ted *ted, const char *menu_name) {
@@ -124,37 +94,9 @@ void menu_update(Ted *ted) {
const MenuInfo *info = &ted->all_menus[ted->menu_open_idx];
if (info->update) info->update(ted);
-
- /*
- TextBuffer *line_buffer = &ted->line_buffer;
- const Settings *settings = ted_active_settings(ted);
- const u32 *colors = settings->colors;
- switch (menu) {
- case MENU_GOTO_DEFINITION: {
- definitions_selector_update(ted);
- } break;
- case MENU_SHELL:
- if (line_buffer->line_buffer_submitted) {
- char *command = str32_to_utf8_cstr(buffer_get_line(line_buffer, 0));
- if (ted->shell_history_pos == arr_len(ted->shell_history) || line_buffer->modified) {
- arr_add(ted->shell_history, command);
- }
- menu_close(ted);
- strbuf_cpy(ted->build_dir, ted->cwd);
- build_start_with_command(ted, command);
- }
- break;
- case MENU_RENAME_SYMBOL:
- if (line_buffer->line_buffer_submitted) {
- char *new_name = str32_to_utf8_cstr(buffer_get_line(line_buffer, 0));
- rename_symbol_at_cursor(ted, ted->prev_active_buffer, new_name);
- free(new_name);
- }
- break;
- }*/
}
-static Rect selection_menu_render_bg(Ted *ted) {
+Rect selection_menu_render_bg(Ted *ted) {
const Settings *settings = ted_active_settings(ted);
const float menu_width = ted_get_menu_width(ted);
const float padding = settings->padding;
@@ -191,79 +133,6 @@ void menu_render(Ted *ted) {
if (info->render)
info->render(ted);
-
- /*
- Font *font_bold = ted->font_bold, *font = ted->font;
- const float char_height = text_font_char_height(font);
- const float char_height_bold = text_font_char_height(font_bold);
- const float line_buffer_height = ted_line_buffer_height(ted);
-
- switch (menu) {
- case MENU_NONE: assert(0); break;
- case MENU_GOTO_DEFINITION: {
- definitions_selector_render(ted, rect4(x1, y1, x2, y2));
- } break;
- case MENU_SHELL: {
- bounds.size.y = line_buffer_height + 2 * padding;
- gl_geometry_rect(bounds, colors[COLOR_MENU_BG]);
- gl_geometry_rect_border(bounds, settings->border_thickness, colors[COLOR_BORDER]);
- gl_geometry_draw();
- bounds = rect_shrink(bounds, padding);
- rect_coords(bounds, &x1, &y1, &x2, &y2);
- const char *text = "Run";
- text_utf8(font_bold, text, x1, y1, colors[COLOR_TEXT]);
- x1 += text_get_size_vec2(font_bold, text).x + padding;
- text_render(font_bold);
-
- buffer_render(&ted->line_buffer, rect4(x1, y1, x2, y2));
- } break;
- case MENU_RENAME_SYMBOL: {
- // highlight symbol
- TextBuffer *buffer = ted->prev_active_buffer;
- if (!buffer) {
- menu_close(ted);
- return;
- }
- if (rename_symbol_is_loading(ted)) {
- // already entered a new name
- return;
- }
-
- u32 sym_start=0, sym_end=0;
- BufferPos cursor_pos = buffer->cursor_pos;
- buffer_word_span_at_pos(buffer, cursor_pos, &sym_start, &sym_end);
- BufferPos bpos0 = {
- .line = cursor_pos.line,
- .index = sym_start
- };
- BufferPos bpos1 = {
- .line = cursor_pos.line,
- .index = sym_end
- };
- // symbol should span from pos0 to pos1
- vec2 p0 = buffer_pos_to_pixels(buffer, bpos0);
- vec2 p1 = buffer_pos_to_pixels(buffer, bpos1);
- p1.y += text_font_char_height(buffer_font(buffer));
- Rect highlight = rect_endpoints(p0, p1);
- gl_geometry_rect_border(highlight, settings->border_thickness, colors[COLOR_BORDER]);
- gl_geometry_rect(highlight, colors[COLOR_HOVER_HL]);
-
- float height = line_buffer_height + 2 * padding;
- bounds.size.y = height;
- gl_geometry_rect(bounds, colors[COLOR_MENU_BG]);
- gl_geometry_rect_border(bounds, settings->border_thickness, colors[COLOR_BORDER]);
- gl_geometry_draw();
- bounds = rect_shrink(bounds, padding);
- rect_coords(bounds, &x1, &y1, &x2, &y2);
- const char *text = "Rename symbol to...";
- text_utf8(font_bold, text, x1, y1, colors[COLOR_TEXT]);
- x1 += text_get_size_vec2(font_bold, text).x + padding;
- text_render(font_bold);
-
- buffer_render(&ted->line_buffer, rect4(x1, y1, x2, y2));
- } break;
- }
- */
}
void menu_shell_move(Ted *ted, int direction) {
@@ -634,6 +503,51 @@ static bool goto_line_menu_close(Ted *ted) {
return true;
}
+static void shell_menu_open(Ted *ted) {
+ ted_switch_to_buffer(ted, &ted->line_buffer);
+ ted->shell_history_pos = arr_len(ted->shell_history);
+}
+
+static void shell_menu_update(Ted *ted) {
+ TextBuffer *line_buffer = &ted->line_buffer;
+ if (line_buffer->line_buffer_submitted) {
+ char *command = str32_to_utf8_cstr(buffer_get_line(line_buffer, 0));
+ if (ted->shell_history_pos == arr_len(ted->shell_history) || line_buffer->modified) {
+ arr_add(ted->shell_history, command);
+ }
+ menu_close(ted);
+ strbuf_cpy(ted->build_dir, ted->cwd);
+ build_start_with_command(ted, command);
+ }
+}
+
+static void shell_menu_render(Ted *ted) {
+ const float line_buffer_height = ted_line_buffer_height(ted);
+ const Settings *settings = ted_active_settings(ted);
+ const float padding = settings->padding;
+ const u32 *colors = settings->colors;
+ const float width = ted_get_menu_width(ted);
+ const float height = line_buffer_height + 2 * padding;
+ Rect bounds = {
+ .pos = {(ted->window_width - width) / 2, padding},
+ .size = {width, height},
+ };
+ gl_geometry_rect(bounds, colors[COLOR_MENU_BG]);
+ gl_geometry_rect_border(bounds, settings->border_thickness, colors[COLOR_BORDER]);
+ gl_geometry_draw();
+ bounds = rect_shrink(bounds, padding);
+ const char *text = "Run";
+ text_utf8(ted->font_bold, text, bounds.pos.x, bounds.pos.y, colors[COLOR_TEXT]);
+ bounds = rect_shrink_left(bounds, text_get_size_vec2(ted->font_bold, text).x + padding);
+ text_render(ted->font_bold);
+ buffer_render(&ted->line_buffer, bounds);
+}
+
+static bool shell_menu_close(Ted *ted) {
+ buffer_clear(&ted->line_buffer);
+ return true;
+}
+
void menu_register(Ted *ted, const MenuInfo *infop) {
MenuInfo info = *infop;
if (!*info.name) {
@@ -701,6 +615,15 @@ void menu_init(Ted *ted) {
};
strbuf_cpy(goto_line_menu.name, MENU_GOTO_LINE);
menu_register(ted, &goto_line_menu);
+
+ MenuInfo shell_menu = {
+ .open = shell_menu_open,
+ .update = shell_menu_update,
+ .render = shell_menu_render,
+ .close = shell_menu_close,
+ };
+ strbuf_cpy(shell_menu.name, MENU_SHELL);
+ menu_register(ted, &shell_menu);
}
void menu_quit(Ted *ted) {
diff --git a/ted-internal.h b/ted-internal.h
index 83a088d..b2f54bf 100644
--- a/ted-internal.h
+++ b/ted-internal.h
@@ -749,6 +749,7 @@ void autocomplete_frame(Ted *ted);
void autocomplete_process_lsp_response(Ted *ted, const LSPResponse *response);
// === ide-definitions.c ===
+void definitions_init(Ted *ted);
/// go to the definition of `name`.
/// if `lsp` is NULL, tags will be used.
/// Note: the document position is required for LSP requests because of overloading (where the name
@@ -808,6 +809,7 @@ void menu_shell_move(Ted *ted, int direction);
void menu_shell_up(Ted *ted);
/// move to next command
void menu_shell_down(Ted *ted);
+Rect selection_menu_render_bg(Ted *ted);
// === node.c ===
void node_free(Node *node);
diff --git a/ted.h b/ted.h
index b47c403..be5fb4c 100644
--- a/ted.h
+++ b/ted.h
@@ -742,13 +742,6 @@ void autocomplete_close(Ted *ted);
// === ide-definitions.c ===
/// cancel the last go-to-definition / find symbols request.
void definition_cancel_lookup(Ted *ted);
-/// open the definitions menu
-void definitions_selector_open(Ted *ted);
-/// update the definitions menu
-void definitions_selector_update(Ted *ted);
-void definitions_selector_render(Ted *ted, Rect bounds);
-/// close the definitions menu
-void definitions_selector_close(Ted *ted);
// === ide-document-link.c ===
/// get document link at this position in the active buffer.
@@ -768,8 +761,6 @@ void hover_close(Ted *ted);
// === ide-rename-symbol.c ===
void rename_symbol_at_cursor(Ted *ted, TextBuffer *buffer, const char *new_name);
-/// returns true if we are currently waiting for the LSP to send us a response
-bool rename_symbol_is_loading(Ted *ted);
void rename_symbol_clear(Ted *ted);
// === ide-signature-help.c ===
diff --git a/util.c b/util.c
index 2f32015..a16f7a5 100644
--- a/util.c
+++ b/util.c
@@ -925,7 +925,6 @@ bool rect_clip_to_rect(Rect *clipped, Rect clipper) {
return clipped->size.x > 0 && clipped->size.y > 0;
}
-// removes `amount` from all sides of r
Rect rect_shrink(Rect r, float amount) {
r.pos.x += amount;
r.pos.y += amount;
@@ -936,7 +935,32 @@ Rect rect_shrink(Rect r, float amount) {
return r;
}
-// adds `amount` to all sides of r
+Rect rect_shrink_left(Rect r, float amount) {
+ r.pos.x += amount;
+ r.size.x -= amount;
+ r.size.x = maxf(r.size.x, 0);
+ return r;
+}
+
+Rect rect_shrink_top(Rect r, float amount) {
+ r.pos.y += amount;
+ r.size.y -= amount;
+ r.size.y = maxf(r.size.y, 0);
+ return r;
+}
+
+Rect rect_shrink_right(Rect r, float amount) {
+ r.size.x -= amount;
+ r.size.x = maxf(r.size.x, 0);
+ return r;
+}
+
+Rect rect_shrink_bottom(Rect r, float amount) {
+ r.size.y -= amount;
+ r.size.y = maxf(r.size.y, 0);
+ return r;
+}
+
Rect rect_grow(Rect r, float amount) {
r.pos.x -= amount;
r.pos.y -= amount;
diff --git a/util.h b/util.h
index 1278e87..aba98bc 100644
--- a/util.h
+++ b/util.h
@@ -212,7 +212,17 @@ void rect_coords(Rect r, float *x1, float *y1, float *x2, float *y2);
void rect_print(Rect r);
float rects_intersect(Rect r1, Rect r2);
bool rect_clip_to_rect(Rect *clipped, Rect clipper);
+/// removes `amount` from all sides of r
Rect rect_shrink(Rect r, float amount);
+/// removes `amount` from the left side of r
+Rect rect_shrink_left(Rect r, float amount);
+/// removes `amount` from the top side of r
+Rect rect_shrink_top(Rect r, float amount);
+/// removes `amount` from the right side of r
+Rect rect_shrink_right(Rect r, float amount);
+/// removes `amount` from the bottom side of r
+Rect rect_shrink_bottom(Rect r, float amount);
+/// adds `amount` to all sides of r
Rect rect_grow(Rect r, float amount);
vec4 color_rgba_to_hsva(vec4 rgba);
vec4 color_hsva_to_rgba(vec4 hsva);