Merge branch 'master' of https://bitbucket.org/4coder/4coder
						commit
						5aceb5b910
					
				|  | @ -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.
 | // 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_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.) */ | /* DOC(Generic_Command acts as a name for a command, and can name an internal command or a custom command.) */ | ||||||
| UNION Generic_Command{ | UNION Generic_Command{ | ||||||
|  |  | ||||||
|  | @ -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); |     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; |     uint32_t access = AccessOpen; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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); |     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; |     uint32_t access = AccessOpen; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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); |     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; |     uint32_t access = AccessOpen; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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); |     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); |     exec_command(app, write_character); | ||||||
|      |      | ||||||
|     uint32_t access = AccessOpen; |     uint32_t access = AccessOpen; | ||||||
|  |  | ||||||
|  | @ -19,7 +19,9 @@ TYPE: 'drop-in-command-pack' | ||||||
| // Fundamental Editing Commands
 | // 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; |     uint32_t access = AccessOpen; | ||||||
|     View_Summary view = get_active_view(app, access); |     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; |     uint32_t access = AccessOpen; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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; |     uint32_t access = AccessOpen; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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_Summary view = get_active_view(app, AccessProtected); | ||||||
|      |      | ||||||
|     view_set_mark(app, &view, seek_pos(view.cursor.pos)); |     view_set_mark(app, &view, seek_pos(view.cursor.pos)); | ||||||
|     view_set_cursor(app, &view, seek_pos(view.cursor.pos), 1); |     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); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|      |      | ||||||
|     int32_t cursor = view.cursor.pos; |     int32_t cursor = view.cursor.pos; | ||||||
|  | @ -97,7 +107,9 @@ CUSTOM_COMMAND_SIG(cursor_mark_swap){ | ||||||
|     view_set_mark(app, &view, seek_pos(cursor)); |     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; |     uint32_t access = AccessOpen; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); |     Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); | ||||||
|  | @ -110,7 +122,9 @@ CUSTOM_COMMAND_SIG(delete_range){ | ||||||
| // Basic Navigation Commands
 | // 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); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|      |      | ||||||
|     i32_Rect region = view.file_region; |     i32_Rect region = view.file_region; | ||||||
|  | @ -123,7 +137,9 @@ CUSTOM_COMMAND_SIG(center_view){ | ||||||
|     view_set_scroll(app, &view, scroll); |     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); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|      |      | ||||||
|     GUI_Scroll_Vars scroll = view.scroll_vars; |     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); |     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; |     uint32_t access = AccessProtected; | ||||||
|     View_Summary view = get_active_view(app, access); |     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; |     uint32_t access = AccessProtected; | ||||||
|     View_Summary view = get_active_view(app, access); |     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); |     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); |     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); |     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); |     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); |     move_vertical(app, 10.f); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -225,14 +253,18 @@ get_page_jump(View_Summary *view){ | ||||||
|     return(page_jump); |     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; |     uint32_t access = AccessProtected; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     float page_jump = get_page_jump(&view); |     float page_jump = get_page_jump(&view); | ||||||
|     move_vertical(app, -page_jump); |     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; |     uint32_t access = AccessProtected; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     float page_jump = get_page_jump(&view); |     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; |     uint32_t access = AccessProtected; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     int32_t new_pos = view.cursor.character_pos - 1; |     int32_t new_pos = view.cursor.character_pos - 1; | ||||||
|     view_set_cursor(app, &view, seek_character_pos(new_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; |     uint32_t access = AccessProtected; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     int32_t new_pos = view.cursor.character_pos + 1; |     int32_t new_pos = view.cursor.character_pos + 1; | ||||||
|     view_set_cursor(app, &view, seek_character_pos(new_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); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); |     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); | ||||||
|     view_set_cursor(app, &view, seek_character_pos(0), true); |     view_set_cursor(app, &view, seek_character_pos(0), true); | ||||||
|  | @ -265,7 +303,9 @@ CUSTOM_COMMAND_SIG(select_all){ | ||||||
| // Long Seeks
 | // 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; |     uint32_t access = AccessProtected; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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); |     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; |     uint32_t access = AccessProtected; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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); |     view_set_cursor(app, &view, seek_pos(new_pos), true); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| CUSTOM_COMMAND_SIG(seek_end_of_textual_line){ | CUSTOM_COMMAND_SIG(seek_beginning_of_textual_line) | ||||||
|     uint32_t access = AccessProtected; | CUSTOM_DOC("Seeks the cursor to the beginning of the line across all text.") | ||||||
|     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){ |  | ||||||
|     uint32_t access = AccessProtected; |     uint32_t access = AccessProtected; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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); |     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); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|      |      | ||||||
|     float y = view.cursor.wrapped_y; |     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); |     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); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|      |      | ||||||
|     float y = view.cursor.wrapped_y; |     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); |     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_whitespace_up); | ||||||
|     exec_command(app, seek_end_of_line); |     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_whitespace_down); | ||||||
|     exec_command(app, seek_end_of_line); |     exec_command(app, seek_end_of_line); | ||||||
| } | } | ||||||
|  | @ -338,7 +392,9 @@ CUSTOM_COMMAND_SIG(seek_whitespace_down_end_line){ | ||||||
| // Fancy Editing
 | // 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); |     View_Summary view = get_active_view(app, AccessOpen); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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); |     View_Summary view = get_active_view(app, AccessOpen); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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
 |     // TODO(allen): This command always iterates accross the entire
 | ||||||
|     // buffer, so streaming it is actually the wrong call.  Rewrite this
 |     // buffer, so streaming it is actually the wrong call.  Rewrite this
 | ||||||
|     // to minimize calls to buffer_read_range.
 |     // to minimize calls to buffer_read_range.
 | ||||||
|  | @ -440,13 +500,17 @@ CUSTOM_COMMAND_SIG(clean_all_lines){ | ||||||
| // Basic Panel Management
 | // 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); |     View_Summary view = get_active_view(app, AccessAll); | ||||||
|     get_view_next_looped(app, &view, AccessAll); |     get_view_next_looped(app, &view, AccessAll); | ||||||
|     set_active_view(app, &view); |     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); |     View_Summary view = get_active_view(app, AccessAll); | ||||||
|     close_view(app, &view); |     close_view(app, &view); | ||||||
| } | } | ||||||
|  | @ -456,36 +520,46 @@ CUSTOM_COMMAND_SIG(close_panel){ | ||||||
| // Common Settings Commands
 | // 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_Summary view = get_active_view(app, AccessAll); | ||||||
|     view_set_setting(app, &view, ViewSetting_ShowScrollbar, true); |     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_Summary view = get_active_view(app, AccessAll); | ||||||
|     view_set_setting(app, &view, ViewSetting_ShowScrollbar, false); |     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_Summary view = get_active_view(app, AccessAll); | ||||||
|     view_set_setting(app, &view, ViewSetting_ShowFileBar, true); |     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_Summary view = get_active_view(app, AccessAll); | ||||||
|     view_set_setting(app, &view, ViewSetting_ShowFileBar, false); |     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); |     View_Summary view = get_active_view(app, AccessAll); | ||||||
|     bool32 value; |     bool32 value; | ||||||
|     view_get_setting(app, &view, ViewSetting_ShowFileBar, &value); |     view_get_setting(app, &view, ViewSetting_ShowFileBar, &value); | ||||||
|     view_set_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_DOC("Toggles the current buffer's line wrapping status.") | ||||||
| CUSTOM_COMMAND_SIG(toggle_line_wrap){ | { | ||||||
|     View_Summary view = get_active_view(app, AccessProtected); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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); |     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); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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); |     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); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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); |     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); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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); |     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_Summary view = get_active_view(app, AccessProtected); | ||||||
|     view_set_setting(app, &view, ViewSetting_ShowWhitespace, !view.show_whitespace); |     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); |     View_Summary view = get_active_view(app, AccessOpen); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); |     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); | ||||||
|     buffer_set_setting(app, &buffer, BufferSetting_Eol, 1); |     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); |     View_Summary view = get_active_view(app, AccessOpen); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); |     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); | ||||||
|     buffer_set_setting(app, &buffer, BufferSetting_Eol, 0); |     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); |     send_exit_signal(app); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -545,7 +633,9 @@ CUSTOM_COMMAND_SIG(exit_4coder){ | ||||||
| // Interactive Commands
 | // 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; |     uint32_t access = AccessProtected; | ||||||
|      |      | ||||||
|     Query_Bar bar = {0}; |     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); |     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}; |     String query = {0}; | ||||||
|     isearch(app, false, query); |     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}; |     String query = {0}; | ||||||
|     isearch(app, true, query); |     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); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); |     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); | ||||||
|      |      | ||||||
|  | @ -735,7 +831,9 @@ CUSTOM_COMMAND_SIG(search_identifier){ | ||||||
|     isearch(app, false, query); |     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); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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); |     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; |     Query_Bar replace; | ||||||
|     char replace_space[1024]; |     char replace_space[1024]; | ||||||
|     replace.prompt = make_lit_string("Replace: "); |     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); |     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; |     Query_Bar replace; | ||||||
|     char replace_space[1024]; |     char replace_space[1024]; | ||||||
|     replace.prompt = make_lit_string("Replace: "); |     replace.prompt = make_lit_string("Replace: "); | ||||||
|  | @ -843,7 +945,9 @@ CUSTOM_COMMAND_SIG(query_replace){ | ||||||
|     query_replace(app, &view, &buffer, pos, r, w); |     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); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); |     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); | ||||||
|      |      | ||||||
|  | @ -884,7 +988,9 @@ CUSTOM_COMMAND_SIG(query_replace_identifier){ | ||||||
| // File Handling Commands
 | // 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); |     for (Buffer_Summary buffer = get_buffer_first(app, AccessOpen); | ||||||
|          buffer.exists; |          buffer.exists; | ||||||
|          get_buffer_next(app, &buffer, AccessOpen)){ |          get_buffer_next(app, &buffer, AccessOpen)){ | ||||||
|  | @ -898,55 +1004,75 @@ CUSTOM_COMMAND_SIG(save_all_dirty_buffers){ | ||||||
| // cmdid wrappers
 | // cmdid wrappers
 | ||||||
| //
 | //
 | ||||||
| 
 | 
 | ||||||
| CUSTOM_COMMAND_SIG(undo){ | CUSTOM_COMMAND_SIG(undo) | ||||||
|  | CUSTOM_DOC("Advances backwards through the undo history.") | ||||||
|  | { | ||||||
|     exec_command(app, cmdid_undo); |     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); |     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); |     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); |     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); |     exec_command(app, cmdid_interactive_open_or_new); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| CUSTOM_COMMAND_SIG(save_as){ | CUSTOM_COMMAND_SIG(interactive_switch_buffer) | ||||||
|     exec_command(app, cmdid_save_as); | CUSTOM_DOC("Interactively switch to an open buffer.") | ||||||
| } | { | ||||||
| 
 |  | ||||||
| CUSTOM_COMMAND_SIG(interactive_switch_buffer){ |  | ||||||
|     exec_command(app, cmdid_interactive_switch_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); |     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); |     exec_command(app, cmdid_reopen); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| CUSTOM_COMMAND_SIG(save){ | CUSTOM_COMMAND_SIG(save) | ||||||
|  | CUSTOM_DOC("Saves the current buffer.") | ||||||
|  | { | ||||||
|     exec_command(app, cmdid_save); |     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); |     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); |     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); |     exec_command(app, cmdid_open_debug); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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; |     uint32_t access = AccessAll; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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")); |     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; |     uint32_t access = AccessAll; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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*")); |     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); |     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); |     View_Summary view = open_special_note_view(app, false); | ||||||
|      |      | ||||||
|     if (!view.exists){ |     if (!view.exists){ | ||||||
|  |  | ||||||
|  | @ -49,21 +49,27 @@ clipboard_cut(Application_Links *app, int32_t start, int32_t end, Buffer_Summary | ||||||
|     return(result); |     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; |     uint32_t access = AccessProtected; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Range range = get_range(&view); |     Range range = get_range(&view); | ||||||
|     clipboard_copy(app, range.min, range.max, 0, access); |     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; |     uint32_t access = AccessOpen; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Range range = get_range(&view); |     Range range = get_range(&view); | ||||||
|     clipboard_cut(app, range.min, range.max, 0, access); |     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; |     uint32_t access = AccessOpen; | ||||||
|     int32_t count = clipboard_count(app, 0); |     int32_t count = clipboard_count(app, 0); | ||||||
|     if (count > 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; |     uint32_t access = AccessOpen; | ||||||
|     int32_t count = clipboard_count(app, 0); |     int32_t count = clipboard_count(app, 0); | ||||||
|     if (count > 0){ |     if (count > 0){ | ||||||
|  |  | ||||||
|  | @ -122,7 +122,9 @@ open_special_note_view(Application_Links *app, bool32 create_if_not_exist = true | ||||||
|     return(special_view); |     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_Summary view = get_active_view(app, AccessAll); | ||||||
|     View_ID original_view_id = view.view_id; |     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_Summary view = get_active_view(app, AccessAll); | ||||||
|     View_ID original_view_id = view.view_id; |     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 view = get_active_view(app, AccessAll); | ||||||
|     View_Summary new_view = open_view(app, &view, ViewSplit_Right); |     View_Summary new_view = open_view(app, &view, ViewSplit_Right); | ||||||
|     new_view_settings(app, &new_view); |     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 view = get_active_view(app, AccessAll); | ||||||
|     View_Summary new_view = open_view(app, &view, ViewSplit_Bottom); |     View_Summary new_view = open_view(app, &view, ViewSplit_Bottom); | ||||||
|     new_view_settings(app, &new_view); |     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); |     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); |     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); |     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)); |     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}; |     Query_Bar bar = {0}; | ||||||
|     char space[1024]; |     char space[1024]; | ||||||
|     bar.prompt = make_lit_string("Map Name: "); |     bar.prompt = make_lit_string("Map Name: "); | ||||||
|  |  | ||||||
|  | @ -11,29 +11,53 @@ TYPE: 'major-system-include' | ||||||
| 
 | 
 | ||||||
| #include "4coder_API/custom.h" | #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_default_framework.h" | ||||||
| #include "4coder_base_commands.cpp" | #include "4coder_base_commands.cpp" | ||||||
| #include "4coder_auto_indent.cpp" | #include "4coder_auto_indent.cpp" | ||||||
| #include "4coder_search.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_clipboard.cpp" | ||||||
| #include "4coder_system_command.cpp" | #include "4coder_system_command.cpp" | ||||||
| #include "4coder_build_commands.cpp" | #include "4coder_build_commands.cpp" | ||||||
| #include "4coder_project_commands.cpp" | #include "4coder_project_commands.cpp" | ||||||
| #include "4coder_function_list.cpp" | #include "4coder_function_list.cpp" | ||||||
| 
 | 
 | ||||||
| #if !defined(USE_OLD_STYLE_JUMPS) | // NOTE(allen): Define USE_OLD_STYLE_JUMPS before 4coder_default_include.cpp to get
 | ||||||
| #undef FCODER_JUMP_COMMANDS | // the direct jumps (instead of sticky jumps).
 | ||||||
| #include "4coder_sticky_jump.cpp" | #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 | #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_default_hooks.cpp" | ||||||
| 
 | 
 | ||||||
| #include "4coder_helper/4coder_bind_helper.h" | #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 right true | ||||||
| #define left false | #define left false | ||||||
| 
 | 
 | ||||||
| CUSTOM_COMMAND_SIG(seek_whitespace_right){ basic_seek(app, right, BoundaryWhitespace); } | CUSTOM_COMMAND_SIG(seek_whitespace_right) | ||||||
| CUSTOM_COMMAND_SIG(seek_whitespace_left){ basic_seek(app, left, BoundaryWhitespace); } | CUSTOM_DOC("Seek right for the next boundary between whitespace and non-whitespace.") | ||||||
| CUSTOM_COMMAND_SIG(seek_token_right){ basic_seek(app, right, BoundaryToken); } | { basic_seek(app, right, BoundaryWhitespace); } | ||||||
| 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_whitespace_left) | ||||||
| CUSTOM_COMMAND_SIG(seek_white_or_token_left){basic_seek(app, left, BoundaryToken | BoundaryWhitespace);} | CUSTOM_DOC("Seek left for the next boundary between whitespace and non-whitespace.") | ||||||
| CUSTOM_COMMAND_SIG(seek_alphanumeric_right){ basic_seek(app, right, BoundaryAlphanumeric); } | { basic_seek(app, left, BoundaryWhitespace); } | ||||||
| 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_token_right) | ||||||
| CUSTOM_COMMAND_SIG(seek_alphanumeric_or_camel_left){ basic_seek(app, left, BoundaryAlphanumeric | BoundaryCamelCase); } | 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 right | ||||||
| #undef left | #undef left | ||||||
|  | @ -88,7 +141,9 @@ CUSTOM_COMMAND_SIG(seek_alphanumeric_or_camel_left){ basic_seek(app, left, Bound | ||||||
| // Fast Deletes 
 | // 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; |     uint32_t access = AccessOpen; | ||||||
|      |      | ||||||
|     View_Summary view = get_active_view(app, access); |     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; |     uint32_t access = AccessOpen; | ||||||
|      |      | ||||||
|     View_Summary view = get_active_view(app, access); |     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; |     uint32_t access = AccessOpen; | ||||||
|      |      | ||||||
|     View_Summary view = get_active_view(app, access); |     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); |     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; |     uint32_t access = AccessOpen; | ||||||
|      |      | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|  | @ -154,7 +215,9 @@ CUSTOM_COMMAND_SIG(snipe_token_or_word_right){ | ||||||
| // Line Manipulation
 | // 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); |     View_Summary view = get_active_view(app, AccessOpen); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); |     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); | ||||||
|      |      | ||||||
|  | @ -174,7 +237,9 @@ CUSTOM_COMMAND_SIG(duplicate_line){ | ||||||
|     end_temp_memory(temp); |     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); |     View_Summary view = get_active_view(app, AccessOpen); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); |     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); | ||||||
|      |      | ||||||
|  | @ -194,12 +259,16 @@ CUSTOM_COMMAND_SIG(delete_line){ | ||||||
| // Clipboard + Indent Combo Command
 | // 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, paste); | ||||||
|     exec_command(app, auto_tab_range); |     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, paste_next); | ||||||
|     exec_command(app, auto_tab_range); |     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); |     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}"; |     char text[] = "{\n\n}"; | ||||||
|     int32_t size = sizeof(text) - 1; |     int32_t size = sizeof(text) - 1; | ||||||
|     long_braces(app, text, size); |     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};"; |     char text[] = "{\n\n};"; | ||||||
|     int32_t size = sizeof(text) - 1; |     int32_t size = sizeof(text) - 1; | ||||||
|     long_braces(app, text, size); |     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;"; |     char text[] = "{\n\n}break;"; | ||||||
|     int32_t size = sizeof(text) - 1; |     int32_t size = sizeof(text) - 1; | ||||||
|     long_braces(app, text, size); |     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"; |     char text1[] = "\n#if 0"; | ||||||
|     int32_t size1 = sizeof(text1) - 1; |     int32_t size1 = sizeof(text1) - 1; | ||||||
|      |      | ||||||
|  | @ -325,23 +402,33 @@ write_named_comment_string(Application_Links *app, char *type_string){ | ||||||
|     write_string(app, str); |     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"); |     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"); |     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"); |     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("/*  */")); |     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};")); |     write_string(app, make_lit_string(" = {0};")); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -383,7 +470,9 @@ file_name_in_quotes(Application_Links *app, String *file_name){ | ||||||
|     return(result); |     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]; |     char file_name_[256]; | ||||||
|     String file_name = make_fixed_width_string(file_name_); |     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, change_active_panel); | ||||||
|     exec_command(app, interactive_open_or_new); |     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
 | // File Navigating
 | ||||||
| //
 | //
 | ||||||
|  | @ -458,7 +543,9 @@ get_cpp_matching_file(Application_Links *app, Buffer_Summary buffer, Buffer_Summ | ||||||
|     return(result); |     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); |     View_Summary view = get_active_view(app, AccessAll); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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
 | // 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
 |     // 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
 |     // 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
 |     // as an example you have everything you need to make it work already. You could
 | ||||||
|  |  | ||||||
|  | @ -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; |     uint32_t access = AccessProtected; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); |     Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); | ||||||
|  |  | ||||||
|  | @ -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
 |  | ||||||
| 
 |  | ||||||
|  | @ -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. | compiler errors and jumping to them in the corresponding buffer. | ||||||
| 
 | 
 | ||||||
| TYPE: 'drop-in-command-pack' | TYPE: 'drop-in-command-pack' | ||||||
|  | @ -7,20 +7,23 @@ TYPE: 'drop-in-command-pack' | ||||||
| 
 | 
 | ||||||
| // TOP
 | // TOP
 | ||||||
| 
 | 
 | ||||||
| #if !defined(FCODER_JUMP_PARSING) && !defined(FCODER_JUMP_COMMANDS) | //#if !defined(FCODER_JUMP_PARSING) && !defined(FCODER_JUMP_COMMANDS)
 | ||||||
| #define FCODER_JUMP_PARSING | //#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_default_framework.h" | ||||||
| #include "4coder_helper/4coder_long_seek.h" | #include "4coder_helper/4coder_long_seek.h" | ||||||
| #include "4coder_helper/4coder_helper.h" | #include "4coder_helper/4coder_helper.h" | ||||||
| #include "4coder_helper/4coder_jump_parsing.h" |  | ||||||
| 
 | 
 | ||||||
| #include "4coder_lib/4coder_mem.h" | #include "4coder_lib/4coder_mem.h" | ||||||
| #include "4coder_jumping.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); |     Temp_Memory temp = begin_temp_memory(&global_part); | ||||||
|     View_Summary view = get_active_view(app, AccessProtected); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|      |      | ||||||
|  | @ -39,7 +42,9 @@ CUSTOM_COMMAND_SIG(goto_jump_at_cursor){ | ||||||
|     end_temp_memory(temp); |     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); |     Temp_Memory temp = begin_temp_memory(&global_part); | ||||||
|     View_Summary view = get_active_view(app, AccessProtected); |     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); |     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_repeats = true; | ||||||
|     bool32 skip_sub_errors = true; |     bool32 skip_sub_errors = true; | ||||||
|     int32_t dir = 1; |     int32_t dir = 1; | ||||||
|     seek_jump(app, &global_part, skip_repeats, skip_sub_errors, dir); |     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_repeats = true; | ||||||
|     bool32 skip_sub_errors = true; |     bool32 skip_sub_errors = true; | ||||||
|     int32_t dir = -1; |     int32_t dir = -1; | ||||||
|     seek_jump(app, &global_part, skip_repeats, skip_sub_errors, dir); |     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_repeats = false; | ||||||
|     bool32 skip_sub_errors = true; |     bool32 skip_sub_errors = true; | ||||||
|     int32_t dir = 1; |     int32_t dir = 1; | ||||||
|     seek_jump(app, &global_part, skip_repeats, skip_sub_errors, dir); |     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_repeats = false; | ||||||
|     bool32 skip_sub_errors = true; |     bool32 skip_sub_errors = true; | ||||||
|     int32_t dir = -1; |     int32_t dir = -1; | ||||||
|     seek_jump(app, &global_part, skip_repeats, skip_sub_errors, dir); |     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); |     Temp_Memory temp = begin_temp_memory(&global_part); | ||||||
|     View_Summary view = get_view_for_locked_jump_buffer(app); |     View_Summary view = get_view_for_locked_jump_buffer(app); | ||||||
|     if (view.exists){ |     if (view.exists){ | ||||||
|  | @ -99,12 +114,14 @@ CUSTOM_COMMAND_SIG(goto_first_jump){ | ||||||
| // Insert Newline or Tigger Jump on Read Only Buffer
 | // 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); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); |     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); | ||||||
|      |      | ||||||
|     if (buffer.lock_flags & AccessProtected){ |     if (buffer.lock_flags & AccessProtected){ | ||||||
|         goto_jump_at_cursor(app); |         goto_jump_at_cursor_direct(app); | ||||||
|         lock_jump_buffer(buffer); |         lock_jump_buffer(buffer); | ||||||
|     } |     } | ||||||
|     else{ |     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); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); |     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); | ||||||
|      |      | ||||||
|     if (buffer.lock_flags & 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); |         lock_jump_buffer(buffer); | ||||||
|     } |     } | ||||||
|     else{ |     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 | #endif | ||||||
| 
 | 
 | ||||||
| // BOTTOM
 | // BOTTOM
 | ||||||
|  | @ -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. | compiler errors, sticking markers on jump locations, and jumping to them. | ||||||
| 
 | 
 | ||||||
| TYPE: 'drop-in-command-pack' | TYPE: 'drop-in-command-pack' | ||||||
|  | @ -7,14 +7,16 @@ TYPE: 'drop-in-command-pack' | ||||||
| 
 | 
 | ||||||
| // TOP
 | // 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_STICKY_JUMP | ||||||
| #define FCODER_JUMP_COMMANDS |  | ||||||
| 
 | 
 | ||||||
| #include "4coder_default_framework.h" | #include "4coder_default_framework.h" | ||||||
| #include "4coder_helper/4coder_long_seek.h" | #include "4coder_helper/4coder_long_seek.h" | ||||||
| #include "4coder_helper/4coder_helper.h" | #include "4coder_helper/4coder_helper.h" | ||||||
| #include "4coder_helper/4coder_jump_parsing.h" |  | ||||||
| 
 | 
 | ||||||
| #include "4coder_lib/4coder_mem.h" | #include "4coder_lib/4coder_mem.h" | ||||||
| #include "4coder_jumping.h" | #include "4coder_jumping.h" | ||||||
|  | @ -355,7 +357,9 @@ get_line_from_list(Marker_List *list, int32_t index){ | ||||||
|     return(result); |     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; |     General_Memory *general = &global_general; | ||||||
|     Partition *part = &global_part; |     Partition *part = &global_part; | ||||||
|      |      | ||||||
|  | @ -381,7 +385,9 @@ CUSTOM_COMMAND_SIG(goto_jump_at_cursor){ | ||||||
|     end_temp_memory(temp); |     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; |     General_Memory *general = &global_general; | ||||||
|     Partition *part = &global_part; |     Partition *part = &global_part; | ||||||
|      |      | ||||||
|  | @ -474,7 +480,9 @@ get_locked_jump_state(Application_Links *app, Partition *part, General_Memory *g | ||||||
|     return(result); |     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; |     General_Memory *general = &global_general; | ||||||
|     Partition *part = &global_part; |     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; |     General_Memory *general = &global_general; | ||||||
|     Partition *part = &global_part; |     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; |     General_Memory *general = &global_general; | ||||||
|     Partition *part = &global_part; |     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; |     General_Memory *general = &global_general; | ||||||
|     Partition *part = &global_part; |     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; |     General_Memory *general = &global_general; | ||||||
|     Partition *part = &global_part; |     Partition *part = &global_part; | ||||||
|      |      | ||||||
|  | @ -548,12 +563,14 @@ CUSTOM_COMMAND_SIG(goto_first_jump){ | ||||||
| // Insert Newline or Tigger Jump on Read Only Buffer
 | // 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); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); |     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); | ||||||
|      |      | ||||||
|     if (buffer.lock_flags & AccessProtected){ |     if (buffer.lock_flags & AccessProtected){ | ||||||
|         goto_jump_at_cursor(app); |         goto_jump_at_cursor_sticky(app); | ||||||
|         lock_jump_buffer(buffer); |         lock_jump_buffer(buffer); | ||||||
|     } |     } | ||||||
|     else{ |     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); |     View_Summary view = get_active_view(app, AccessProtected); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); |     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); | ||||||
|      |      | ||||||
|     if (buffer.lock_flags & 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); |         lock_jump_buffer(buffer); | ||||||
|     } |     } | ||||||
|     else{ |     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
 | // End File Hook
 | ||||||
| //
 | //
 | ||||||
							
								
								
									
										192
									
								
								4coder_jumping.h
								
								
								
								
							
							
						
						
									
										192
									
								
								4coder_jumping.h
								
								
								
								
							|  | @ -9,6 +9,196 @@ TYPE: 'helper-routines' | ||||||
| #if !defined(FCODER_JUMPING) | #if !defined(FCODER_JUMPING) | ||||||
| #define 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 | static bool32 | ||||||
| get_jump_buffer(Application_Links *app, Buffer_Summary *buffer, Name_Based_Jump_Location *location){ | 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); |     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 | static bool32 | ||||||
|  |  | ||||||
|  | @ -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 <stdlib.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | typedef int32_t bool32; | ||||||
|  | 
 | ||||||
|  | //// WINDOWS BEGIN ////
 | ||||||
|  | #define UNICODE | ||||||
|  | #include <Windows.h> | ||||||
|  | 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] <root-directory> [<root-directory2> ...]\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
 | ||||||
|  | 
 | ||||||
|  | @ -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); |     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; |     int32_t extension_count = 0; | ||||||
|     char **extension_list = get_current_project_extensions(&extension_count); |     char **extension_list = get_current_project_extensions(&extension_count); | ||||||
|     open_all_files_with_extension(app, &global_part, extension_list, extension_count, false); |     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); |     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; |     int32_t extension_count = 0; | ||||||
|     char **extension_list = get_current_project_extensions(&extension_count); |     char **extension_list = get_current_project_extensions(&extension_count); | ||||||
|     open_all_files_with_extension(app, &global_part, extension_list, extension_count, true); |     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; |     int32_t extension_count = 0; | ||||||
|     char **extension_list = get_current_project_extensions(&extension_count); |     char **extension_list = get_current_project_extensions(&extension_count); | ||||||
|     close_all_files_with_extension(app, &global_part, extension_list, 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); |     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; |     Partition *part = &global_part; | ||||||
|      |      | ||||||
|     Temp_Memory temp = begin_temp_memory(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); |     User_Input input = get_command_input(app); | ||||||
|     if (input.type == UserInputKey){ |     if (input.type == UserInputKey){ | ||||||
|         bool32 got_ind = false; |         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){ |     if (current_project.loaded){ | ||||||
|         directory_set_hot(app, current_project.dir, current_project.dir_len); |         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.
 | // TODO(allen): Stop using stdio.h, switch to a 4coder buffer API for all file manipulation.
 | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| 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]; |     char space[4096]; | ||||||
|     String str = make_fixed_width_string(space); |     String str = make_fixed_width_string(space); | ||||||
|     str.size = directory_get_hot(app, str.str, str.memory_size); |     str.size = directory_get_hot(app, str.str, str.memory_size); | ||||||
|  |  | ||||||
|  | @ -30,7 +30,6 @@ default_keys(Bind_Helper *context){ | ||||||
|     bind(context, 'o', MDFR_ALT, open_in_other); |     bind(context, 'o', MDFR_ALT, open_in_other); | ||||||
|     bind(context, 'k', MDFR_CTRL, interactive_kill_buffer); |     bind(context, 'k', MDFR_CTRL, interactive_kill_buffer); | ||||||
|     bind(context, 'i', MDFR_CTRL, interactive_switch_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, 'h', MDFR_CTRL, project_go_to_root_directory); | ||||||
|     bind(context, 'S', MDFR_CTRL, save_all_dirty_buffers); |     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, 'o', MDFR_CTRL, open_in_other); | ||||||
|     bind(context, 'k', MDFR_CMND, interactive_kill_buffer); |     bind(context, 'k', MDFR_CMND, interactive_kill_buffer); | ||||||
|     bind(context, 'i', MDFR_CMND, interactive_switch_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, 'h', MDFR_CMND, project_go_to_root_directory); | ||||||
|     bind(context, 'S', MDFR_CMND, save_all_dirty_buffers); |     bind(context, 'S', MDFR_CMND, save_all_dirty_buffers); | ||||||
|      |      | ||||||
|  | @ -384,7 +382,9 @@ get_context_on_global_part(void){ | ||||||
|     return(result); |     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__) | #if defined(_WIN32) || defined(__linux__) | ||||||
|      |      | ||||||
|     set_bindings_default(app); |     set_bindings_default(app); | ||||||
|  | @ -396,7 +396,9 @@ CUSTOM_COMMAND_SIG(set_bindings_choose){ | ||||||
| #endif | #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); |     Temp_Memory temp = begin_temp_memory(&global_part); | ||||||
|      |      | ||||||
|     Bind_Helper context = get_context_on_global_part(); |     Bind_Helper context = get_context_on_global_part(); | ||||||
|  | @ -408,7 +410,9 @@ CUSTOM_COMMAND_SIG(set_bindings_default){ | ||||||
|     end_temp_memory(temp); |     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); |     Temp_Memory temp = begin_temp_memory(&global_part); | ||||||
|      |      | ||||||
|     Bind_Helper context = get_context_on_global_part(); |     Bind_Helper context = get_context_on_global_part(); | ||||||
|  |  | ||||||
|  | @ -651,28 +651,36 @@ generic_search_all_buffers(Application_Links *app, General_Memory *general, Part | ||||||
| // List Commands
 | // 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; |     Query_Bar bar; | ||||||
|     get_search_all_string(app, &bar); |     get_search_all_string(app, &bar); | ||||||
|     if (bar.string.size == 0) return; |     if (bar.string.size == 0) return; | ||||||
|     generic_search_all_buffers(app, &global_general, &global_part, bar.string, SearchFlag_MatchWholeWord); |     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; |     Query_Bar bar; | ||||||
|     get_search_all_string(app, &bar); |     get_search_all_string(app, &bar); | ||||||
|     if (bar.string.size == 0) return; |     if (bar.string.size == 0) return; | ||||||
|     generic_search_all_buffers(app, &global_general, &global_part, bar.string, SearchFlag_MatchSubstring); |     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; |     Query_Bar bar; | ||||||
|     get_search_all_string(app, &bar); |     get_search_all_string(app, &bar); | ||||||
|     if (bar.string.size == 0) return; |     if (bar.string.size == 0) return; | ||||||
|     generic_search_all_buffers(app, &global_general, &global_part, bar.string, SearchFlag_CaseInsensitive | SearchFlag_MatchWholeWord); |     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; |     Query_Bar bar; | ||||||
|     get_search_all_string(app, &bar); |     get_search_all_string(app, &bar); | ||||||
|     if (bar.string.size == 0) return; |     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); |     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); |     list_all_locations_of_identifier_parameters(app, false, true); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -737,7 +749,9 @@ struct Word_Complete_State{ | ||||||
| 
 | 
 | ||||||
| static Word_Complete_State complete_state = {0}; | 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); |     View_Summary view = get_active_view(app, AccessOpen); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); |     Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); | ||||||
|      |      | ||||||
|  |  | ||||||
|  | @ -11,7 +11,9 @@ TYPE: 'drop-in-command-pack' | ||||||
| 
 | 
 | ||||||
| #include "4coder_default_framework.h" | #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 out_buffer = make_string_slowly(out_buffer_space); | ||||||
|     String cmd = make_string_slowly(command_space); |     String cmd = make_string_slowly(command_space); | ||||||
|     String hot_directory = make_string_slowly(hot_directory_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_out = {0}; | ||||||
|     Query_Bar bar_cmd = {0}; |     Query_Bar bar_cmd = {0}; | ||||||
|      |      | ||||||
|  |  | ||||||
|  | @ -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%" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @ -28,7 +28,9 @@ get_line_y(Application_Links *app, View_Summary *view, int32_t line){ | ||||||
|     return(y); |     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); |     View_Summary view = get_active_view(app, AccessOpen); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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. | 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; |     Partition *part = &global_part; | ||||||
|      |      | ||||||
|     View_Summary view = get_active_view(app, AccessOpen); |     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; | 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; |     uint32_t access = AccessProtected; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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_next_scope_absolute) | ||||||
| CUSTOM_COMMAND_SIG(highlight_first_child_scope){ | CUSTOM_DOC("Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.") | ||||||
|  | { | ||||||
|     uint32_t access = AccessProtected; |     uint32_t access = AccessProtected; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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){ | CUSTOM_COMMAND_SIG(highlight_prev_scope_absolute) | ||||||
|     uint32_t access = AccessProtected; | CUSTOM_DOC("Finds the first scope started by '{' before the cursor and puts the cursor and mark on the '{' and '}'.") | ||||||
|     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){ |  | ||||||
|     uint32_t access = AccessProtected; |     uint32_t access = AccessProtected; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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; |     uint32_t access = AccessOpen; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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; |     uint32_t access = AccessOpen; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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); |     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; |     uint32_t access = AccessOpen; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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.
 | // 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; |     uint32_t access = AccessOpen; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); |     Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); | ||||||
|  | @ -1196,7 +1165,9 @@ CUSTOM_COMMAND_SIG(rename_parameter){ | ||||||
|     end_temp_memory(temp); |     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; |     uint32_t access = AccessOpen; | ||||||
|     View_Summary view = get_active_view(app, access); |     View_Summary view = get_active_view(app, access); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); |     Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); | ||||||
|  |  | ||||||
|  | @ -100,7 +100,9 @@ get_numeric_at_cursor(Application_Links *app, Buffer_Summary *buffer, int32_t po | ||||||
|     return(result); |     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); |     View_Summary view = get_active_view(app, AccessOpen); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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); |     View_Summary view = get_active_view(app, AccessOpen); | ||||||
|     Buffer_Summary buffer = get_buffer(app, view.buffer_id, 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); |     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); |     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); |     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); |     miblo_time_stamp_alter(app, MIBLO_MINUTE, -1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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[2]  = {"build_site.bat"             , "*site*"        , false, true  }; | ||||||
| fkey_command_win[3]  = {"build_string.bat"           , "*compilation*" , true , 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[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[6]  = {"run_profile.bat"            , "*profile*"     , false, true  }; | ||||||
| fkey_command_win[12] = {"package.bat"                , "*package*"     , false, true  }; | fkey_command_win[12] = {"package.bat"                , "*package*"     , false, true  }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Allen Webster
						Allen Webster