From 95c9f7f55884add46bf52884864762779a6d2b11 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Wed, 15 Nov 2017 18:57:21 -0500 Subject: [PATCH] lots and lots of work on command metadata system --- 4coder_API/types.h | 3 +- 4coder_auto_indent.cpp | 16 +- 4coder_base_commands.cpp | 294 +++++-- 4coder_build_commands.cpp | 16 +- 4coder_clipboard.cpp | 16 +- 4coder_default_framework.h | 36 +- 4coder_default_include.cpp | 185 ++-- 4coder_function_list.cpp | 4 +- 4coder_helper/4coder_jump_parsing.h | 190 ----- ...jump_parsing.cpp => 4coder_jump_direct.cpp | 57 +- ..._sticky_jump.cpp => 4coder_jump_sticky.cpp | 57 +- 4coder_jumping.h | 192 ++++- 4coder_metadata_generator.cpp | 792 ++++++++++++++++++ 4coder_project_commands.cpp | 28 +- 4coder_remapping_commands.cpp | 14 +- 4coder_search.cpp | 28 +- 4coder_system_command.cpp | 7 +- build_metadata.bat | 13 + power/4coder_experiments.cpp | 89 +- power/4coder_miblo_numbers.cpp | 24 +- project.4coder | 2 +- 21 files changed, 1585 insertions(+), 478 deletions(-) delete mode 100644 4coder_helper/4coder_jump_parsing.h rename 4coder_jump_parsing.cpp => 4coder_jump_direct.cpp (59%) rename 4coder_sticky_jump.cpp => 4coder_jump_sticky.cpp (90%) create mode 100644 4coder_metadata_generator.cpp create mode 100644 build_metadata.bat diff --git a/4coder_API/types.h b/4coder_API/types.h index bee9a805..3c8dc882 100644 --- a/4coder_API/types.h +++ b/4coder_API/types.h @@ -747,7 +747,8 @@ TYPEDEF void Custom_Command_Function(struct Application_Links *app); // TODO(allen): Improve meta system so that the system for picking up macros is universal. #define CUSTOM_COMMAND_SIG(name) void name(struct Application_Links *app) - +#define CUSTOM_DOC(str) +#define CUSTOM_ALIAS(x) x /* DOC(Generic_Command acts as a name for a command, and can name an internal command or a custom command.) */ UNION Generic_Command{ diff --git a/4coder_auto_indent.cpp b/4coder_auto_indent.cpp index a47d30be..5c106e03 100644 --- a/4coder_auto_indent.cpp +++ b/4coder_auto_indent.cpp @@ -605,7 +605,9 @@ auto_tab_whole_file_by_summary(Application_Links *app, Buffer_Summary *buffer){ buffer_auto_indent(app, buffer, 0, buffer->size, DEF_TAB_WIDTH, DEFAULT_INDENT_FLAGS | AutoIndent_FullTokens); } -CUSTOM_COMMAND_SIG(auto_tab_whole_file){ +CUSTOM_COMMAND_SIG(auto_tab_whole_file) +CUSTOM_DOC("Audo-indents the entire current buffer.") +{ uint32_t access = AccessOpen; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -613,7 +615,9 @@ CUSTOM_COMMAND_SIG(auto_tab_whole_file){ auto_tab_whole_file_by_summary(app, &buffer); } -CUSTOM_COMMAND_SIG(auto_tab_line_at_cursor){ +CUSTOM_COMMAND_SIG(auto_tab_line_at_cursor) +CUSTOM_DOC("Auto-indents the line on which the cursor sits.") +{ uint32_t access = AccessOpen; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -622,7 +626,9 @@ CUSTOM_COMMAND_SIG(auto_tab_line_at_cursor){ move_past_lead_whitespace(app, &view, &buffer); } -CUSTOM_COMMAND_SIG(auto_tab_range){ +CUSTOM_COMMAND_SIG(auto_tab_range) +CUSTOM_DOC("Auto-indents the range between the cursor and the mark.") +{ uint32_t access = AccessOpen; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -632,7 +638,9 @@ CUSTOM_COMMAND_SIG(auto_tab_range){ move_past_lead_whitespace(app, &view, &buffer); } -CUSTOM_COMMAND_SIG(write_and_auto_tab){ +CUSTOM_COMMAND_SIG(write_and_auto_tab) +CUSTOM_DOC("Inserts a character and auto-indents the line on which the cursor sits.") +{ exec_command(app, write_character); uint32_t access = AccessOpen; diff --git a/4coder_base_commands.cpp b/4coder_base_commands.cpp index 78f0ba4a..2aa599a7 100644 --- a/4coder_base_commands.cpp +++ b/4coder_base_commands.cpp @@ -19,7 +19,9 @@ TYPE: 'drop-in-command-pack' // Fundamental Editing Commands // -CUSTOM_COMMAND_SIG(write_character){ +CUSTOM_COMMAND_SIG(write_character) +CUSTOM_DOC("Inserts whatever character was used to trigger this command.") +{ uint32_t access = AccessOpen; View_Summary view = get_active_view(app, access); @@ -47,7 +49,9 @@ CUSTOM_COMMAND_SIG(write_character){ } } -CUSTOM_COMMAND_SIG(delete_char){ +CUSTOM_COMMAND_SIG(delete_char) +CUSTOM_DOC("Deletes the character to the right of the cursor.") +{ uint32_t access = AccessOpen; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -63,7 +67,9 @@ CUSTOM_COMMAND_SIG(delete_char){ } } -CUSTOM_COMMAND_SIG(backspace_char){ +CUSTOM_COMMAND_SIG(backspace_char) +CUSTOM_DOC("Deletes the character to the left of the cursor.") +{ uint32_t access = AccessOpen; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -80,14 +86,18 @@ CUSTOM_COMMAND_SIG(backspace_char){ } } -CUSTOM_COMMAND_SIG(set_mark){ +CUSTOM_COMMAND_SIG(set_mark) +CUSTOM_DOC("Sets the mark to the current position of the cursor.") +{ View_Summary view = get_active_view(app, AccessProtected); view_set_mark(app, &view, seek_pos(view.cursor.pos)); view_set_cursor(app, &view, seek_pos(view.cursor.pos), 1); } -CUSTOM_COMMAND_SIG(cursor_mark_swap){ +CUSTOM_COMMAND_SIG(cursor_mark_swap) +CUSTOM_DOC("Swaps the position of the cursor and the mark.") +{ View_Summary view = get_active_view(app, AccessProtected); int32_t cursor = view.cursor.pos; @@ -97,7 +107,9 @@ CUSTOM_COMMAND_SIG(cursor_mark_swap){ view_set_mark(app, &view, seek_pos(cursor)); } -CUSTOM_COMMAND_SIG(delete_range){ +CUSTOM_COMMAND_SIG(delete_range) +CUSTOM_DOC("Deletes the text in the range between the cursor and the mark.") +{ uint32_t access = AccessOpen; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -110,7 +122,9 @@ CUSTOM_COMMAND_SIG(delete_range){ // Basic Navigation Commands // -CUSTOM_COMMAND_SIG(center_view){ +CUSTOM_COMMAND_SIG(center_view) +CUSTOM_DOC("Centers the view vertically on the line on which the cursor sits.") +{ View_Summary view = get_active_view(app, AccessProtected); i32_Rect region = view.file_region; @@ -123,7 +137,9 @@ CUSTOM_COMMAND_SIG(center_view){ view_set_scroll(app, &view, scroll); } -CUSTOM_COMMAND_SIG(left_adjust_view){ +CUSTOM_COMMAND_SIG(left_adjust_view) +CUSTOM_DOC("Sets the left size of the view near the x position of the cursor.") +{ View_Summary view = get_active_view(app, AccessProtected); GUI_Scroll_Vars scroll = view.scroll_vars; @@ -160,7 +176,9 @@ global_point_to_view_point(View_Summary *view, int32_t x, int32_t y, float *x_ou return(result); } -CUSTOM_COMMAND_SIG(click_set_cursor){ +CUSTOM_COMMAND_SIG(click_set_cursor) +CUSTOM_DOC("Sets the cursor position to the mouse position.") +{ uint32_t access = AccessProtected; View_Summary view = get_active_view(app, access); @@ -171,7 +189,9 @@ CUSTOM_COMMAND_SIG(click_set_cursor){ } } -CUSTOM_COMMAND_SIG(click_set_mark){ +CUSTOM_COMMAND_SIG(click_set_mark) +CUSTOM_DOC("Sets the mark position to the mouse position.") +{ uint32_t access = AccessProtected; View_Summary view = get_active_view(app, access); @@ -193,19 +213,27 @@ move_vertical(Application_Links *app, float line_multiplier){ view_set_cursor(app, &view, seek_xy(x, new_y, 0, view.unwrapped_lines), 0); } -CUSTOM_COMMAND_SIG(move_up){ +CUSTOM_COMMAND_SIG(move_up) +CUSTOM_DOC("Moves the cursor up one line.") +{ move_vertical(app, -1.f); } -CUSTOM_COMMAND_SIG(move_down){ +CUSTOM_COMMAND_SIG(move_down) +CUSTOM_DOC("Moves the cursor down one line.") +{ move_vertical(app, 1.f); } -CUSTOM_COMMAND_SIG(move_up_10){ +CUSTOM_COMMAND_SIG(move_up_10) +CUSTOM_DOC("Moves the cursor up ten lines.") +{ move_vertical(app, -10.f); } -CUSTOM_COMMAND_SIG(move_down_10){ +CUSTOM_COMMAND_SIG(move_down_10) +CUSTOM_DOC("Moves the cursor down ten lines.") +{ move_vertical(app, 10.f); } @@ -225,14 +253,18 @@ get_page_jump(View_Summary *view){ return(page_jump); } -CUSTOM_COMMAND_SIG(page_up){ +CUSTOM_COMMAND_SIG(page_up) +CUSTOM_DOC("Scrolls the view up one view height and moves the cursor up one view height.") +{ uint32_t access = AccessProtected; View_Summary view = get_active_view(app, access); float page_jump = get_page_jump(&view); move_vertical(app, -page_jump); } -CUSTOM_COMMAND_SIG(page_down){ +CUSTOM_COMMAND_SIG(page_down) +CUSTOM_DOC("Scrolls the view down one view height and moves the cursor down one view height.") +{ uint32_t access = AccessProtected; View_Summary view = get_active_view(app, access); float page_jump = get_page_jump(&view); @@ -240,21 +272,27 @@ CUSTOM_COMMAND_SIG(page_down){ } -CUSTOM_COMMAND_SIG(move_left){ +CUSTOM_COMMAND_SIG(move_left) +CUSTOM_DOC("Moves the cursor one character to the left.") +{ uint32_t access = AccessProtected; View_Summary view = get_active_view(app, access); int32_t new_pos = view.cursor.character_pos - 1; view_set_cursor(app, &view, seek_character_pos(new_pos), 1); } -CUSTOM_COMMAND_SIG(move_right){ +CUSTOM_COMMAND_SIG(move_right) +CUSTOM_DOC("Moves the cursor one character to the right.") +{ uint32_t access = AccessProtected; View_Summary view = get_active_view(app, access); int32_t new_pos = view.cursor.character_pos + 1; view_set_cursor(app, &view, seek_character_pos(new_pos), 1); } -CUSTOM_COMMAND_SIG(select_all){ +CUSTOM_COMMAND_SIG(select_all) +CUSTOM_DOC("Puts the cursor at the top of the file, and the mark at the bottom of the file.") +{ View_Summary view = get_active_view(app, AccessProtected); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); view_set_cursor(app, &view, seek_character_pos(0), true); @@ -265,7 +303,9 @@ CUSTOM_COMMAND_SIG(select_all){ // Long Seeks // -CUSTOM_COMMAND_SIG(seek_whitespace_up){ +CUSTOM_COMMAND_SIG(seek_whitespace_up) +CUSTOM_DOC("Seeks the cursor up to the next blank line.") +{ uint32_t access = AccessProtected; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -274,7 +314,9 @@ CUSTOM_COMMAND_SIG(seek_whitespace_up){ view_set_cursor(app, &view, seek_pos(new_pos), true); } -CUSTOM_COMMAND_SIG(seek_whitespace_down){ +CUSTOM_COMMAND_SIG(seek_whitespace_down) +CUSTOM_DOC("Seeks the cursor down to the next blank line.") +{ uint32_t access = AccessProtected; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -283,16 +325,9 @@ CUSTOM_COMMAND_SIG(seek_whitespace_down){ view_set_cursor(app, &view, seek_pos(new_pos), true); } -CUSTOM_COMMAND_SIG(seek_end_of_textual_line){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - - int32_t new_pos = seek_line_end(app, &buffer, view.cursor.pos); - view_set_cursor(app, &view, seek_pos(new_pos), true); -} - -CUSTOM_COMMAND_SIG(seek_beginning_of_textual_line){ +CUSTOM_COMMAND_SIG(seek_beginning_of_textual_line) +CUSTOM_DOC("Seeks the cursor to the beginning of the line across all text.") +{ uint32_t access = AccessProtected; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -301,7 +336,20 @@ CUSTOM_COMMAND_SIG(seek_beginning_of_textual_line){ view_set_cursor(app, &view, seek_pos(new_pos), true); } -CUSTOM_COMMAND_SIG(seek_beginning_of_line){ +CUSTOM_COMMAND_SIG(seek_end_of_textual_line) +CUSTOM_DOC("Seeks the cursor to the end of the line across all text.") +{ + uint32_t access = AccessProtected; + View_Summary view = get_active_view(app, access); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); + + int32_t new_pos = seek_line_end(app, &buffer, view.cursor.pos); + view_set_cursor(app, &view, seek_pos(new_pos), true); +} + +CUSTOM_COMMAND_SIG(seek_beginning_of_line) +CUSTOM_DOC("Seeks the cursor to the beginning of the visual line.") +{ View_Summary view = get_active_view(app, AccessProtected); float y = view.cursor.wrapped_y; @@ -312,7 +360,9 @@ CUSTOM_COMMAND_SIG(seek_beginning_of_line){ view_set_cursor(app, &view, seek_xy(0, y, 1, view.unwrapped_lines), 1); } -CUSTOM_COMMAND_SIG(seek_end_of_line){ +CUSTOM_COMMAND_SIG(seek_end_of_line) +CUSTOM_DOC("Seeks the cursor to the end of the visual line.") +{ View_Summary view = get_active_view(app, AccessProtected); float y = view.cursor.wrapped_y; @@ -323,12 +373,16 @@ CUSTOM_COMMAND_SIG(seek_end_of_line){ view_set_cursor(app, &view, seek_xy(100000.f, y, 1, view.unwrapped_lines), 1); } -CUSTOM_COMMAND_SIG(seek_whitespace_up_end_line){ +CUSTOM_COMMAND_SIG(seek_whitespace_up_end_line) +CUSTOM_DOC("Seeks the cursor up to the next blank line and places it at the end of the line.") +{ exec_command(app, seek_whitespace_up); exec_command(app, seek_end_of_line); } -CUSTOM_COMMAND_SIG(seek_whitespace_down_end_line){ +CUSTOM_COMMAND_SIG(seek_whitespace_down_end_line) +CUSTOM_DOC("Seeks the cursor down to the next blank line and places it at the end of the line.") +{ exec_command(app, seek_whitespace_down); exec_command(app, seek_end_of_line); } @@ -338,7 +392,9 @@ CUSTOM_COMMAND_SIG(seek_whitespace_down_end_line){ // Fancy Editing // -CUSTOM_COMMAND_SIG(to_uppercase){ +CUSTOM_COMMAND_SIG(to_uppercase) +CUSTOM_DOC("Converts all ascii text in the range between the cursor and the mark to uppercase.") +{ View_Summary view = get_active_view(app, AccessOpen); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); @@ -356,7 +412,9 @@ CUSTOM_COMMAND_SIG(to_uppercase){ } } -CUSTOM_COMMAND_SIG(to_lowercase){ +CUSTOM_COMMAND_SIG(to_lowercase) +CUSTOM_DOC("Converts all ascii text in the range between the cursor and the mark to lowercase.") +{ View_Summary view = get_active_view(app, AccessOpen); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); @@ -374,7 +432,9 @@ CUSTOM_COMMAND_SIG(to_lowercase){ } } -CUSTOM_COMMAND_SIG(clean_all_lines){ +CUSTOM_COMMAND_SIG(clean_all_lines) +CUSTOM_DOC("Removes trailing whitespace from all lines in the current buffer.") +{ // TODO(allen): This command always iterates accross the entire // buffer, so streaming it is actually the wrong call. Rewrite this // to minimize calls to buffer_read_range. @@ -401,10 +461,10 @@ CUSTOM_COMMAND_SIG(clean_all_lines){ for (; i < chunk.end; ++i){ char at_pos = chunk.data[i]; if (at_pos == '\n'){ - if (last_hard+1 < i){ + if (last_hard + 1 < i){ edit->str_start = 0; edit->len = 0; - edit->start = last_hard+1; + edit->start = last_hard + 1; edit->end = i; ++edit; } @@ -421,10 +481,10 @@ CUSTOM_COMMAND_SIG(clean_all_lines){ still_looping = forward_stream_chunk(&chunk); }while(still_looping); - if (last_hard+1 < buffer_size){ + if (last_hard + 1 < buffer_size){ edit->str_start = 0; edit->len = 0; - edit->start = last_hard+1; + edit->start = last_hard + 1; edit->end = buffer_size; ++edit; } @@ -440,13 +500,17 @@ CUSTOM_COMMAND_SIG(clean_all_lines){ // Basic Panel Management // -CUSTOM_COMMAND_SIG(basic_change_active_panel){ +CUSTOM_COMMAND_SIG(basic_change_active_panel) +CUSTOM_DOC("Change the currently active panel, moving to the panel with the next highest view_id. Will not skipe the build panel if it is open.") +{ View_Summary view = get_active_view(app, AccessAll); get_view_next_looped(app, &view, AccessAll); set_active_view(app, &view); } -CUSTOM_COMMAND_SIG(close_panel){ +CUSTOM_COMMAND_SIG(close_panel) +CUSTOM_DOC("Closes the currently active panel if it is not the only panel open.") +{ View_Summary view = get_active_view(app, AccessAll); close_view(app, &view); } @@ -456,36 +520,46 @@ CUSTOM_COMMAND_SIG(close_panel){ // Common Settings Commands // -CUSTOM_COMMAND_SIG(show_scrollbar){ +CUSTOM_COMMAND_SIG(show_scrollbar) +CUSTOM_DOC("Sets the current view to show it's scrollbar.") +{ View_Summary view = get_active_view(app, AccessAll); view_set_setting(app, &view, ViewSetting_ShowScrollbar, true); } -CUSTOM_COMMAND_SIG(hide_scrollbar){ +CUSTOM_COMMAND_SIG(hide_scrollbar) +CUSTOM_DOC("Sets the current view to hide it's scrollbar.") +{ View_Summary view = get_active_view(app, AccessAll); view_set_setting(app, &view, ViewSetting_ShowScrollbar, false); } -CUSTOM_COMMAND_SIG(show_filebar){ +CUSTOM_COMMAND_SIG(show_filebar) +CUSTOM_DOC("Sets the current view to show it's filebar.") +{ View_Summary view = get_active_view(app, AccessAll); view_set_setting(app, &view, ViewSetting_ShowFileBar, true); } -CUSTOM_COMMAND_SIG(hide_filebar){ +CUSTOM_COMMAND_SIG(hide_filebar) +CUSTOM_DOC("Sets the current view to hide it's filebar.") +{ View_Summary view = get_active_view(app, AccessAll); view_set_setting(app, &view, ViewSetting_ShowFileBar, false); } -CUSTOM_COMMAND_SIG(toggle_filebar){ +CUSTOM_COMMAND_SIG(toggle_filebar) +CUSTOM_DOC("Toggles the visibility status of the current view's filebar.") +{ View_Summary view = get_active_view(app, AccessAll); bool32 value; view_get_setting(app, &view, ViewSetting_ShowFileBar, &value); view_set_setting(app, &view, ViewSetting_ShowFileBar, !value); } -//toggle_fullscreen can be used as a command - -CUSTOM_COMMAND_SIG(toggle_line_wrap){ +CUSTOM_COMMAND_SIG(toggle_line_wrap) +CUSTOM_DOC("Toggles the current buffer's line wrapping status.") +{ View_Summary view = get_active_view(app, AccessProtected); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); @@ -493,7 +567,9 @@ CUSTOM_COMMAND_SIG(toggle_line_wrap){ buffer_set_setting(app, &buffer, BufferSetting_WrapLine, unwrapped); } -CUSTOM_COMMAND_SIG(increase_line_wrap){ +CUSTOM_COMMAND_SIG(increase_line_wrap) +CUSTOM_DOC("Increases the current buffer's width for line wrapping.") +{ View_Summary view = get_active_view(app, AccessProtected); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); @@ -502,7 +578,9 @@ CUSTOM_COMMAND_SIG(increase_line_wrap){ buffer_set_setting(app, &buffer, BufferSetting_WrapPosition, wrap + 10); } -CUSTOM_COMMAND_SIG(decrease_line_wrap){ +CUSTOM_COMMAND_SIG(decrease_line_wrap) +CUSTOM_DOC("Decrases the current buffer's width for line wrapping.") +{ View_Summary view = get_active_view(app, AccessProtected); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); @@ -511,7 +589,9 @@ CUSTOM_COMMAND_SIG(decrease_line_wrap){ buffer_set_setting(app, &buffer, BufferSetting_WrapPosition, wrap - 10); } -CUSTOM_COMMAND_SIG(toggle_virtual_whitespace){ +CUSTOM_COMMAND_SIG(toggle_virtual_whitespace) +CUSTOM_DOC("Toggles the current buffer's virtual whitespace status.") +{ View_Summary view = get_active_view(app, AccessProtected); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); @@ -520,24 +600,32 @@ CUSTOM_COMMAND_SIG(toggle_virtual_whitespace){ buffer_set_setting(app, &buffer, BufferSetting_VirtualWhitespace, !vwhite); } -CUSTOM_COMMAND_SIG(toggle_show_whitespace){ +CUSTOM_COMMAND_SIG(toggle_show_whitespace) +CUSTOM_DOC("Toggles the current buffer's whitespace visibility status.") +{ View_Summary view = get_active_view(app, AccessProtected); view_set_setting(app, &view, ViewSetting_ShowWhitespace, !view.show_whitespace); } -CUSTOM_COMMAND_SIG(eol_dosify){ +CUSTOM_COMMAND_SIG(eol_dosify) +CUSTOM_DOC("Puts the buffer in DOS line ending mode.") +{ View_Summary view = get_active_view(app, AccessOpen); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); buffer_set_setting(app, &buffer, BufferSetting_Eol, 1); } -CUSTOM_COMMAND_SIG(eol_nixify){ +CUSTOM_COMMAND_SIG(eol_nixify) +CUSTOM_DOC("Puts the buffer in NIX line ending mode.") +{ View_Summary view = get_active_view(app, AccessOpen); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); buffer_set_setting(app, &buffer, BufferSetting_Eol, 0); } -CUSTOM_COMMAND_SIG(exit_4coder){ +CUSTOM_COMMAND_SIG(exit_4coder) +CUSTOM_DOC("Attempts to close 4coder.") +{ send_exit_signal(app); } @@ -545,7 +633,9 @@ CUSTOM_COMMAND_SIG(exit_4coder){ // Interactive Commands // -CUSTOM_COMMAND_SIG(goto_line){ +CUSTOM_COMMAND_SIG(goto_line) +CUSTOM_DOC("Queries the user for a number, and jumps the cursor to the corresponding line.") +{ uint32_t access = AccessProtected; Query_Bar bar = {0}; @@ -716,17 +806,23 @@ isearch(Application_Links *app, int32_t start_reversed, String query_init){ view_set_cursor(app, &view, seek_pos(match.min), true); } -CUSTOM_COMMAND_SIG(search){ +CUSTOM_COMMAND_SIG(search) +CUSTOM_DOC("Begins an incremental search down through the current buffer for a user specified string.") +{ String query = {0}; isearch(app, false, query); } -CUSTOM_COMMAND_SIG(reverse_search){ +CUSTOM_COMMAND_SIG(reverse_search) +CUSTOM_DOC("Begins an incremental search up through the current buffer for a user specified string.") +{ String query = {0}; isearch(app, true, query); } -CUSTOM_COMMAND_SIG(search_identifier){ +CUSTOM_COMMAND_SIG(search_identifier) +CUSTOM_DOC("Begins an incremental search down through the current buffer for the word or token under the cursor.") +{ View_Summary view = get_active_view(app, AccessProtected); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); @@ -735,7 +831,9 @@ CUSTOM_COMMAND_SIG(search_identifier){ isearch(app, false, query); } -CUSTOM_COMMAND_SIG(reverse_search_identifier){ +CUSTOM_COMMAND_SIG(reverse_search_identifier) +CUSTOM_DOC("Begins an incremental search up through the current buffer for the word or token under the cursor.") +{ View_Summary view = get_active_view(app, AccessProtected); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); @@ -744,7 +842,9 @@ CUSTOM_COMMAND_SIG(reverse_search_identifier){ isearch(app, true, query); } -CUSTOM_COMMAND_SIG(replace_in_range){ +CUSTOM_COMMAND_SIG(replace_in_range) +CUSTOM_DOC("Queries the user for two strings, and replaces all occurences of the first string in the range between the cursor and the mark with the second string.") +{ Query_Bar replace; char replace_space[1024]; replace.prompt = make_lit_string("Replace: "); @@ -812,7 +912,9 @@ query_replace(Application_Links *app, View_Summary *view, Buffer_Summary *buffer view_set_cursor(app, view, seek_pos(pos), true); } -CUSTOM_COMMAND_SIG(query_replace){ +CUSTOM_COMMAND_SIG(query_replace) +CUSTOM_DOC("Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.") +{ Query_Bar replace; char replace_space[1024]; replace.prompt = make_lit_string("Replace: "); @@ -843,7 +945,9 @@ CUSTOM_COMMAND_SIG(query_replace){ query_replace(app, &view, &buffer, pos, r, w); } -CUSTOM_COMMAND_SIG(query_replace_identifier){ +CUSTOM_COMMAND_SIG(query_replace_identifier) +CUSTOM_DOC("Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.") +{ View_Summary view = get_active_view(app, AccessProtected); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); @@ -884,7 +988,9 @@ CUSTOM_COMMAND_SIG(query_replace_identifier){ // File Handling Commands // -CUSTOM_COMMAND_SIG(save_all_dirty_buffers){ +CUSTOM_COMMAND_SIG(save_all_dirty_buffers) +CUSTOM_DOC("Saves all buffers marked dirty (showing the '*' indicator).") +{ for (Buffer_Summary buffer = get_buffer_first(app, AccessOpen); buffer.exists; get_buffer_next(app, &buffer, AccessOpen)){ @@ -898,55 +1004,75 @@ CUSTOM_COMMAND_SIG(save_all_dirty_buffers){ // cmdid wrappers // -CUSTOM_COMMAND_SIG(undo){ +CUSTOM_COMMAND_SIG(undo) +CUSTOM_DOC("Advances backwards through the undo history.") +{ exec_command(app, cmdid_undo); } -CUSTOM_COMMAND_SIG(redo){ +CUSTOM_COMMAND_SIG(redo) +CUSTOM_DOC("Advances forewards through the undo history.") +{ exec_command(app, cmdid_redo); } -CUSTOM_COMMAND_SIG(interactive_new){ +CUSTOM_COMMAND_SIG(interactive_new) +CUSTOM_DOC("Interactively creates a new file.") +{ exec_command(app, cmdid_interactive_new); } -CUSTOM_COMMAND_SIG(interactive_open){ +CUSTOM_COMMAND_SIG(interactive_open) +CUSTOM_DOC("Interactively opens a file.") +{ exec_command(app, cmdid_interactive_open); } -CUSTOM_COMMAND_SIG(interactive_open_or_new){ +CUSTOM_COMMAND_SIG(interactive_open_or_new) +CUSTOM_DOC("Interactively opens or creates a new file.") +{ exec_command(app, cmdid_interactive_open_or_new); } -CUSTOM_COMMAND_SIG(save_as){ - exec_command(app, cmdid_save_as); -} - -CUSTOM_COMMAND_SIG(interactive_switch_buffer){ +CUSTOM_COMMAND_SIG(interactive_switch_buffer) +CUSTOM_DOC("Interactively switch to an open buffer.") +{ exec_command(app, cmdid_interactive_switch_buffer); } -CUSTOM_COMMAND_SIG(interactive_kill_buffer){ +CUSTOM_COMMAND_SIG(interactive_kill_buffer) +CUSTOM_DOC("Interactively kill an open buffer.") +{ exec_command(app, cmdid_interactive_kill_buffer); } -CUSTOM_COMMAND_SIG(reopen){ +CUSTOM_COMMAND_SIG(reopen) +CUSTOM_DOC("Reopen the current buffer from the hard drive.") +{ exec_command(app, cmdid_reopen); } -CUSTOM_COMMAND_SIG(save){ +CUSTOM_COMMAND_SIG(save) +CUSTOM_DOC("Saves the current buffer.") +{ exec_command(app, cmdid_save); } -CUSTOM_COMMAND_SIG(kill_buffer){ +CUSTOM_COMMAND_SIG(kill_buffer) +CUSTOM_DOC("Kills the current buffer.") +{ exec_command(app, cmdid_kill_buffer); } -CUSTOM_COMMAND_SIG(open_color_tweaker){ +CUSTOM_COMMAND_SIG(open_color_tweaker) +CUSTOM_DOC("Opens the 4coder colors and fonts selector menu.") +{ exec_command(app, cmdid_open_color_tweaker); } -CUSTOM_COMMAND_SIG(open_debug){ +CUSTOM_COMMAND_SIG(open_debug) +CUSTOM_DOC("Opens a debug view for internal use.") +{ exec_command(app, cmdid_open_debug); } diff --git a/4coder_build_commands.cpp b/4coder_build_commands.cpp index 054a6fc2..a4d58f94 100644 --- a/4coder_build_commands.cpp +++ b/4coder_build_commands.cpp @@ -166,7 +166,9 @@ execute_standard_build(Application_Links *app, View_Summary *view, Buffer_Summar } } -CUSTOM_COMMAND_SIG(build_search){ +CUSTOM_COMMAND_SIG(build_search) +CUSTOM_DOC("Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*.") +{ uint32_t access = AccessAll; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -198,7 +200,9 @@ set_fancy_compilation_buffer_font(Application_Links *app){ buffer_set_font(app, &comp_buffer, literal("Inconsolata")); } -CUSTOM_COMMAND_SIG(build_in_build_panel){ +CUSTOM_COMMAND_SIG(build_in_build_panel) +CUSTOM_DOC("Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. Puts the *compilation* buffer in a panel at the footer of the current view.") +{ uint32_t access = AccessAll; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -212,11 +216,15 @@ CUSTOM_COMMAND_SIG(build_in_build_panel){ lock_jump_buffer(literal("*compilation*")); } -CUSTOM_COMMAND_SIG(close_build_panel){ +CUSTOM_COMMAND_SIG(close_build_panel) +CUSTOM_DOC("If the special build panel is open, closes it.") +{ close_special_note_view(app); } -CUSTOM_COMMAND_SIG(change_to_build_panel){ +CUSTOM_COMMAND_SIG(change_to_build_panel) +CUSTOM_DOC("If the special build panel is open, makes the build panel the active panel.") +{ View_Summary view = open_special_note_view(app, false); if (!view.exists){ diff --git a/4coder_clipboard.cpp b/4coder_clipboard.cpp index 56e13c01..0f029fa8 100644 --- a/4coder_clipboard.cpp +++ b/4coder_clipboard.cpp @@ -49,21 +49,27 @@ clipboard_cut(Application_Links *app, int32_t start, int32_t end, Buffer_Summary return(result); } -CUSTOM_COMMAND_SIG(copy){ +CUSTOM_COMMAND_SIG(copy) +CUSTOM_DOC("Copy the text in the range from the cursor to the mark onto the clipboard.") +{ uint32_t access = AccessProtected; View_Summary view = get_active_view(app, access); Range range = get_range(&view); clipboard_copy(app, range.min, range.max, 0, access); } -CUSTOM_COMMAND_SIG(cut){ +CUSTOM_COMMAND_SIG(cut) +CUSTOM_DOC("Cut the text in the range from the cursor to the mark onto the clipboard.") +{ uint32_t access = AccessOpen; View_Summary view = get_active_view(app, access); Range range = get_range(&view); clipboard_cut(app, range.min, range.max, 0, access); } -CUSTOM_COMMAND_SIG(paste){ +CUSTOM_COMMAND_SIG(paste) +CUSTOM_DOC("At the cursor, insert the text at the top of the clipboard.") +{ uint32_t access = AccessOpen; int32_t count = clipboard_count(app, 0); if (count > 0){ @@ -99,7 +105,9 @@ CUSTOM_COMMAND_SIG(paste){ } } -CUSTOM_COMMAND_SIG(paste_next){ +CUSTOM_COMMAND_SIG(paste_next) +CUSTOM_DOC("If the previous command was paste or paste_next, replaces the paste range with the next text down on the clipboard, otherwise operates as the paste command.") +{ uint32_t access = AccessOpen; int32_t count = clipboard_count(app, 0); if (count > 0){ diff --git a/4coder_default_framework.h b/4coder_default_framework.h index a41e4a62..2cbfb3a8 100644 --- a/4coder_default_framework.h +++ b/4coder_default_framework.h @@ -122,7 +122,9 @@ open_special_note_view(Application_Links *app, bool32 create_if_not_exist = true return(special_view); } -CUSTOM_COMMAND_SIG(change_active_panel){ +CUSTOM_COMMAND_SIG(change_active_panel) +CUSTOM_DOC("Change the currently active panel, moving to the panel with the next highest view_id.") +{ View_Summary view = get_active_view(app, AccessAll); View_ID original_view_id = view.view_id; @@ -138,7 +140,9 @@ CUSTOM_COMMAND_SIG(change_active_panel){ } } -CUSTOM_COMMAND_SIG(change_active_panel_backwards){ +CUSTOM_COMMAND_SIG(change_active_panel_backwards) +CUSTOM_DOC("Change the currently active panel, moving to the panel with the next lowest view_id.") +{ View_Summary view = get_active_view(app, AccessAll); View_ID original_view_id = view.view_id; @@ -154,13 +158,17 @@ CUSTOM_COMMAND_SIG(change_active_panel_backwards){ } } -CUSTOM_COMMAND_SIG(open_panel_vsplit){ +CUSTOM_COMMAND_SIG(open_panel_vsplit) +CUSTOM_DOC("Create a new panel by vertically splitting the active panel.") +{ View_Summary view = get_active_view(app, AccessAll); View_Summary new_view = open_view(app, &view, ViewSplit_Right); new_view_settings(app, &new_view); } -CUSTOM_COMMAND_SIG(open_panel_hsplit){ +CUSTOM_COMMAND_SIG(open_panel_hsplit) +CUSTOM_DOC("Create a new panel by horizontally splitting the active panel.") +{ View_Summary view = get_active_view(app, AccessAll); View_Summary new_view = open_view(app, &view, ViewSplit_Bottom); new_view_settings(app, &new_view); @@ -213,19 +221,27 @@ set_mouse_suppression(Application_Links *app, int32_t suppress){ } } -CUSTOM_COMMAND_SIG(suppress_mouse){ +CUSTOM_COMMAND_SIG(suppress_mouse) +CUSTOM_DOC("Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.") +{ set_mouse_suppression(app, true); } -CUSTOM_COMMAND_SIG(allow_mouse){ +CUSTOM_COMMAND_SIG(allow_mouse) +CUSTOM_DOC("Shows the mouse and causes all mouse input to be processed normally.") +{ set_mouse_suppression(app, false); } -CUSTOM_COMMAND_SIG(toggle_mouse){ +CUSTOM_COMMAND_SIG(toggle_mouse) +CUSTOM_DOC("Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.") +{ set_mouse_suppression(app, !suppressing_mouse); } -CUSTOM_COMMAND_SIG(toggle_fullscreen){ +CUSTOM_COMMAND_SIG(toggle_fullscreen) +CUSTOM_DOC("Toggle fullscreen mode on or off. The change(s) do not take effect until the next frame.") +{ set_fullscreen(app, !is_fullscreen(app)); } @@ -722,7 +738,9 @@ change_mapping(Application_Links *app, String mapping){ } } -CUSTOM_COMMAND_SIG(remap_interactive){ +CUSTOM_COMMAND_SIG(remap_interactive) +CUSTOM_DOC("Switch to a named key binding map.") +{ Query_Bar bar = {0}; char space[1024]; bar.prompt = make_lit_string("Map Name: "); diff --git a/4coder_default_include.cpp b/4coder_default_include.cpp index 1bfd1ca6..f4768bdf 100644 --- a/4coder_default_include.cpp +++ b/4coder_default_include.cpp @@ -11,29 +11,53 @@ TYPE: 'major-system-include' #include "4coder_API/custom.h" -#include "4coder_helper/4coder_jump_parsing.h" - -// NOTE(allen): Define USE_OLD_STYLE_JUMPS before including to get the old jumps (instead of sticky jumps). -#if !defined(USE_OLD_STYLE_JUMPS) -#define FCODER_JUMP_COMMANDS -#endif - #include "4coder_default_framework.h" #include "4coder_base_commands.cpp" #include "4coder_auto_indent.cpp" #include "4coder_search.cpp" -#include "4coder_jump_parsing.cpp" +#include "4coder_jump_direct.cpp" +#include "4coder_jump_sticky.cpp" #include "4coder_clipboard.cpp" #include "4coder_system_command.cpp" #include "4coder_build_commands.cpp" #include "4coder_project_commands.cpp" #include "4coder_function_list.cpp" -#if !defined(USE_OLD_STYLE_JUMPS) -#undef FCODER_JUMP_COMMANDS -#include "4coder_sticky_jump.cpp" +// NOTE(allen): Define USE_OLD_STYLE_JUMPS before 4coder_default_include.cpp to get +// the direct jumps (instead of sticky jumps). +#if defined(USE_OLD_STYLE_JUMPS) + +#define goto_jump_at_cursor CUSTOM_ALIAS(goto_jump_at_cursor_direct) +#define goto_jump_at_cursor_same_panel CUSTOM_ALIAS(goto_jump_at_cursor_same_panel_direct) +#define goto_next_jump CUSTOM_ALIAS(goto_next_jump_direct) +#define goto_prev_jump CUSTOM_ALIAS(goto_prev_jump_direct) +#define goto_next_jump_no_skips CUSTOM_ALIAS(goto_next_jump_no_skips_direct) +#define goto_prev_jump_no_skips CUSTOM_ALIAS(goto_prev_jump_no_skips_direct) +#define goto_first_jump CUSTOM_ALIAS(goto_first_jump_direct) +#define newline_or_goto_position CUSTOM_ALIAS(newline_or_goto_position_direct) +#define newline_or_goto_position_same_panel CUSTOM_ALIAS(newline_or_goto_position_same_panel_direct) + +#else + +#define goto_jump_at_cursor CUSTOM_ALIAS(goto_jump_at_cursor_sticky) +#define goto_jump_at_cursor_same_panel CUSTOM_ALIAS(goto_jump_at_cursor_same_panel_sticky) +#define goto_next_jump CUSTOM_ALIAS(goto_next_jump_sticky) +#define goto_prev_jump CUSTOM_ALIAS(goto_prev_jump_sticky) +#define goto_next_jump_no_skips CUSTOM_ALIAS(goto_next_jump_no_skips_sticky) +#define goto_prev_jump_no_skips CUSTOM_ALIAS(goto_prev_jump_no_skips_sticky) +#define goto_first_jump CUSTOM_ALIAS(goto_first_jump_sticky) +#define newline_or_goto_position CUSTOM_ALIAS(newline_or_goto_position_sticky) +#define newline_or_goto_position_same_panel CUSTOM_ALIAS(newline_or_goto_position_same_panel_sticky) + #endif +#define seek_error CUSTOM_ALIAS(seek_jump) +#define goto_next_error CUSTOM_ALIAS(goto_next_jump) +#define goto_prev_error CUSTOM_ALIAS(goto_prev_jump) +#define goto_next_error_no_skips CUSTOM_ALIAS(goto_next_jump_no_skips) +#define goto_prev_error_no_skips CUSTOM_ALIAS(goto_prev_jump_no_skips) +#define goto_first_error CUSTOM_ALIAS(goto_first_jump) + #include "4coder_default_hooks.cpp" #include "4coder_helper/4coder_bind_helper.h" @@ -70,16 +94,45 @@ basic_seek(Application_Links *app, bool32 seek_forward, uint32_t flags){ #define right true #define left false -CUSTOM_COMMAND_SIG(seek_whitespace_right){ basic_seek(app, right, BoundaryWhitespace); } -CUSTOM_COMMAND_SIG(seek_whitespace_left){ basic_seek(app, left, BoundaryWhitespace); } -CUSTOM_COMMAND_SIG(seek_token_right){ basic_seek(app, right, BoundaryToken); } -CUSTOM_COMMAND_SIG(seek_token_left){ basic_seek(app, left, BoundaryToken); } -CUSTOM_COMMAND_SIG(seek_white_or_token_right){basic_seek(app, right, BoundaryToken | BoundaryWhitespace);} -CUSTOM_COMMAND_SIG(seek_white_or_token_left){basic_seek(app, left, BoundaryToken | BoundaryWhitespace);} -CUSTOM_COMMAND_SIG(seek_alphanumeric_right){ basic_seek(app, right, BoundaryAlphanumeric); } -CUSTOM_COMMAND_SIG(seek_alphanumeric_left){ basic_seek(app, left, BoundaryAlphanumeric); } -CUSTOM_COMMAND_SIG(seek_alphanumeric_or_camel_right){ basic_seek(app, right, BoundaryAlphanumeric | BoundaryCamelCase); } -CUSTOM_COMMAND_SIG(seek_alphanumeric_or_camel_left){ basic_seek(app, left, BoundaryAlphanumeric | BoundaryCamelCase); } +CUSTOM_COMMAND_SIG(seek_whitespace_right) +CUSTOM_DOC("Seek right for the next boundary between whitespace and non-whitespace.") +{ basic_seek(app, right, BoundaryWhitespace); } + +CUSTOM_COMMAND_SIG(seek_whitespace_left) +CUSTOM_DOC("Seek left for the next boundary between whitespace and non-whitespace.") +{ basic_seek(app, left, BoundaryWhitespace); } + +CUSTOM_COMMAND_SIG(seek_token_right) +CUSTOM_DOC("Seek right for the next end of a token.") +{ basic_seek(app, right, BoundaryToken); } + +CUSTOM_COMMAND_SIG(seek_token_left) +CUSTOM_DOC("Seek left for the next beginning of a token.") +{ basic_seek(app, left, BoundaryToken); } + +CUSTOM_COMMAND_SIG(seek_white_or_token_right) +CUSTOM_DOC("Seek right for the next end of a token or boundary between whitespace and non-whitespace.") +{basic_seek(app, right, BoundaryToken | BoundaryWhitespace);} + +CUSTOM_COMMAND_SIG(seek_white_or_token_left) +CUSTOM_DOC("Seek left for the next end of a token or boundary between whitespace and non-whitespace.") +{basic_seek(app, left, BoundaryToken | BoundaryWhitespace);} + +CUSTOM_COMMAND_SIG(seek_alphanumeric_right) +CUSTOM_DOC("Seek right for boundary between alphanumeric characters and non-alphanumeric characters.") +{ basic_seek(app, right, BoundaryAlphanumeric); } + +CUSTOM_COMMAND_SIG(seek_alphanumeric_left) +CUSTOM_DOC("Seek left for boundary between alphanumeric characters and non-alphanumeric characters.") +{ basic_seek(app, left, BoundaryAlphanumeric); } + +CUSTOM_COMMAND_SIG(seek_alphanumeric_or_camel_right) +CUSTOM_DOC("Seek right for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.") +{ basic_seek(app, right, BoundaryAlphanumeric | BoundaryCamelCase); } + +CUSTOM_COMMAND_SIG(seek_alphanumeric_or_camel_left) +CUSTOM_DOC("Seek left for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.") +{ basic_seek(app, left, BoundaryAlphanumeric | BoundaryCamelCase); } #undef right #undef left @@ -88,7 +141,9 @@ CUSTOM_COMMAND_SIG(seek_alphanumeric_or_camel_left){ basic_seek(app, left, Bound // Fast Deletes // -CUSTOM_COMMAND_SIG(backspace_word){ +CUSTOM_COMMAND_SIG(backspace_word) +CUSTOM_DOC("Delete characters between the cursor position and the first alphanumeric boundary to the left.") +{ uint32_t access = AccessOpen; View_Summary view = get_active_view(app, access); @@ -106,7 +161,9 @@ CUSTOM_COMMAND_SIG(backspace_word){ } } -CUSTOM_COMMAND_SIG(delete_word){ +CUSTOM_COMMAND_SIG(delete_word) +CUSTOM_DOC("Delete characters between the cursor position and the first alphanumeric boundary to the right.") +{ uint32_t access = AccessOpen; View_Summary view = get_active_view(app, access); @@ -124,7 +181,9 @@ CUSTOM_COMMAND_SIG(delete_word){ } } -CUSTOM_COMMAND_SIG(snipe_token_or_word){ +CUSTOM_COMMAND_SIG(snipe_token_or_word) +CUSTOM_DOC("Delete a single, whole token on or to the left of the cursor.") +{ uint32_t access = AccessOpen; View_Summary view = get_active_view(app, access); @@ -137,7 +196,9 @@ CUSTOM_COMMAND_SIG(snipe_token_or_word){ buffer_replace_range(app, &buffer, range.start, range.end, 0, 0); } -CUSTOM_COMMAND_SIG(snipe_token_or_word_right){ +CUSTOM_COMMAND_SIG(snipe_token_or_word_right) +CUSTOM_DOC("Delete a single, whole token on or to the right of the cursor.") +{ uint32_t access = AccessOpen; View_Summary view = get_active_view(app, access); @@ -154,7 +215,9 @@ CUSTOM_COMMAND_SIG(snipe_token_or_word_right){ // Line Manipulation // -CUSTOM_COMMAND_SIG(duplicate_line){ +CUSTOM_COMMAND_SIG(duplicate_line) +CUSTOM_DOC("Create a copy of the line on which the cursor sits.") +{ View_Summary view = get_active_view(app, AccessOpen); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); @@ -174,7 +237,9 @@ CUSTOM_COMMAND_SIG(duplicate_line){ end_temp_memory(temp); } -CUSTOM_COMMAND_SIG(delete_line){ +CUSTOM_COMMAND_SIG(delete_line) +CUSTOM_DOC("Delete the line the on which the cursor sits.") +{ View_Summary view = get_active_view(app, AccessOpen); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); @@ -194,12 +259,16 @@ CUSTOM_COMMAND_SIG(delete_line){ // Clipboard + Indent Combo Command // -CUSTOM_COMMAND_SIG(paste_and_indent){ +CUSTOM_COMMAND_SIG(paste_and_indent) +CUSTOM_DOC("Paste from the top of clipboard and run auto-indent on the newly pasted text.") +{ exec_command(app, paste); exec_command(app, auto_tab_range); } -CUSTOM_COMMAND_SIG(paste_next_and_indent){ +CUSTOM_COMMAND_SIG(paste_next_and_indent) +CUSTOM_DOC("Paste the next item on the clipboard and run auto-indent on the newly pasted text.") +{ exec_command(app, paste_next); exec_command(app, auto_tab_range); } @@ -237,25 +306,33 @@ long_braces(Application_Links *app, char *text, int32_t size){ move_past_lead_whitespace(app, &view, &buffer); } -CUSTOM_COMMAND_SIG(open_long_braces){ +CUSTOM_COMMAND_SIG(open_long_braces) +CUSTOM_DOC("At the cursor, insert a '{' and '}' separated by a blank line.") +{ char text[] = "{\n\n}"; int32_t size = sizeof(text) - 1; long_braces(app, text, size); } -CUSTOM_COMMAND_SIG(open_long_braces_semicolon){ +CUSTOM_COMMAND_SIG(open_long_braces_semicolon) +CUSTOM_DOC("At the cursor, insert a '{' and '};' separated by a blank line.") +{ char text[] = "{\n\n};"; int32_t size = sizeof(text) - 1; long_braces(app, text, size); } -CUSTOM_COMMAND_SIG(open_long_braces_break){ +CUSTOM_COMMAND_SIG(open_long_braces_break) +CUSTOM_DOC("At the cursor, insert a '{' and '}break;' separated by a blank line.") +{ char text[] = "{\n\n}break;"; int32_t size = sizeof(text) - 1; long_braces(app, text, size); } -CUSTOM_COMMAND_SIG(if0_off){ +CUSTOM_COMMAND_SIG(if0_off) +CUSTOM_DOC("Surround the range between the cursor and mark with an '#if 0' and an '#endif'") +{ char text1[] = "\n#if 0"; int32_t size1 = sizeof(text1) - 1; @@ -325,23 +402,33 @@ write_named_comment_string(Application_Links *app, char *type_string){ write_string(app, str); } -CUSTOM_COMMAND_SIG(write_todo){ +CUSTOM_COMMAND_SIG(write_todo) +CUSTOM_DOC("At the cursor, insert a '// TODO' comment, includes user name if it was specified in config.4coder.") +{ write_named_comment_string(app, "TODO"); } -CUSTOM_COMMAND_SIG(write_hack){ +CUSTOM_COMMAND_SIG(write_hack) +CUSTOM_DOC("At the cursor, insert a '// HACK' comment, includes user name if it was specified in config.4coder.") +{ write_named_comment_string(app, "HACK"); } -CUSTOM_COMMAND_SIG(write_note){ +CUSTOM_COMMAND_SIG(write_note) +CUSTOM_DOC("At the cursor, insert a '// NOTE' comment, includes user name if it was specified in config.4coder.") +{ write_named_comment_string(app, "NOTE"); } -CUSTOM_COMMAND_SIG(write_block){ +CUSTOM_COMMAND_SIG(write_block) +CUSTOM_DOC("At the cursor, insert a block comment.") +{ write_string(app, make_lit_string("/* */")); } -CUSTOM_COMMAND_SIG(write_zero_struct){ +CUSTOM_COMMAND_SIG(write_zero_struct) +CUSTOM_DOC("At the cursor, insert a ' = {0};'.") +{ write_string(app, make_lit_string(" = {0};")); } @@ -383,7 +470,9 @@ file_name_in_quotes(Application_Links *app, String *file_name){ return(result); } -CUSTOM_COMMAND_SIG(open_file_in_quotes){ +CUSTOM_COMMAND_SIG(open_file_in_quotes) +CUSTOM_DOC("Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.") +{ char file_name_[256]; String file_name = make_fixed_width_string(file_name_); @@ -394,17 +483,13 @@ CUSTOM_COMMAND_SIG(open_file_in_quotes){ } } -CUSTOM_COMMAND_SIG(open_in_other){ +CUSTOM_COMMAND_SIG(open_in_other) +CUSTOM_DOC("Reads a filename from surrounding '\"' characters and attempts to open the corresponding file, displaying it in the other view.") +{ exec_command(app, change_active_panel); exec_command(app, interactive_open_or_new); } -CUSTOM_COMMAND_SIG(new_in_other){ - exec_command(app, change_active_panel); - exec_command(app, interactive_new); -} - - // // File Navigating // @@ -458,7 +543,9 @@ get_cpp_matching_file(Application_Links *app, Buffer_Summary buffer, Buffer_Summ return(result); } -CUSTOM_COMMAND_SIG(open_matching_file_cpp){ +CUSTOM_COMMAND_SIG(open_matching_file_cpp) +CUSTOM_DOC("If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.") +{ View_Summary view = get_active_view(app, AccessAll); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessAll); @@ -475,7 +562,9 @@ CUSTOM_COMMAND_SIG(open_matching_file_cpp){ // Execute Arbitrary Command // -CUSTOM_COMMAND_SIG(execute_arbitrary_command){ +CUSTOM_COMMAND_SIG(execute_arbitrary_command) +CUSTOM_DOC("Execute a 'long form' command.") +{ // NOTE(allen): This isn't a super powerful version of this command, I will expand // upon it so that it has all the cmdid_* commands by default. However, with this // as an example you have everything you need to make it work already. You could diff --git a/4coder_function_list.cpp b/4coder_function_list.cpp index 50975908..59652f70 100644 --- a/4coder_function_list.cpp +++ b/4coder_function_list.cpp @@ -345,7 +345,9 @@ list_all_functions(Application_Links *app, Partition *part, Buffer_Summary *buff } -CUSTOM_COMMAND_SIG(list_all_functions_current_buffer){ +CUSTOM_COMMAND_SIG(list_all_functions_current_buffer) +CUSTOM_DOC("Creates a jump list of lines of the current buffer that appear to define or declare functions.") +{ uint32_t access = AccessProtected; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); diff --git a/4coder_helper/4coder_jump_parsing.h b/4coder_helper/4coder_jump_parsing.h deleted file mode 100644 index 62c3ea4d..00000000 --- a/4coder_helper/4coder_jump_parsing.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Helpers for parsing jump location strings. - */ - -// TOP - -#if !defined(FCODER_JUMP_PARSING_H) -#define FCODER_JUMP_PARSING_H - -#include "4coder_helper/4coder_helper.h" -#include "4coder_helper/4coder_long_seek.h" - -#include "4coder_lib/4coder_mem.h" - -struct ID_Pos_Jump_Location{ - Buffer_ID buffer_id; - int32_t pos; -}; - -struct Name_Based_Jump_Location{ - String file; - int32_t line; - int32_t column; -}; - -static bool32 -ms_style_verify(String line, int32_t left_paren_pos, int32_t right_paren_pos){ - int32_t result = false; - String line_part = substr_tail(line, right_paren_pos); - if (match_part_sc(line_part, ") : ")){ - result = true; - } - else if (match_part_sc(line_part, "): ")){ - result = true; - } - if (result){ - String number = substr(line, left_paren_pos + 1, right_paren_pos - left_paren_pos - 2); - if (!str_is_int_s(number)){ - result = false; - } - } - return(result); -} - -static bool32 -parse_jump_location(String line, Name_Based_Jump_Location *location, int32_t *colon_char, bool32 *is_sub_error){ - bool32 result = false; - *is_sub_error = (line.str[0] == ' '); - - int32_t whitespace_length = 0; - line = skip_chop_whitespace(line, &whitespace_length); - - int32_t colon_pos = 0; - bool32 is_ms_style = false; - - int32_t left_paren_pos = find_s_char(line, 0, '('); - int32_t right_paren_pos = find_s_char(line, left_paren_pos, ')'); - while (!is_ms_style && right_paren_pos < line.size){ - if (ms_style_verify(line, left_paren_pos, right_paren_pos)){ - is_ms_style = true; - colon_pos = find_s_char(line, right_paren_pos, ':'); - if (colon_pos < line.size){ - String location_str = substr(line, 0, colon_pos); - - location_str = skip_chop_whitespace(location_str); - - int32_t close_pos = right_paren_pos; - int32_t open_pos = left_paren_pos; - - if (0 < open_pos && open_pos < location_str.size){ - String file = substr(location_str, 0, open_pos); - file = skip_chop_whitespace(file); - - if (file.size > 0){ - String line_number = substr(location_str, - open_pos+1, - close_pos-open_pos-1); - line_number = skip_chop_whitespace(line_number); - - if (line_number.size > 0){ - location->file = file; - - int32_t comma_pos = find_s_char(line_number, 0, ','); - if (comma_pos < line_number.size){ - int32_t start = comma_pos+1; - String column_number = substr(line_number, start, line_number.size-start); - line_number = substr(line_number, 0, comma_pos); - - location->line = str_to_int_s(line_number); - location->column = str_to_int_s(column_number); - } - else{ - location->line = str_to_int_s(line_number); - location->column = 1; - } - - *colon_char = colon_pos + whitespace_length; - result = true; - } - } - } - } - } - else{ - left_paren_pos = find_s_char(line, left_paren_pos + 1, '('); - right_paren_pos = find_s_char(line, left_paren_pos, ')'); - } - } - - if (!is_ms_style){ - int32_t colon_pos1 = find_s_char(line, 0, ':'); - if (line.size > colon_pos1+1){ - if (char_is_slash(line.str[colon_pos1+1])){ - colon_pos1 = find_s_char(line, colon_pos1+1, ':'); - } - } - - int32_t colon_pos2 = find_s_char(line, colon_pos1+1, ':'); - int32_t colon_pos3 = find_s_char(line, colon_pos2+1, ':'); - - if (colon_pos3+1 <= line.size){ - String filename = substr(line, 0, colon_pos1); - String line_number = substr(line, colon_pos1+1, colon_pos2 - colon_pos1 - 1); - String column_number = substr(line, colon_pos2+1, colon_pos3 - colon_pos2 - 1); - - if (filename.size > 0 && - line_number.size > 0 && - column_number.size > 0){ - location->file = filename; - location->line = str_to_int_s(line_number); - location->column = str_to_int_s(column_number); - *colon_char = colon_pos3 + whitespace_length; - result = true; - } - } - else{ - if (colon_pos2+1 <= line.size){ - String filename = substr(line, 0, colon_pos1); - String line_number = substr(line, colon_pos1+1, colon_pos2 - colon_pos1 - 1); - - if (str_is_int_s(line_number)){ - if (filename.size > 0 && line_number.size > 0){ - location->file = filename; - location->line = str_to_int_s(line_number); - location->column = 0; - *colon_char = colon_pos2 + whitespace_length; - result = true; - } - } - } - } - } - - if (!result){ - *is_sub_error = false; - } - - return(result); -} - -static bool32 -parse_jump_location(String line, Name_Based_Jump_Location *location, bool32 skip_sub_error, int32_t *colon_char){ - bool32 is_sub_error = false; - bool32 result = parse_jump_location(line, location, colon_char, &is_sub_error); - if (is_sub_error && skip_sub_error){ - result = false; - } - return(result); -} - -static int32_t -parse_jump_from_buffer_line(Application_Links *app, Partition *part, int32_t buffer_id, int32_t line, int32_t skip_sub_errors, Name_Based_Jump_Location *location){ - - int32_t result = false; - String line_str = {0}; - Buffer_Summary buffer = get_buffer(app, buffer_id, AccessAll); - if (read_line(app, part, &buffer, line, &line_str)){ - int32_t colon_char = 0; - if (parse_jump_location(line_str, location, skip_sub_errors, &colon_char)){ - result = true; - } - } - - return(result); -} - -#endif - -// BOTTOM - diff --git a/4coder_jump_parsing.cpp b/4coder_jump_direct.cpp similarity index 59% rename from 4coder_jump_parsing.cpp rename to 4coder_jump_direct.cpp index 00af4919..2ab1e00d 100644 --- a/4coder_jump_parsing.cpp +++ b/4coder_jump_direct.cpp @@ -1,5 +1,5 @@ /* -4coder_jump_parsing.cpp - Commands and helpers for parsing jump locations from +4coder_direct_jump.cpp - Commands and helpers for parsing jump locations from compiler errors and jumping to them in the corresponding buffer. TYPE: 'drop-in-command-pack' @@ -7,20 +7,23 @@ TYPE: 'drop-in-command-pack' // TOP -#if !defined(FCODER_JUMP_PARSING) && !defined(FCODER_JUMP_COMMANDS) -#define FCODER_JUMP_PARSING +//#if !defined(FCODER_JUMP_PARSING) && !defined(FCODER_JUMP_COMMANDS) +//#define FCODER_JUMP_PARSING +//#define FCODER_JUMP_COMMANDS -#define FCODER_JUMP_COMMANDS +#if !defined(FCODER_JUMP_PARSING) +#define FCODER_JUMP_PARSING #include "4coder_default_framework.h" #include "4coder_helper/4coder_long_seek.h" #include "4coder_helper/4coder_helper.h" -#include "4coder_helper/4coder_jump_parsing.h" #include "4coder_lib/4coder_mem.h" #include "4coder_jumping.h" -CUSTOM_COMMAND_SIG(goto_jump_at_cursor){ +CUSTOM_COMMAND_SIG(goto_jump_at_cursor_direct) +CUSTOM_DOC("If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.") +{ Temp_Memory temp = begin_temp_memory(&global_part); View_Summary view = get_active_view(app, AccessProtected); @@ -39,7 +42,9 @@ CUSTOM_COMMAND_SIG(goto_jump_at_cursor){ end_temp_memory(temp); } -CUSTOM_COMMAND_SIG(goto_jump_at_cursor_same_panel){ +CUSTOM_COMMAND_SIG(goto_jump_at_cursor_same_panel_direct) +CUSTOM_DOC("If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list..") +{ Temp_Memory temp = begin_temp_memory(&global_part); View_Summary view = get_active_view(app, AccessProtected); @@ -56,35 +61,45 @@ CUSTOM_COMMAND_SIG(goto_jump_at_cursor_same_panel){ end_temp_memory(temp); } -CUSTOM_COMMAND_SIG(goto_next_jump){ +CUSTOM_COMMAND_SIG(goto_next_jump_direct) +CUSTOM_DOC("If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.") +{ bool32 skip_repeats = true; bool32 skip_sub_errors = true; int32_t dir = 1; seek_jump(app, &global_part, skip_repeats, skip_sub_errors, dir); } -CUSTOM_COMMAND_SIG(goto_prev_jump){ +CUSTOM_COMMAND_SIG(goto_prev_jump_direct) +CUSTOM_DOC("If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.") +{ bool32 skip_repeats = true; bool32 skip_sub_errors = true; int32_t dir = -1; seek_jump(app, &global_part, skip_repeats, skip_sub_errors, dir); } -CUSTOM_COMMAND_SIG(goto_next_jump_no_skips){ +CUSTOM_COMMAND_SIG(goto_next_jump_no_skips_direct) +CUSTOM_DOC("If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.") +{ bool32 skip_repeats = false; bool32 skip_sub_errors = true; int32_t dir = 1; seek_jump(app, &global_part, skip_repeats, skip_sub_errors, dir); } -CUSTOM_COMMAND_SIG(goto_prev_jump_no_skips){ +CUSTOM_COMMAND_SIG(goto_prev_jump_no_skips_direct) +CUSTOM_DOC("If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.") +{ bool32 skip_repeats = false; bool32 skip_sub_errors = true; int32_t dir = -1; seek_jump(app, &global_part, skip_repeats, skip_sub_errors, dir); } -CUSTOM_COMMAND_SIG(goto_first_jump){ +CUSTOM_COMMAND_SIG(goto_first_jump_direct) +CUSTOM_DOC("If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.") +{ Temp_Memory temp = begin_temp_memory(&global_part); View_Summary view = get_view_for_locked_jump_buffer(app); if (view.exists){ @@ -99,12 +114,14 @@ CUSTOM_COMMAND_SIG(goto_first_jump){ // Insert Newline or Tigger Jump on Read Only Buffer // -CUSTOM_COMMAND_SIG(newline_or_goto_position){ +CUSTOM_COMMAND_SIG(newline_or_goto_position_direct) +CUSTOM_DOC("If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.") +{ View_Summary view = get_active_view(app, AccessProtected); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); if (buffer.lock_flags & AccessProtected){ - goto_jump_at_cursor(app); + goto_jump_at_cursor_direct(app); lock_jump_buffer(buffer); } else{ @@ -112,12 +129,14 @@ CUSTOM_COMMAND_SIG(newline_or_goto_position){ } } -CUSTOM_COMMAND_SIG(newline_or_goto_position_same_panel){ +CUSTOM_COMMAND_SIG(newline_or_goto_position_same_panel_direct) +CUSTOM_DOC("If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.") +{ View_Summary view = get_active_view(app, AccessProtected); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); if (buffer.lock_flags & AccessProtected){ - goto_jump_at_cursor_same_panel(app); + goto_jump_at_cursor_same_panel_direct(app); lock_jump_buffer(buffer); } else{ @@ -125,12 +144,6 @@ CUSTOM_COMMAND_SIG(newline_or_goto_position_same_panel){ } } -#define seek_error seek_jump -#define goto_next_error goto_next_jump -#define goto_prev_error goto_prev_jump -#define goto_next_error_no_skips goto_next_jump_no_skips -#define goto_first_error goto_first_jump - #endif // BOTTOM diff --git a/4coder_sticky_jump.cpp b/4coder_jump_sticky.cpp similarity index 90% rename from 4coder_sticky_jump.cpp rename to 4coder_jump_sticky.cpp index e4c6c690..7d70c43a 100644 --- a/4coder_sticky_jump.cpp +++ b/4coder_jump_sticky.cpp @@ -1,5 +1,5 @@ /* -4coder_sticky_jump.cpp - Commands and helpers for parsing jump locations from +4coder_jump_sticky.cpp - Commands and helpers for parsing jump locations from compiler errors, sticking markers on jump locations, and jumping to them. TYPE: 'drop-in-command-pack' @@ -7,14 +7,16 @@ TYPE: 'drop-in-command-pack' // TOP -#if !defined(FCODER_STICKY_JUMP) && !defined(FCODER_JUMP_COMMANDS) +//#if !defined(FCODER_STICKY_JUMP) && !defined(FCODER_JUMP_COMMANDS) +//#define FCODER_STICKY_JUMP +//#define FCODER_JUMP_COMMANDS + +#if !defined(FCODER_STICKY_JUMP) #define FCODER_STICKY_JUMP -#define FCODER_JUMP_COMMANDS #include "4coder_default_framework.h" #include "4coder_helper/4coder_long_seek.h" #include "4coder_helper/4coder_helper.h" -#include "4coder_helper/4coder_jump_parsing.h" #include "4coder_lib/4coder_mem.h" #include "4coder_jumping.h" @@ -355,7 +357,9 @@ get_line_from_list(Marker_List *list, int32_t index){ return(result); } -CUSTOM_COMMAND_SIG(goto_jump_at_cursor){ +CUSTOM_COMMAND_SIG(goto_jump_at_cursor_sticky) +CUSTOM_DOC("If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.") +{ General_Memory *general = &global_general; Partition *part = &global_part; @@ -381,7 +385,9 @@ CUSTOM_COMMAND_SIG(goto_jump_at_cursor){ end_temp_memory(temp); } -CUSTOM_COMMAND_SIG(goto_jump_at_cursor_same_panel){ +CUSTOM_COMMAND_SIG(goto_jump_at_cursor_same_panel_sticky) +CUSTOM_DOC("If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.") +{ General_Memory *general = &global_general; Partition *part = &global_part; @@ -474,7 +480,9 @@ get_locked_jump_state(Application_Links *app, Partition *part, General_Memory *g return(result); } -CUSTOM_COMMAND_SIG(goto_next_jump){ +CUSTOM_COMMAND_SIG(goto_next_jump_sticky) +CUSTOM_DOC("If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.") +{ General_Memory *general = &global_general; Partition *part = &global_part; @@ -488,7 +496,8 @@ CUSTOM_COMMAND_SIG(goto_next_jump){ } } -CUSTOM_COMMAND_SIG(goto_prev_jump){ +CUSTOM_COMMAND_SIG(goto_prev_jump_sticky) +CUSTOM_DOC("If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations."){ General_Memory *general = &global_general; Partition *part = &global_part; @@ -501,7 +510,9 @@ CUSTOM_COMMAND_SIG(goto_prev_jump){ } } -CUSTOM_COMMAND_SIG(goto_next_jump_no_skips){ +CUSTOM_COMMAND_SIG(goto_next_jump_no_skips_sticky) +CUSTOM_DOC("If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.") +{ General_Memory *general = &global_general; Partition *part = &global_part; @@ -515,7 +526,9 @@ CUSTOM_COMMAND_SIG(goto_next_jump_no_skips){ } } -CUSTOM_COMMAND_SIG(goto_prev_jump_no_skips){ +CUSTOM_COMMAND_SIG(goto_prev_jump_no_skips_sticky) +CUSTOM_DOC("If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.") +{ General_Memory *general = &global_general; Partition *part = &global_part; @@ -528,7 +541,9 @@ CUSTOM_COMMAND_SIG(goto_prev_jump_no_skips){ } } -CUSTOM_COMMAND_SIG(goto_first_jump){ +CUSTOM_COMMAND_SIG(goto_first_jump_sticky) +CUSTOM_DOC("If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.") +{ General_Memory *general = &global_general; Partition *part = &global_part; @@ -548,12 +563,14 @@ CUSTOM_COMMAND_SIG(goto_first_jump){ // Insert Newline or Tigger Jump on Read Only Buffer // -CUSTOM_COMMAND_SIG(newline_or_goto_position){ +CUSTOM_COMMAND_SIG(newline_or_goto_position_sticky) +CUSTOM_DOC("If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.") +{ View_Summary view = get_active_view(app, AccessProtected); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); if (buffer.lock_flags & AccessProtected){ - goto_jump_at_cursor(app); + goto_jump_at_cursor_sticky(app); lock_jump_buffer(buffer); } else{ @@ -561,12 +578,14 @@ CUSTOM_COMMAND_SIG(newline_or_goto_position){ } } -CUSTOM_COMMAND_SIG(newline_or_goto_position_same_panel){ +CUSTOM_COMMAND_SIG(newline_or_goto_position_same_panel_sticky) +CUSTOM_DOC("If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.") +{ View_Summary view = get_active_view(app, AccessProtected); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); if (buffer.lock_flags & AccessProtected){ - goto_jump_at_cursor_same_panel(app); + goto_jump_at_cursor_same_panel_sticky(app); lock_jump_buffer(buffer); } else{ @@ -574,14 +593,6 @@ CUSTOM_COMMAND_SIG(newline_or_goto_position_same_panel){ } } - -#define seek_error seek_jump -#define goto_next_error goto_next_jump -#define goto_prev_error goto_prev_jump -#define goto_next_error_no_skips goto_next_jump_no_skips -#define goto_prev_error_no_skips goto_prev_jump_no_skips -#define goto_first_error goto_first_jump - // // End File Hook // diff --git a/4coder_jumping.h b/4coder_jumping.h index 0f3ac735..519ed023 100644 --- a/4coder_jumping.h +++ b/4coder_jumping.h @@ -9,6 +9,196 @@ TYPE: 'helper-routines' #if !defined(FCODER_JUMPING) #define FCODER_JUMPING +#include "4coder_helper/4coder_helper.h" +#include "4coder_helper/4coder_long_seek.h" + +#include "4coder_lib/4coder_mem.h" + +// +// Jump Parsing +// + +#include "4coder_helper/4coder_helper.h" +#include "4coder_helper/4coder_long_seek.h" + +#include "4coder_lib/4coder_mem.h" + +struct ID_Pos_Jump_Location{ + Buffer_ID buffer_id; + int32_t pos; +}; + +struct Name_Based_Jump_Location{ + String file; + int32_t line; + int32_t column; +}; + +static bool32 +ms_style_verify(String line, int32_t left_paren_pos, int32_t right_paren_pos){ + int32_t result = false; + String line_part = substr_tail(line, right_paren_pos); + if (match_part_sc(line_part, ") : ")){ + result = true; + } + else if (match_part_sc(line_part, "): ")){ + result = true; + } + if (result){ + String number = substr(line, left_paren_pos + 1, right_paren_pos - left_paren_pos - 2); + if (!str_is_int_s(number)){ + result = false; + } + } + return(result); +} + +static bool32 +parse_jump_location(String line, Name_Based_Jump_Location *location, int32_t *colon_char, bool32 *is_sub_error){ + bool32 result = false; + *is_sub_error = (line.str[0] == ' '); + + int32_t whitespace_length = 0; + line = skip_chop_whitespace(line, &whitespace_length); + + int32_t colon_pos = 0; + bool32 is_ms_style = false; + + int32_t left_paren_pos = find_s_char(line, 0, '('); + int32_t right_paren_pos = find_s_char(line, left_paren_pos, ')'); + while (!is_ms_style && right_paren_pos < line.size){ + if (ms_style_verify(line, left_paren_pos, right_paren_pos)){ + is_ms_style = true; + colon_pos = find_s_char(line, right_paren_pos, ':'); + if (colon_pos < line.size){ + String location_str = substr(line, 0, colon_pos); + + location_str = skip_chop_whitespace(location_str); + + int32_t close_pos = right_paren_pos; + int32_t open_pos = left_paren_pos; + + if (0 < open_pos && open_pos < location_str.size){ + String file = substr(location_str, 0, open_pos); + file = skip_chop_whitespace(file); + + if (file.size > 0){ + String line_number = substr(location_str, + open_pos+1, + close_pos-open_pos-1); + line_number = skip_chop_whitespace(line_number); + + if (line_number.size > 0){ + location->file = file; + + int32_t comma_pos = find_s_char(line_number, 0, ','); + if (comma_pos < line_number.size){ + int32_t start = comma_pos+1; + String column_number = substr(line_number, start, line_number.size-start); + line_number = substr(line_number, 0, comma_pos); + + location->line = str_to_int_s(line_number); + location->column = str_to_int_s(column_number); + } + else{ + location->line = str_to_int_s(line_number); + location->column = 1; + } + + *colon_char = colon_pos + whitespace_length; + result = true; + } + } + } + } + } + else{ + left_paren_pos = find_s_char(line, left_paren_pos + 1, '('); + right_paren_pos = find_s_char(line, left_paren_pos, ')'); + } + } + + if (!is_ms_style){ + int32_t colon_pos1 = find_s_char(line, 0, ':'); + if (line.size > colon_pos1+1){ + if (char_is_slash(line.str[colon_pos1+1])){ + colon_pos1 = find_s_char(line, colon_pos1+1, ':'); + } + } + + int32_t colon_pos2 = find_s_char(line, colon_pos1+1, ':'); + int32_t colon_pos3 = find_s_char(line, colon_pos2+1, ':'); + + if (colon_pos3+1 <= line.size){ + String filename = substr(line, 0, colon_pos1); + String line_number = substr(line, colon_pos1+1, colon_pos2 - colon_pos1 - 1); + String column_number = substr(line, colon_pos2+1, colon_pos3 - colon_pos2 - 1); + + if (filename.size > 0 && + line_number.size > 0 && + column_number.size > 0){ + location->file = filename; + location->line = str_to_int_s(line_number); + location->column = str_to_int_s(column_number); + *colon_char = colon_pos3 + whitespace_length; + result = true; + } + } + else{ + if (colon_pos2+1 <= line.size){ + String filename = substr(line, 0, colon_pos1); + String line_number = substr(line, colon_pos1+1, colon_pos2 - colon_pos1 - 1); + + if (str_is_int_s(line_number)){ + if (filename.size > 0 && line_number.size > 0){ + location->file = filename; + location->line = str_to_int_s(line_number); + location->column = 0; + *colon_char = colon_pos2 + whitespace_length; + result = true; + } + } + } + } + } + + if (!result){ + *is_sub_error = false; + } + + return(result); +} + +static bool32 +parse_jump_location(String line, Name_Based_Jump_Location *location, bool32 skip_sub_error, int32_t *colon_char){ + bool32 is_sub_error = false; + bool32 result = parse_jump_location(line, location, colon_char, &is_sub_error); + if (is_sub_error && skip_sub_error){ + result = false; + } + return(result); +} + +static int32_t +parse_jump_from_buffer_line(Application_Links *app, Partition *part, int32_t buffer_id, int32_t line, int32_t skip_sub_errors, Name_Based_Jump_Location *location){ + + int32_t result = false; + String line_str = {0}; + Buffer_Summary buffer = get_buffer(app, buffer_id, AccessAll); + if (read_line(app, part, &buffer, line, &line_str)){ + int32_t colon_char = 0; + if (parse_jump_location(line_str, location, skip_sub_errors, &colon_char)){ + result = true; + } + } + + return(result); +} + +// +// Jumping Details +// + static bool32 get_jump_buffer(Application_Links *app, Buffer_Summary *buffer, Name_Based_Jump_Location *location){ bool32 result = open_file(app, buffer, location->file.str, location->file.size, false, true); @@ -62,7 +252,7 @@ jump_to_location(Application_Links *app, View_Summary *view, Buffer_Summary *buf } // -// Error Jumping +// Jump List Traversing // static bool32 diff --git a/4coder_metadata_generator.cpp b/4coder_metadata_generator.cpp new file mode 100644 index 00000000..dbb12434 --- /dev/null +++ b/4coder_metadata_generator.cpp @@ -0,0 +1,792 @@ +/* +4coder_metadata_generator.cpp - A preprocessor program for generating a list of commands and their descriptions. + +TYPE: 'code-preprocessor' +*/ + +// TOP + +#include "4coder_lib/4coder_mem.h" +#define FSTRING_IMPLEMENTATION +#include "4coder_lib/4coder_string.h" +#include "4cpp/4cpp_lexer.h" + +#include +#include +#include + +typedef int32_t bool32; + +//// WINDOWS BEGIN //// +#define UNICODE +#include +typedef TCHAR Filename_Character; +//// WINDOWS END //// + +struct File_Info{ + Filename_Character *name; + int32_t len; + bool32 is_folder; +}; + +struct File_List{ + File_Info *info; + int32_t count; + int32_t final_length; + Filename_Character final_name[4096]; +}; + +static File_List +get_file_list(Partition *part, Filename_Character *dir); + +static Filename_Character* +encode(Partition *part, char *str); + +static char* +unencode(Partition *part, Filename_Character *str, int32_t len); + +//// WINDOWS BEGIN //// +static bool32 +is_code_file(Filename_Character *name, int32_t len){ + bool32 is_code = false; + if (len >= 5){ + Filename_Character *ext = &name[len - 4]; + if (ext[0] == '.' && ext[1] == 'c' && ext[2] == 'p' && ext[3] == 'p'){ + is_code = true; + } + else if (ext[0] == '.' && ext[1] == 'h' && ext[2] == 'p' && ext[3] == 'p'){ + is_code = true; + } + } + if (len >= 4){ + Filename_Character *ext = &name[len - 3]; + if (ext[0] == '.' && ext[1] == 'c' && ext[2] == 'c'){ + is_code = true; + } + } + if (len >= 3){ + Filename_Character *ext = &name[len - 2]; + if (ext[0] == '.' && ext[1] == 'h'){ + is_code = true; + } + else if (ext[0] == '.' && ext[1] == 'c'){ + is_code = true; + } + } + return(is_code); +} + +static File_List +get_file_list(Partition *part, Filename_Character *dir){ + if (part == 0){ + fprintf(stdout, "fatal error: NULL part passed to %s\n", __FUNCTION__); + exit(1); + } + if (dir == 0){ + fprintf(stdout, "fatal error: NULL dir passed to %s\n", __FUNCTION__); + exit(1); + } + + File_List list = {0}; + Temp_Memory part_reset = begin_temp_memory(part); + + HANDLE dir_handle = + CreateFile(dir, + FILE_LIST_DIRECTORY, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + 0, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, + 0); + + if (dir_handle == INVALID_HANDLE_VALUE){ + fprintf(stdout, "fatal error: could not open directory handle\n"); + exit(1); + } + + Filename_Character final_name[4096]; + DWORD final_length = GetFinalPathNameByHandle(dir_handle, final_name, sizeof(final_name), 0); + if (final_length > sizeof(final_name)){ + fprintf(stdout, "fatal error: path name too long for local buffer\n"); + exit(1); + } + CloseHandle(dir_handle); + + final_length -= 4; + memmove(final_name, final_name + 4, final_length*sizeof(*final_name)); + final_name[final_length] = '\\'; + final_name[final_length + 1] = '*'; + final_name[final_length + 2] = 0; + + WIN32_FIND_DATA find_data = {0}; + HANDLE search = FindFirstFile(final_name, &find_data); + if (search == INVALID_HANDLE_VALUE){ + fprintf(stdout, "fatal error: could not begin a file search\n"); + exit(1); + } + + int32_t character_count = 0; + int32_t file_count = 0; + BOOL more_files = true; + do{ + Filename_Character *name = &find_data.cFileName[0]; + + int32_t size = 0; + for(;name[size];++size); + + uint32_t attribs = find_data.dwFileAttributes; + bool32 is_folder = ((attribs & FILE_ATTRIBUTE_DIRECTORY) != 0); + + if (name[0] != '.' && (is_folder || is_code_file(name, size))){ + ++file_count; + character_count += size + 1; + } + + more_files = FindNextFile(search, &find_data); + }while(more_files); + FindClose(search); + + int32_t rounded_char_size = (character_count*sizeof(Filename_Character) + 7)&(~7); + int32_t memsize = rounded_char_size + file_count*sizeof(File_Info); + void *mem = push_array(part, uint8_t, memsize); + if (mem == 0){ + fprintf(stdout, "fatal error: not enough memory on the partition for a file list.\n"); + exit(1); + } + + Filename_Character *char_ptr = (Filename_Character*)mem; + File_Info *info_ptr = (File_Info*)((uint8_t*)mem + rounded_char_size); + + Filename_Character *char_ptr_end = (Filename_Character*)info_ptr; + File_Info *info_ptr_end = info_ptr + file_count; + + File_Info *info_ptr_base = info_ptr; + + search = FindFirstFile(final_name, &find_data); + if (search == INVALID_HANDLE_VALUE){ + fprintf(stdout, "fatal error: could not restart a file search\n"); + exit(1); + } + + int32_t adjusted_file_count = 0; + more_files = true; + do{ + Filename_Character *name = &find_data.cFileName[0]; + + int32_t size = 0; + for(;name[size]!=0;++size); + + uint32_t attribs = find_data.dwFileAttributes; + bool32 is_folder = ((attribs & FILE_ATTRIBUTE_DIRECTORY) != 0); + + if (name[0] != '.' && (is_folder || is_code_file(name, size))){ + if (info_ptr + 1 > info_ptr_end || char_ptr + size + 1 > char_ptr_end){ + memset(&list, 0, sizeof(list)); + end_temp_memory(part_reset); + FindClose(search); + return(list); + } + + info_ptr->name = char_ptr; + info_ptr->len = size; + info_ptr->is_folder = is_folder; + + memmove(char_ptr, name, size*sizeof(*name)); + char_ptr[size] = 0; + + char_ptr += size + 1; + ++info_ptr; + ++adjusted_file_count; + } + + more_files = FindNextFile(search, &find_data); + }while(more_files); + FindClose(search); + + list.info = info_ptr_base; + list.count = adjusted_file_count; + list.final_length = final_length; + memcpy(list.final_name, final_name, list.final_length*sizeof(*final_name)); + list.final_name[list.final_length] = 0; + + return(list); +} + +static Filename_Character* +encode(Partition *part, char *str){ + int32_t size = 0; + for (;str[size]!=0;++size); + + Filename_Character *out = push_array(part, Filename_Character, size + 1); + push_align(part, 8); + + if (out == 0){ + fprintf(stdout, "fatal error: ran out of memory encoding string to filename\n"); + exit(1); + } + + for (int32_t i = 0, j = 0; i <= size; ++i){ + if (str[i] != '"'){ + out[j++] = str[i]; + } + } + + return(out); +} + +static char* +unencode(Partition *part, Filename_Character *str, int32_t len){ + Temp_Memory temp = begin_temp_memory(part); + char *out = push_array(part, char, len + 1); + push_align(part, 8); + + if (out == 0){ + fprintf(stdout, "fatal error: ran out of memory unencoding string to filename\n"); + exit(1); + } + + for (int32_t i = 0; i <= len; ++i){ + if (str[i] <= 127){ + out[i] = (char)str[i]; + } + else{ + out = 0; + end_temp_memory(temp); + break; + } + } + + return(out); +} +//// WINDOWS END //// + +static String +file_dump(Partition *part, char *name){ + String text = {0}; + + FILE *file = fopen(name, "rb"); + if (file != 0){ + fseek(file, 0, SEEK_END); + text.size = ftell(file); + fseek(file, 0, SEEK_SET); + text.memory_size = text.size + 1; + text.str = push_array(part, char, text.memory_size); + fread(text.str, 1, text.size, file); + terminate_with_null(&text); + fclose(file); + } + + return(text); +} + +static void +error(char *source_name, String text, int32_t pos, char *msg){ + if (pos < 0){ + pos = 0; + } + if (pos > text.size){ + pos = text.size; + } + + int32_t line_number = 1; + int32_t character_pos = 1; + char *end = text.str + pos; + for (char *p = text.str; p < end; ++p){ + if (*p == '\n'){ + ++line_number; + character_pos = 1; + } + else{ + ++character_pos; + } + } + + fprintf(stdout, "%s:%d:%d: %s\n", source_name, line_number, character_pos, msg); + fflush(stdout); +} + +struct Reader{ + char *source_name; + String text; + Cpp_Token_Array tokens; + Cpp_Token *ptr; +}; + +static Reader +make_reader(Cpp_Token_Array array, char *source_name, String text){ + Reader reader = {0}; + reader.tokens = array; + reader.ptr = array.tokens; + reader.source_name = source_name; + reader.text = text; + return(reader); +} + +static Cpp_Token +prev_token(Reader *reader){ + Cpp_Token result = {0}; + + for (;;){ + if (reader->ptr > reader->tokens.tokens + reader->tokens.count){ + reader->ptr = reader->tokens.tokens + reader->tokens.count; + } + + if (reader->ptr > reader->tokens.tokens){ + --reader->ptr; + result = *reader->ptr; + } + else{ + reader->ptr = reader->tokens.tokens; + memset(&result, 0, sizeof(result)); + break; + } + + if (result.type != CPP_TOKEN_COMMENT && result.type != CPP_TOKEN_JUNK){ + break; + } + } + + return(result); +} + +static Cpp_Token +get_token(Reader *reader){ + Cpp_Token result = {0}; + + for (;;){ + if (reader->ptr < reader->tokens.tokens){ + reader->ptr = reader->tokens.tokens; + } + + if (reader->ptr < reader->tokens.tokens + reader->tokens.count){ + result = *reader->ptr; + ++reader->ptr; + } + else{ + reader->ptr = reader->tokens.tokens + reader->tokens.count; + memset(&result, 0, sizeof(result)); + result.start = reader->text.size; + break; + } + + if (result.type != CPP_TOKEN_COMMENT && result.type != CPP_TOKEN_JUNK){ + break; + } + } + + return(result); +} + +static Cpp_Token +peek_token(Reader *reader){ + Cpp_Token result = {0}; + + if (reader->ptr < reader->tokens.tokens){ + reader->ptr = reader->tokens.tokens; + } + + if (reader->ptr >= reader->tokens.tokens + reader->tokens.count){ + result.start = reader->text.size; + } + else{ + result = *reader->ptr; + } + + return(result); +} + +static int32_t +peek_pos(Reader *reader){ + Cpp_Token token = peek_token(reader); + return(token.start); +} + +static void +error(Reader *reader, int32_t pos, char *msg){ + error(reader->source_name, reader->text, pos, msg); +} + +struct Temp_Read{ + Reader *reader; + Cpp_Token *pos; +}; + +static Temp_Read +begin_temp_read(Reader *reader){ + Temp_Read temp = {0}; + temp.reader = reader; + temp.pos = reader->ptr; + return(temp); +} + +static void +end_temp_read(Temp_Read temp){ + temp.reader->ptr = temp.pos; +} + +static String +token_str(String text, Cpp_Token token){ + String str = substr(text, token.start, token.size); + return(str); +} + +static bool32 +require_key_identifier(Reader *reader, char *str){ + bool32 success = false; + + Cpp_Token token = get_token(reader); + if (token.type == CPP_TOKEN_IDENTIFIER){ + String lexeme = token_str(reader->text, token); + if (match(lexeme, str)){ + success = true; + } + } + + if (!success){ + char space[1024]; + String s = make_fixed_width_string(space); + copy(&s, "expected to find '"); + append(&s, str); + append(&s, "'"); + terminate_with_null(&s); + error(reader, token.start, s.str); + } + + return(success); +} + +static bool32 +require_open_parenthese(Reader *reader){ + bool32 success = false; + + Cpp_Token token = get_token(reader); + if (token.type == CPP_TOKEN_PARENTHESE_OPEN){ + success = true; + } + + if (!success){ + error(reader, token.start, "expected to find '('"); + } + + return(success); +} + +static bool32 +require_close_parenthese(Reader *reader){ + bool32 success = false; + + Cpp_Token token = get_token(reader); + if (token.type == CPP_TOKEN_PARENTHESE_CLOSE){ + success = true; + } + + if (!success){ + error(reader, token.start, "expected to find ')'"); + } + + return(success); +} + +static bool32 +require_define(Reader *reader){ + bool32 success = false; + + Cpp_Token token = get_token(reader); + if (token.type == CPP_PP_DEFINE){ + success = true; + } + + if (!success){ + error(reader, token.start, "expected to find '#define'"); + } + + return(success); +} + +static bool32 +extract_identifier(Reader *reader, String *str_out){ + bool32 success = false; + + Cpp_Token token = get_token(reader); + if (token.type == CPP_TOKEN_IDENTIFIER){ + String lexeme = token_str(reader->text, token); + *str_out = lexeme; + success = true; + } + + if (!success){ + error(reader, token.start, "expected to find an identifier"); + } + + return(success); +} + +static bool32 +extract_string(Reader *reader, String *str_out){ + bool32 success = false; + + Cpp_Token token = get_token(reader); + if (token.type == CPP_TOKEN_STRING_CONSTANT){ + String lexeme = token_str(reader->text, token); + *str_out = lexeme; + success = true; + } + + if (!success){ + error(reader, token.start, "expected to find a string literal"); + } + + return(success); +} + +static bool32 +parse_documented_command(Partition *part, Reader *reader){ + String name = {0}; + String doc = {0}; + + // Getting the command's name + if (!require_key_identifier(reader, "CUSTOM_COMMAND_SIG")){ + return(false); + } + + if (!require_open_parenthese(reader)){ + return(false); + } + + if (!extract_identifier(reader, &name)){ + return(false); + } + + if (!require_close_parenthese(reader)){ + return(false); + } + + // Getting the command's doc string + if (!require_key_identifier(reader, "CUSTOM_DOC")){ + return(false); + } + + if (!require_open_parenthese(reader)){ + return(false); + } + + if (!extract_string(reader, &doc)){ + return(false); + } + + if (!require_close_parenthese(reader)){ + return(false); + } + + // TODO(allen): Store into data structure for codegen. + //error(reader, name_pos, "name of a command"); + //error(reader, str_pos, "doc string of a command"); + + return(true); +} + +static bool32 +parse_alias(Partition *part, Reader *reader){ + String name = {0}; + String potential = {0}; + + // Getting the alias's name + if (!require_define(reader)){ + return(false); + } + + int32_t name_pos = peek_pos(reader); + if (!extract_identifier(reader, &name)){ + return(false); + } + + // Getting the alias's target + if (!require_key_identifier(reader, "CUSTOM_ALIAS")){ + return(false); + } + + if (!require_open_parenthese(reader)){ + return(false); + } + + int32_t potential_pos = peek_pos(reader); + if (!extract_identifier(reader, &potential)){ + return(false); + } + + if (!require_close_parenthese(reader)){ + return(false); + } + + error(reader, name_pos, "name of an alias"); + error(reader, potential_pos, "name of a potential"); + + return(true); +} + +static void +parse_text(Partition *part, char *source_name, String text){ + Cpp_Token_Array array = cpp_make_token_array(1024); + cpp_lex_file(text.str, text.size, &array); + + Reader reader_ = make_reader(array, source_name, text); + Reader *reader = &reader_; + + for (;;){ + Cpp_Token token = get_token(reader); + + if (token.type == CPP_TOKEN_IDENTIFIER){ + String lexeme = token_str(text, token); + + bool32 in_preproc_body = ((token.flags & CPP_TFLAG_PP_BODY) != 0); + + if (!in_preproc_body && match(lexeme, "CUSTOM_DOC")){ + Temp_Read temp_read = begin_temp_read(reader); + + bool32 found_start_pos = false; + for (int32_t R = 0; R < 5; ++R){ + Cpp_Token p_token = prev_token(reader); + if (p_token.type == CPP_TOKEN_IDENTIFIER){ + String p_lexeme = token_str(text, p_token); + if (match(p_lexeme, "CUSTOM_COMMAND_SIG")){ + found_start_pos = true; + break; + } + } + if (p_token.type == 0){ + break; + } + } + + if (!found_start_pos){ + end_temp_read(temp_read); + } + else{ + if (!parse_documented_command(part, reader)){ + end_temp_read(temp_read); + } + } + } + else if (match(lexeme, "CUSTOM_ALIAS")){ + Temp_Read temp_read = begin_temp_read(reader); + + bool32 found_start_pos = false; + for (int32_t R = 0; R < 3; ++R){ + Cpp_Token p_token = prev_token(reader); + if (p_token.type == CPP_PP_DEFINE){ + if (R == 2){ + found_start_pos = true; + } + break; + } + if (p_token.type == 0){ + break; + } + } + + if (!found_start_pos){ + end_temp_read(temp_read); + } + else{ + if (!parse_alias(part, reader)){ + end_temp_read(temp_read); + } + } + } + } + + if (token.type == 0){ + break; + } + } + + cpp_free_token_array(array); +} + +static void +parse_file(Partition *part, Filename_Character *name_, int32_t len){ + char *name = unencode(part, name_, len); + if (name == 0){ + if (sizeof(*name_) == 2){ + fprintf(stdout, "warning: could not unencode file name %ls - file skipped\n", name_); + } + else{ + fprintf(stdout, "warning: could not unencode file name %s - file skipped\n", name_); + } + return; + } + + String text = file_dump(part, name); + parse_text(part, name, text); +} + +static void +parse_files_in_directory(Partition *part, Filename_Character *root, bool32 recursive){ + File_List list = get_file_list(part, root); + for (int32_t i = 0; i < list.count; ++i){ + File_Info *info = &list.info[i]; + + int32_t full_name_len = list.final_length + 1 + info->len; + Filename_Character *full_name = push_array(part, Filename_Character, full_name_len + 1); + push_align(part, 8); + + if (full_name == 0){ + fprintf(stdout, "fatal error: not enough memory to recurse to sub directory\n"); + exit(1); + } + + memmove(full_name, list.final_name, list.final_length*sizeof(*full_name)); + full_name[list.final_length] = '\\'; + memmove(full_name + list.final_length + 1, info->name, info->len*sizeof(*full_name)); + full_name[full_name_len] = 0; + + if (!info->is_folder){ + parse_file(part, full_name, full_name_len); + } + else{ + parse_files_in_directory(part, full_name, recursive); + } + } +} + +static void +show_usage(int argc, char **argv){ + char *name = "metadata_generator"; + if (argc >= 1){ + name = argv[0]; + } + fprintf(stdout, "usage:\n%s [-R] [ ...]\n", name); + exit(0); +} + +int +main(int argc, char **argv){ + if (argc < 2){ + show_usage(argc, argv); + } + + bool32 recursive = match(argv[1], "-R"); + if (recursive && argc < 3){ + show_usage(argc, argv); + } + + int32_t size = (256 << 20); + void *mem = malloc(size); + Partition part_ = make_part(mem, size); + Partition *part = &part_; + + int32_t start_i = 1; + if (recursive){ + start_i = 2; + } + + for (int32_t i = start_i; i < argc; ++i){ + Filename_Character *root_name = encode(part, argv[i]); + parse_files_in_directory(part, root_name, recursive); + } + + return(0); +} + +// BOTTOM + diff --git a/4coder_project_commands.cpp b/4coder_project_commands.cpp index 30f0e48a..dde3e1b0 100644 --- a/4coder_project_commands.cpp +++ b/4coder_project_commands.cpp @@ -162,7 +162,9 @@ open_all_code(Application_Links *app, String dir){ open_all_files_with_extension_internal(app, dir, extension_list, extension_count, false); } -CUSTOM_COMMAND_SIG(open_all_code){ +CUSTOM_COMMAND_SIG(open_all_code) +CUSTOM_DOC("Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.") +{ int32_t extension_count = 0; char **extension_list = get_current_project_extensions(&extension_count); open_all_files_with_extension(app, &global_part, extension_list, extension_count, false); @@ -175,13 +177,17 @@ open_all_code_recursive(Application_Links *app, String dir){ open_all_files_with_extension_internal(app, dir, extension_list, extension_count, true); } -CUSTOM_COMMAND_SIG(open_all_code_recursive){ +CUSTOM_COMMAND_SIG(open_all_code_recursive) +CUSTOM_DOC("Works as open_all_code but also runs in all subdirectories.") +{ int32_t extension_count = 0; char **extension_list = get_current_project_extensions(&extension_count); open_all_files_with_extension(app, &global_part, extension_list, extension_count, true); } -CUSTOM_COMMAND_SIG(close_all_code){ +CUSTOM_COMMAND_SIG(close_all_code) +CUSTOM_DOC("Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.") +{ int32_t extension_count = 0; char **extension_list = get_current_project_extensions(&extension_count); close_all_files_with_extension(app, &global_part, extension_list, extension_count); @@ -391,7 +397,9 @@ load_project_from_config_data(Application_Links *app, Partition *part, char *con end_temp_memory(temp); } -CUSTOM_COMMAND_SIG(load_project){ +CUSTOM_COMMAND_SIG(load_project) +CUSTOM_DOC("Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.") +{ Partition *part = &global_part; Temp_Memory temp = begin_temp_memory(part); @@ -513,7 +521,9 @@ exec_project_fkey_command(Application_Links *app, int32_t command_ind){ } } -CUSTOM_COMMAND_SIG(project_fkey_command){ +CUSTOM_COMMAND_SIG(project_fkey_command) +CUSTOM_DOC("Run an 'fkey command' configured in a project.4coder file. Determines the index of the 'fkey command' by which function key or numeric key was pressed to trigger the command.") +{ User_Input input = get_command_input(app); if (input.type == UserInputKey){ bool32 got_ind = false; @@ -537,7 +547,9 @@ CUSTOM_COMMAND_SIG(project_fkey_command){ } } -CUSTOM_COMMAND_SIG(project_go_to_root_directory){ +CUSTOM_COMMAND_SIG(project_go_to_root_directory) +CUSTOM_DOC("Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns.") +{ if (current_project.loaded){ directory_set_hot(app, current_project.dir, current_project.dir_len); } @@ -592,7 +604,9 @@ project_is_setup(Application_Links *app, char *dir, int32_t dir_len, int32_t dir // TODO(allen): Stop using stdio.h, switch to a 4coder buffer API for all file manipulation. #include -CUSTOM_COMMAND_SIG(setup_new_project){ +CUSTOM_COMMAND_SIG(setup_new_project) +CUSTOM_DOC("Queries the user for several configuration options and initializes a new 4coder project with build scripts for every OS.") +{ char space[4096]; String str = make_fixed_width_string(space); str.size = directory_get_hot(app, str.str, str.memory_size); diff --git a/4coder_remapping_commands.cpp b/4coder_remapping_commands.cpp index ba8ca4bb..477bb014 100644 --- a/4coder_remapping_commands.cpp +++ b/4coder_remapping_commands.cpp @@ -30,7 +30,6 @@ default_keys(Bind_Helper *context){ bind(context, 'o', MDFR_ALT, open_in_other); bind(context, 'k', MDFR_CTRL, interactive_kill_buffer); bind(context, 'i', MDFR_CTRL, interactive_switch_buffer); - bind(context, 'w', MDFR_CTRL, save_as); bind(context, 'h', MDFR_CTRL, project_go_to_root_directory); bind(context, 'S', MDFR_CTRL, save_all_dirty_buffers); @@ -206,7 +205,6 @@ mac_default_keys(Bind_Helper *context){ bind(context, 'o', MDFR_CTRL, open_in_other); bind(context, 'k', MDFR_CMND, interactive_kill_buffer); bind(context, 'i', MDFR_CMND, interactive_switch_buffer); - bind(context, 'w', MDFR_CMND, save_as); bind(context, 'h', MDFR_CMND, project_go_to_root_directory); bind(context, 'S', MDFR_CMND, save_all_dirty_buffers); @@ -384,7 +382,9 @@ get_context_on_global_part(void){ return(result); } -CUSTOM_COMMAND_SIG(set_bindings_choose){ +CUSTOM_COMMAND_SIG(set_bindings_choose) +CUSTOM_DOC("Remap keybindings using the 'choose' mapping rule.") +{ #if defined(_WIN32) || defined(__linux__) set_bindings_default(app); @@ -396,7 +396,9 @@ CUSTOM_COMMAND_SIG(set_bindings_choose){ #endif } -CUSTOM_COMMAND_SIG(set_bindings_default){ +CUSTOM_COMMAND_SIG(set_bindings_default) +CUSTOM_DOC("Remap keybindings using the 'default' mapping rule.") +{ Temp_Memory temp = begin_temp_memory(&global_part); Bind_Helper context = get_context_on_global_part(); @@ -408,7 +410,9 @@ CUSTOM_COMMAND_SIG(set_bindings_default){ end_temp_memory(temp); } -CUSTOM_COMMAND_SIG(set_bindings_mac_default){ +CUSTOM_COMMAND_SIG(set_bindings_mac_default) +CUSTOM_DOC("Remap keybindings using the 'mac-default' mapping rule.") +{ Temp_Memory temp = begin_temp_memory(&global_part); Bind_Helper context = get_context_on_global_part(); diff --git a/4coder_search.cpp b/4coder_search.cpp index 7ee96382..7dd2d54c 100644 --- a/4coder_search.cpp +++ b/4coder_search.cpp @@ -651,28 +651,36 @@ generic_search_all_buffers(Application_Links *app, General_Memory *general, Part // List Commands // -CUSTOM_COMMAND_SIG(list_all_locations){ +CUSTOM_COMMAND_SIG(list_all_locations) +CUSTOM_DOC("Queries the user for a string and lists all exact case-sensitive matches found in all open buffers.") +{ Query_Bar bar; get_search_all_string(app, &bar); if (bar.string.size == 0) return; generic_search_all_buffers(app, &global_general, &global_part, bar.string, SearchFlag_MatchWholeWord); } -CUSTOM_COMMAND_SIG(list_all_substring_locations){ +CUSTOM_COMMAND_SIG(list_all_substring_locations) +CUSTOM_DOC("Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.") +{ Query_Bar bar; get_search_all_string(app, &bar); if (bar.string.size == 0) return; generic_search_all_buffers(app, &global_general, &global_part, bar.string, SearchFlag_MatchSubstring); } -CUSTOM_COMMAND_SIG(list_all_locations_case_insensitive){ +CUSTOM_COMMAND_SIG(list_all_locations_case_insensitive) +CUSTOM_DOC("Queries the user for a string and lists all exact case-insensitive matches found in all open buffers.") +{ Query_Bar bar; get_search_all_string(app, &bar); if (bar.string.size == 0) return; generic_search_all_buffers(app, &global_general, &global_part, bar.string, SearchFlag_CaseInsensitive | SearchFlag_MatchWholeWord); } -CUSTOM_COMMAND_SIG(list_all_substring_locations_case_insensitive){ +CUSTOM_COMMAND_SIG(list_all_substring_locations_case_insensitive) +CUSTOM_DOC("Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.") +{ Query_Bar bar; get_search_all_string(app, &bar); if (bar.string.size == 0) return; @@ -713,11 +721,15 @@ list_all_locations_of_identifier_parameters(Application_Links *app, bool32 subst } } -CUSTOM_COMMAND_SIG(list_all_locations_of_identifier){ +CUSTOM_COMMAND_SIG(list_all_locations_of_identifier) +CUSTOM_DOC("Reads a token or word under the cursor and lists all exact case-sensitive mathces in all open buffers.") +{ list_all_locations_of_identifier_parameters(app, false, false); } -CUSTOM_COMMAND_SIG(list_all_locations_of_identifier_case_insensitive){ +CUSTOM_COMMAND_SIG(list_all_locations_of_identifier_case_insensitive) +CUSTOM_DOC("Reads a token or word under the cursor and lists all exact case-insensitive mathces in all open buffers.") +{ list_all_locations_of_identifier_parameters(app, false, true); } @@ -737,7 +749,9 @@ struct Word_Complete_State{ static Word_Complete_State complete_state = {0}; -CUSTOM_COMMAND_SIG(word_complete){ +CUSTOM_COMMAND_SIG(word_complete) +CUSTOM_DOC("Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.") +{ View_Summary view = get_active_view(app, AccessOpen); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); diff --git a/4coder_system_command.cpp b/4coder_system_command.cpp index 19382778..69a9e3bf 100644 --- a/4coder_system_command.cpp +++ b/4coder_system_command.cpp @@ -11,7 +11,9 @@ TYPE: 'drop-in-command-pack' #include "4coder_default_framework.h" -CUSTOM_COMMAND_SIG(execute_previous_cli){ +CUSTOM_COMMAND_SIG(execute_previous_cli) +CUSTOM_DOC("If the command execute_any_cli has already been used, this will execute a CLI reusing the most recent buffer name and command.") +{ String out_buffer = make_string_slowly(out_buffer_space); String cmd = make_string_slowly(command_space); String hot_directory = make_string_slowly(hot_directory_space); @@ -25,7 +27,8 @@ CUSTOM_COMMAND_SIG(execute_previous_cli){ } } -CUSTOM_COMMAND_SIG(execute_any_cli){ +CUSTOM_COMMAND_SIG(execute_any_cli) +CUSTOM_DOC("Queries for an output buffer name and system command, runs the system command as a CLI and prints the output to the specified buffer."){ Query_Bar bar_out = {0}; Query_Bar bar_cmd = {0}; diff --git a/build_metadata.bat b/build_metadata.bat new file mode 100644 index 00000000..7bf77907 --- /dev/null +++ b/build_metadata.bat @@ -0,0 +1,13 @@ +@echo off + +SET OPTS=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512 /wd4610 /wd4390 /WX +SET OPTS=%OPTS% /GR- /EHa- /nologo /FC + +pushd ..\build +cl %OPTS% ..\code\4coder_metadata_generator.cpp /Zi /Femetadata_generator +popd + +SET CODE_HOME=%~dp0 +..\build\metadata_generator -R "%CODE_HOME%" + + diff --git a/power/4coder_experiments.cpp b/power/4coder_experiments.cpp index 92cd5bbc..27aae2b4 100644 --- a/power/4coder_experiments.cpp +++ b/power/4coder_experiments.cpp @@ -28,7 +28,9 @@ get_line_y(Application_Links *app, View_Summary *view, int32_t line){ return(y); } -CUSTOM_COMMAND_SIG(kill_rect){ +CUSTOM_COMMAND_SIG(kill_rect) +CUSTOM_DOC("Delete characters in a rectangular region. Range testing is done by unwrapped-xy coordinates.") +{ View_Summary view = get_active_view(app, AccessOpen); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); @@ -117,7 +119,9 @@ it just seems like the wrong way to do it, so I'll stop without doing multi-cursor for now. */ -CUSTOM_COMMAND_SIG(multi_line_edit){ +CUSTOM_COMMAND_SIG(multi_line_edit) +CUSTOM_DOC("Begin multi-line mode. In multi-line mode characters are inserted at every line between the mark and cursor. All characters are inserted at the same character offset into the line. This mode uses line_char coordinates.") +{ Partition *part = &global_part; View_Summary view = get_active_view(app, AccessOpen); @@ -541,7 +545,9 @@ view_set_to_region(Application_Links *app, View_Summary *view, int32_t major_pos static float scope_center_threshold = 0.75f; -CUSTOM_COMMAND_SIG(highlight_surrounding_scope){ +CUSTOM_COMMAND_SIG(highlight_surrounding_scope) +CUSTOM_DOC("Finds the scope enclosed by '{' '}' surrounding the cursor and puts the cursor and mark on the '{' and '}'.") +{ uint32_t access = AccessProtected; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -560,8 +566,9 @@ CUSTOM_COMMAND_SIG(highlight_surrounding_scope){ } } -// TODO(allen): These aren't super top notch yet (the ones about children and siblings). I am not sure I want them around anyway, because it's not that fluid feeling even when it works. -CUSTOM_COMMAND_SIG(highlight_first_child_scope){ +CUSTOM_COMMAND_SIG(highlight_next_scope_absolute) +CUSTOM_DOC("Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.") +{ uint32_t access = AccessProtected; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -577,55 +584,9 @@ CUSTOM_COMMAND_SIG(highlight_first_child_scope){ } } -CUSTOM_COMMAND_SIG(highlight_next_sibling_scope){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - - int32_t start_pos = view.cursor.pos; - int32_t top = 0, bottom = 0; - if (find_next_scope(app, &buffer, start_pos, FindScope_NextSibling, &top)){ - if (find_scope_bottom(app, &buffer, top, FindScope_EndOfToken, &bottom)){ - view_set_cursor(app, &view, seek_pos(top), true); - view_set_mark(app, &view, seek_pos(bottom)); - view_set_to_region(app, &view, top, bottom, scope_center_threshold); - } - } -} - -CUSTOM_COMMAND_SIG(highlight_prev_sibling_scope){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - - int32_t start_pos = view.cursor.pos; - int32_t top = 0, bottom = 0; - if (find_prev_scope(app, &buffer, start_pos, FindScope_NextSibling, &top)){ - if (find_scope_bottom(app, &buffer, top, FindScope_EndOfToken, &bottom)){ - view_set_cursor(app, &view, seek_pos(top), true); - view_set_mark(app, &view, seek_pos(bottom)); - view_set_to_region(app, &view, top, bottom, scope_center_threshold); - } - } -} - -CUSTOM_COMMAND_SIG(highlight_next_scope_absolute){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - - int32_t start_pos = view.cursor.pos; - int32_t top = 0, bottom = 0; - if (find_next_scope(app, &buffer, start_pos, 0, &top)){ - if (find_scope_bottom(app, &buffer, top, FindScope_EndOfToken, &bottom)){ - view_set_cursor(app, &view, seek_pos(top), true); - view_set_mark(app, &view, seek_pos(bottom)); - view_set_to_region(app, &view, top, bottom, scope_center_threshold); - } - } -} - -CUSTOM_COMMAND_SIG(highlight_prev_scope_absolute){ +CUSTOM_COMMAND_SIG(highlight_prev_scope_absolute) +CUSTOM_DOC("Finds the first scope started by '{' before the cursor and puts the cursor and mark on the '{' and '}'.") +{ uint32_t access = AccessProtected; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -641,7 +602,9 @@ CUSTOM_COMMAND_SIG(highlight_prev_scope_absolute){ } } -CUSTOM_COMMAND_SIG(place_in_scope){ +CUSTOM_COMMAND_SIG(place_in_scope) +CUSTOM_DOC("Wraps the code contained in the range between cursor and mark with a new curly brace scope.") +{ uint32_t access = AccessOpen; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -715,7 +678,9 @@ CUSTOM_COMMAND_SIG(place_in_scope){ } } -CUSTOM_COMMAND_SIG(delete_current_scope){ +CUSTOM_COMMAND_SIG(delete_current_scope) +CUSTOM_DOC("Deletes the braces surrounding the currently selected scope. Leaves the contents within the scope.") +{ uint32_t access = AccessOpen; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -972,7 +937,9 @@ find_whole_statement_down(Application_Links *app, Buffer_Summary *buffer, int32_ return(result); } -CUSTOM_COMMAND_SIG(scope_absorb_down){ +CUSTOM_COMMAND_SIG(scope_absorb_down) +CUSTOM_DOC("If a scope is currently selected, and a statement or block statement is present below the current scope, the statement is moved into the scope.") +{ uint32_t access = AccessOpen; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -1045,7 +1012,9 @@ CUSTOM_COMMAND_SIG(scope_absorb_down){ // NOTE(allen): Some basic code manipulation ideas. -CUSTOM_COMMAND_SIG(rename_parameter){ +CUSTOM_COMMAND_SIG(rename_parameter) +CUSTOM_DOC("If the cursor is found to be on the name of a function parameter in the signature of a function definition, all occurences within the scope of the function will be replaced with a new provided string.") +{ uint32_t access = AccessOpen; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); @@ -1196,7 +1165,9 @@ CUSTOM_COMMAND_SIG(rename_parameter){ end_temp_memory(temp); } -CUSTOM_COMMAND_SIG(write_explicit_enum_values){ +CUSTOM_COMMAND_SIG(write_explicit_enum_values) +CUSTOM_DOC("If the cursor is found to be on the '{' of an enum definition, the values of the enum will be filled in sequentially starting from zero. Existing values are overwritten.") +{ uint32_t access = AccessOpen; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); diff --git a/power/4coder_miblo_numbers.cpp b/power/4coder_miblo_numbers.cpp index c42f2f97..33ad7bef 100644 --- a/power/4coder_miblo_numbers.cpp +++ b/power/4coder_miblo_numbers.cpp @@ -100,7 +100,9 @@ get_numeric_at_cursor(Application_Links *app, Buffer_Summary *buffer, int32_t po return(result); } -CUSTOM_COMMAND_SIG(miblo_increment_basic){ +CUSTOM_COMMAND_SIG(miblo_increment_basic) +CUSTOM_DOC("Increment an integer under the cursor by one.") +{ View_Summary view = get_active_view(app, AccessOpen); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); @@ -114,7 +116,9 @@ CUSTOM_COMMAND_SIG(miblo_increment_basic){ } } -CUSTOM_COMMAND_SIG(miblo_decrement_basic){ +CUSTOM_COMMAND_SIG(miblo_decrement_basic) +CUSTOM_DOC("Decrement an integer under the cursor by one.") +{ View_Summary view = get_active_view(app, AccessOpen); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); @@ -379,19 +383,27 @@ miblo_time_stamp_alter(Application_Links *app, int32_t unit_type, int32_t amt){ } } -CUSTOM_COMMAND_SIG(miblo_increment_time_stamp){ +CUSTOM_COMMAND_SIG(miblo_increment_time_stamp) +CUSTOM_DOC("Increment a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss") +{ miblo_time_stamp_alter(app, MIBLO_SECOND, 1); } -CUSTOM_COMMAND_SIG(miblo_decrement_time_stamp){ +CUSTOM_COMMAND_SIG(miblo_decrement_time_stamp) +CUSTOM_DOC("Decrement a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss") +{ miblo_time_stamp_alter(app, MIBLO_SECOND, -1); } -CUSTOM_COMMAND_SIG(miblo_increment_time_stamp_minute){ +CUSTOM_COMMAND_SIG(miblo_increment_time_stamp_minute) +CUSTOM_DOC("Increment a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss") +{ miblo_time_stamp_alter(app, MIBLO_MINUTE, 1); } -CUSTOM_COMMAND_SIG(miblo_decrement_time_stamp_minute){ +CUSTOM_COMMAND_SIG(miblo_decrement_time_stamp_minute) +CUSTOM_DOC("Decrement a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss") +{ miblo_time_stamp_alter(app, MIBLO_MINUTE, -1); } diff --git a/project.4coder b/project.4coder index 7ccf28ce..d409ec08 100644 --- a/project.4coder +++ b/project.4coder @@ -5,7 +5,7 @@ fkey_command_win[1] = {"echo build: x64 & build.bat", "*compilation*" , true , fkey_command_win[2] = {"build_site.bat" , "*site*" , false, true }; fkey_command_win[3] = {"build_string.bat" , "*compilation*" , true , true }; fkey_command_win[4] = {"echo build: x86 & build.bat /DDEV_BUILD_X86" , "*compilation*", true, true }; -fkey_command_win[5] = {"..\\misc\\run.bat" , "*run*" , false, false }; +fkey_command_win[5] = {"build_metadata.bat" , "*compilation*" , true , true }; fkey_command_win[6] = {"run_profile.bat" , "*profile*" , false, true }; fkey_command_win[12] = {"package.bat" , "*package*" , false, true };