diff --git a/4coder_API/app_functions.h b/4coder_API/app_functions.h index 5f1ab6f7..496c6c70 100644 --- a/4coder_API/app_functions.h +++ b/4coder_API/app_functions.h @@ -14,6 +14,7 @@ struct Application_Links; #define BUFFER_COMPUTE_CURSOR_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out) #define BUFFER_BATCH_EDIT_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type) #define BUFFER_ADD_MARKERS_SIG(n) Marker_Handle n(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count) +#define GET_BUFFER_BY_MARKER_HANDLE_SIG(n) Buffer_Summary n(Application_Links *app, Marker_Handle marker, Access_Flag access) #define BUFFER_SET_MARKERS_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers) #define BUFFER_GET_MARKERS_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *markers_out) #define BUFFER_REMOVE_MARKERS_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker) @@ -59,7 +60,7 @@ struct Application_Links; #define DIRECTORY_GET_HOT_SIG(n) int32_t n(Application_Links *app, char *out, int32_t capacity) #define GET_FILE_LIST_SIG(n) File_List n(Application_Links *app, char *dir, int32_t len) #define FREE_FILE_LIST_SIG(n) void n(Application_Links *app, File_List list) -#define SET_GUI_UP_DOWN_KEYS_SIG(n) void n(Application_Links *app, int16_t up_key, int16_t down_key) +#define SET_GUI_UP_DOWN_KEYS_SIG(n) void n(Application_Links *app, Key_Code up_key, Key_Modifier up_key_modifier, Key_Code down_key, Key_Modifier down_key_modifier) #define MEMORY_ALLOCATE_SIG(n) void* n(Application_Links *app, int32_t size) #define MEMORY_SET_PROTECTION_SIG(n) bool32 n(Application_Links *app, void *ptr, int32_t size, Memory_Protect_Flags flags) #define MEMORY_FREE_SIG(n) void n(Application_Links *app, void *ptr, int32_t size) @@ -85,6 +86,7 @@ typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function); typedef BUFFER_COMPUTE_CURSOR_SIG(Buffer_Compute_Cursor_Function); typedef BUFFER_BATCH_EDIT_SIG(Buffer_Batch_Edit_Function); typedef BUFFER_ADD_MARKERS_SIG(Buffer_Add_Markers_Function); +typedef GET_BUFFER_BY_MARKER_HANDLE_SIG(Get_Buffer_By_Marker_Handle_Function); typedef BUFFER_SET_MARKERS_SIG(Buffer_Set_Markers_Function); typedef BUFFER_GET_MARKERS_SIG(Buffer_Get_Markers_Function); typedef BUFFER_REMOVE_MARKERS_SIG(Buffer_Remove_Markers_Function); @@ -158,6 +160,7 @@ Buffer_Replace_Range_Function *buffer_replace_range; Buffer_Compute_Cursor_Function *buffer_compute_cursor; Buffer_Batch_Edit_Function *buffer_batch_edit; Buffer_Add_Markers_Function *buffer_add_markers; +Get_Buffer_By_Marker_Handle_Function *get_buffer_by_marker_handle; Buffer_Set_Markers_Function *buffer_set_markers; Buffer_Get_Markers_Function *buffer_get_markers; Buffer_Remove_Markers_Function *buffer_remove_markers; @@ -230,6 +233,7 @@ Buffer_Replace_Range_Function *buffer_replace_range_; Buffer_Compute_Cursor_Function *buffer_compute_cursor_; Buffer_Batch_Edit_Function *buffer_batch_edit_; Buffer_Add_Markers_Function *buffer_add_markers_; +Get_Buffer_By_Marker_Handle_Function *get_buffer_by_marker_handle_; Buffer_Set_Markers_Function *buffer_set_markers_; Buffer_Get_Markers_Function *buffer_get_markers_; Buffer_Remove_Markers_Function *buffer_remove_markers_; @@ -310,6 +314,7 @@ app_links->buffer_replace_range_ = Buffer_Replace_Range;\ app_links->buffer_compute_cursor_ = Buffer_Compute_Cursor;\ app_links->buffer_batch_edit_ = Buffer_Batch_Edit;\ app_links->buffer_add_markers_ = Buffer_Add_Markers;\ +app_links->get_buffer_by_marker_handle_ = Get_Buffer_By_Marker_Handle;\ app_links->buffer_set_markers_ = Buffer_Set_Markers;\ app_links->buffer_get_markers_ = Buffer_Get_Markers;\ app_links->buffer_remove_markers_ = Buffer_Remove_Markers;\ @@ -382,6 +387,7 @@ static inline bool32 buffer_replace_range(Application_Links *app, Buffer_Summary static inline bool32 buffer_compute_cursor(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out){return(app->buffer_compute_cursor(app, buffer, seek, cursor_out));} static inline bool32 buffer_batch_edit(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type){return(app->buffer_batch_edit(app, buffer, str, str_len, edits, edit_count, type));} static inline Marker_Handle buffer_add_markers(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count){return(app->buffer_add_markers(app, buffer, marker_count));} +static inline Buffer_Summary get_buffer_by_marker_handle(Application_Links *app, Marker_Handle marker, Access_Flag access){return(app->get_buffer_by_marker_handle(app, marker, access));} static inline bool32 buffer_set_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers){return(app->buffer_set_markers(app, buffer, marker, first_marker_index, marker_count, source_markers));} static inline bool32 buffer_get_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *markers_out){return(app->buffer_get_markers(app, buffer, marker, first_marker_index, marker_count, markers_out));} static inline bool32 buffer_remove_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker){return(app->buffer_remove_markers(app, buffer, marker));} @@ -427,7 +433,7 @@ static inline void get_theme_colors(Application_Links *app, Theme_Color *colors, static inline int32_t directory_get_hot(Application_Links *app, char *out, int32_t capacity){return(app->directory_get_hot(app, out, capacity));} static inline File_List get_file_list(Application_Links *app, char *dir, int32_t len){return(app->get_file_list(app, dir, len));} static inline void free_file_list(Application_Links *app, File_List list){(app->free_file_list(app, list));} -static inline void set_gui_up_down_keys(Application_Links *app, int16_t up_key, int16_t down_key){(app->set_gui_up_down_keys(app, up_key, down_key));} +static inline void set_gui_up_down_keys(Application_Links *app, Key_Code up_key, Key_Modifier up_key_modifier, Key_Code down_key, Key_Modifier down_key_modifier){(app->set_gui_up_down_keys(app, up_key, up_key_modifier, down_key, down_key_modifier));} static inline void* memory_allocate(Application_Links *app, int32_t size){return(app->memory_allocate(app, size));} static inline bool32 memory_set_protection(Application_Links *app, void *ptr, int32_t size, Memory_Protect_Flags flags){return(app->memory_set_protection(app, ptr, size, flags));} static inline void memory_free(Application_Links *app, void *ptr, int32_t size){(app->memory_free(app, ptr, size));} @@ -454,6 +460,7 @@ static inline bool32 buffer_replace_range(Application_Links *app, Buffer_Summary static inline bool32 buffer_compute_cursor(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out){return(app->buffer_compute_cursor_(app, buffer, seek, cursor_out));} static inline bool32 buffer_batch_edit(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type){return(app->buffer_batch_edit_(app, buffer, str, str_len, edits, edit_count, type));} static inline Marker_Handle buffer_add_markers(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count){return(app->buffer_add_markers_(app, buffer, marker_count));} +static inline Buffer_Summary get_buffer_by_marker_handle(Application_Links *app, Marker_Handle marker, Access_Flag access){return(app->get_buffer_by_marker_handle_(app, marker, access));} static inline bool32 buffer_set_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers){return(app->buffer_set_markers_(app, buffer, marker, first_marker_index, marker_count, source_markers));} static inline bool32 buffer_get_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *markers_out){return(app->buffer_get_markers_(app, buffer, marker, first_marker_index, marker_count, markers_out));} static inline bool32 buffer_remove_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker){return(app->buffer_remove_markers_(app, buffer, marker));} @@ -499,7 +506,7 @@ static inline void get_theme_colors(Application_Links *app, Theme_Color *colors, static inline int32_t directory_get_hot(Application_Links *app, char *out, int32_t capacity){return(app->directory_get_hot_(app, out, capacity));} static inline File_List get_file_list(Application_Links *app, char *dir, int32_t len){return(app->get_file_list_(app, dir, len));} static inline void free_file_list(Application_Links *app, File_List list){(app->free_file_list_(app, list));} -static inline void set_gui_up_down_keys(Application_Links *app, int16_t up_key, int16_t down_key){(app->set_gui_up_down_keys_(app, up_key, down_key));} +static inline void set_gui_up_down_keys(Application_Links *app, Key_Code up_key, Key_Modifier up_key_modifier, Key_Code down_key, Key_Modifier down_key_modifier){(app->set_gui_up_down_keys_(app, up_key, up_key_modifier, down_key, down_key_modifier));} static inline void* memory_allocate(Application_Links *app, int32_t size){return(app->memory_allocate_(app, size));} static inline bool32 memory_set_protection(Application_Links *app, void *ptr, int32_t size, Memory_Protect_Flags flags){return(app->memory_set_protection_(app, ptr, size, flags));} static inline void memory_free(Application_Links *app, void *ptr, int32_t size){(app->memory_free_(app, ptr, size));} diff --git a/4coder_API/types.h b/4coder_API/types.h index 2090b46b..28d5ccaa 100644 --- a/4coder_API/types.h +++ b/4coder_API/types.h @@ -27,8 +27,8 @@ TYPEDEF int32_t Buffer_ID; /* DOC(View_ID is used to name a 4coder view. Each view has a unique id in the interval [1,16].) */ TYPEDEF int32_t View_ID; -/* DOC(A Key_Modifier acts as an index for specifying modifiers in arrays.) */ -ENUM(int32_t, Key_Modifier){ +/* DOC(A Key_Modifier_Index acts as an index for specifying modifiers in arrays.) */ +ENUM(int32_t, Key_Modifier_Index){ MDFR_SHIFT_INDEX, MDFR_CONTROL_INDEX, MDFR_ALT_INDEX, @@ -145,6 +145,9 @@ ENUM(int32_t, Buffer_Setting_ID){ from with the buffer.) */ BufferSetting_Lex, + /* DOC(The BufferSetting_LexWithoutStrings tells the system to treat string and character marks as identifiers instead of strings. This settings does nothing if the buffer does not have lexing turned on.) */ + BufferSetting_LexWithoutStrings, + /* DOC(The BufferSetting_WrapLine setting is used to determine whether a buffer prefers to be viewed with wrapped lines, individual views can be set to override this value after being tied to the buffer.) */ @@ -340,6 +343,10 @@ ENUM(int32_t, View_Split_Position){ /* DOC(Key_Code is the alias for key codes including raw codes and codes translated to textual input that takes modifiers into account.) */ TYPEDEF uint32_t Key_Code; +/* DOC(Key_Modifier is the alias for flags that represent keyboard modifiers, ctrl, alt, shift, etc.) +DOC_SEE(Key_Modifier_Flag) */ +TYPEDEF uint8_t Key_Modifier; + /* DOC(Key_Event_Data describes a key event, including the translation to a character, the translation to a character ignoring the state of caps lock, and an array of all the modifiers that were pressed at the time of the event.) */ STRUCT Key_Event_Data{ /* DOC(This field is the raw keycode which is always non-zero in valid key events.) */ @@ -351,11 +358,11 @@ STRUCT Key_Event_Data{ /* DOC(This field is like the field character, except that the state of caps lock is ignored in the translation.) */ Key_Code character_no_caps_lock; - /* DOC(This field is an array indicating the state of modifiers at the time of the key press. The array is indexed using the values of Key_Modifier. 1 indicates that the corresponding modifier was held, and a 0 indicates that it was not held.) + /* DOC(This field is an array indicating the state of modifiers at the time of the key press. The array is indexed using the values of Key_Modifier_Index. 1 indicates that the corresponding modifier was held, and a 0 indicates that it was not held.) DOC_SEE(Key_Modifier) */ - char modifiers[MDFR_INDEX_COUNT]; + int8_t modifiers[MDFR_INDEX_COUNT]; }; // TODO(allen): GLOBAL_VAR meta parsing diff --git a/4coder_API/version.h b/4coder_API/version.h index 67f7e71c..64caa0ab 100644 --- a/4coder_API/version.h +++ b/4coder_API/version.h @@ -1,6 +1,6 @@ #define MAJOR 4 #define MINOR 0 -#define PATCH 18 +#define PATCH 19 // string #define VN__(a,b,c) #a"."#b"."#c diff --git a/4coder_base_commands.cpp b/4coder_base_commands.cpp index 4ba226e4..5b209de2 100644 --- a/4coder_base_commands.cpp +++ b/4coder_base_commands.cpp @@ -26,11 +26,7 @@ CUSTOM_COMMAND_SIG(write_character){ User_Input in = get_command_input(app); uint8_t character[4]; - uint32_t length = 0; - if (in.type == UserInputKey){ - u32_to_utf8_unchecked(in.key.character, character, &length); - } - + uint32_t length = to_writable_character(in, character); if (length != 0){ Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); int32_t pos = view.cursor.pos; @@ -630,26 +626,26 @@ isearch(Application_Links *app, int32_t start_reversed, String query_init){ bool32 backspace = false; if (!first_step){ - in = get_user_input(app, EventOnAnyKey, EventOnEsc | EventOnButton); + //in = get_user_input(app, EventOnAnyKey, EventOnEsc | EventOnButton); + in = get_user_input(app, EventOnAnyKey, EventOnEsc); if (in.abort) break; // NOTE(allen): If we're getting mouse events here it's a 4coder bug, because we only asked to intercept key events. Assert(in.type == UserInputKey); - char character = to_writable_char(in.key.character); + uint8_t character[4]; + uint32_t length = to_writable_character(in, character); + bool32 made_change = false; if (in.key.keycode == '\n' || in.key.keycode == '\t'){ break; } - else if (character && key_is_unmodified(&in.key)){ - append_s_char(&bar.string, character); + else if (length != 0 && key_is_unmodified(&in.key)){ + append_ss(&bar.string, make_string(character, length)); made_change = true; } else if (in.key.keycode == key_back){ - if (bar.string.size > 0){ - --bar.string.size; - made_change = true; - } + made_change = backspace_utf8(&bar.string); backspace = true; } diff --git a/4coder_default_framework.h b/4coder_default_framework.h index a77d70b2..259cb191 100644 --- a/4coder_default_framework.h +++ b/4coder_default_framework.h @@ -1,6 +1,5 @@ /* -4coder_default_framework.cpp - Sets up the basics of the framework that is used -for default 4coder behaviour. +4coder_default_framework.cpp - Sets up the basics of the framework that is used for default 4coder behaviour. TYPE: 'internal-for-default-system' */ @@ -291,11 +290,11 @@ get_current_project_extensions(int32_t *extension_count_out){ // Location Jumping State // -typedef struct ID_Based_Jump_Location{ +struct ID_Based_Jump_Location{ int32_t buffer_id; int32_t line; int32_t column; -} ID_Based_Jump_Location; +}; static ID_Based_Jump_Location null_location = {0}; static ID_Based_Jump_Location prev_location = {0}; @@ -724,7 +723,7 @@ process_config_file(Application_Links *app){ array.max_count = (1 << 20)/sizeof(Cpp_Token); array.tokens = push_array(&global_part, Cpp_Token, array.max_count); - Cpp_Lex_Data S = cpp_lex_data_init(); + Cpp_Lex_Data S = cpp_lex_data_init(false); Cpp_Lex_Result result = cpp_lex_step(&S, mem, size+1, HAS_NULL_TERM, &array, NO_OUT_LIMIT); if (result == LexResult_Finished){ diff --git a/4coder_default_hooks.cpp b/4coder_default_hooks.cpp index b36e7791..5cb5c835 100644 --- a/4coder_default_hooks.cpp +++ b/4coder_default_hooks.cpp @@ -79,19 +79,28 @@ OPEN_FILE_HOOK_SIG(default_file_settings){ Assert(buffer.exists); bool32 treat_as_code = false; + bool32 treat_as_todo = false; bool32 wrap_lines = true; int32_t extension_count = 0; char **extension_list = get_current_code_extensions(&extension_count); if (buffer.file_name != 0 && buffer.size < (16 << 20)){ - String ext = file_extension(make_string(buffer.file_name, buffer.file_name_len)); + String name = make_string(buffer.file_name, buffer.file_name_len); + String ext = file_extension(name); for (int32_t i = 0; i < extension_count; ++i){ if (match(ext, extension_list[i])){ treat_as_code = true; break; } } + + if (!treat_as_code){ + String lead_name = front_of_directory(name); + if (match_insensitive(lead_name, "todo.txt")){ + treat_as_todo = true; + } + } } if (treat_as_code){ @@ -107,7 +116,12 @@ OPEN_FILE_HOOK_SIG(default_file_settings){ buffer_set_setting(app, &buffer, BufferSetting_MinimumBaseWrapPosition, default_min_base_width); buffer_set_setting(app, &buffer, BufferSetting_MapID, map_id); - if (treat_as_code && enable_code_wrapping && buffer.size < (1 << 18)){ + if (treat_as_todo){ + buffer_set_setting(app, &buffer, BufferSetting_WrapLine, true); + buffer_set_setting(app, &buffer, BufferSetting_LexWithoutStrings, true); + buffer_set_setting(app, &buffer, BufferSetting_VirtualWhitespace, true); + } + else if (treat_as_code && enable_code_wrapping && buffer.size < (1 << 18)){ // NOTE(allen|a4.0.12): There is a little bit of grossness going on here. // If we set BufferSetting_Lex to true, it will launch a lexing job. // If a lexing job is active when we set BufferSetting_VirtualWhitespace, the call can fail. diff --git a/4coder_helper/4coder_bind_helper.h b/4coder_helper/4coder_bind_helper.h index 3232008e..a9d42255 100644 --- a/4coder_helper/4coder_bind_helper.h +++ b/4coder_helper/4coder_bind_helper.h @@ -226,6 +226,13 @@ end_bind_helper(Bind_Helper *helper){ return(result); } +static u32_4tech +get_key_code(char *buffer){ + u32_4tech ignore; + u32_4tech result = utf8_to_u32_length_unchecked((u8_4tech*)buffer, &ignore); + return(result); +} + #endif // BOTTOM diff --git a/4coder_helper/4coder_helper.h b/4coder_helper/4coder_helper.h index 8d65266c..4c577599 100644 --- a/4coder_helper/4coder_helper.h +++ b/4coder_helper/4coder_helper.h @@ -6,6 +6,7 @@ #define FCODER_HELPER_H #include "4coder_seek_types.h" +#include "4coder_lib/4coder_utf8.h" static void exec_command(Application_Links *app, Custom_Command_Function *func){ @@ -24,26 +25,46 @@ exec_command(Application_Links *app, Generic_Command cmd){ static int32_t key_is_unmodified(Key_Event_Data *key){ - char *mods = key->modifiers; - int32_t unmodified = !mods[MDFR_CONTROL_INDEX] && !mods[MDFR_ALT_INDEX]; + int8_t *mods = key->modifiers; + int32_t unmodified = (!mods[MDFR_CONTROL_INDEX] && !mods[MDFR_ALT_INDEX]); return(unmodified); } -static char -to_writable_char(Key_Code long_character){ - char character = 0; - if (long_character < ' '){ - if (long_character == '\n'){ - character = '\n'; - } - else if (long_character == '\t'){ - character = '\t'; +static uint32_t +to_writable_character(User_Input in, uint8_t *character){ + uint32_t result = 0; + if (in.type == UserInputKey){ + if (in.key.character != 0){ + u32_to_utf8_unchecked(in.key.character, character, &result); } } - else if (long_character <= 255 && long_character != 127){ - character = (char)long_character; + return(result); +} + +static uint32_t +to_writable_character(Key_Event_Data key, uint8_t *character){ + uint32_t result = 0; + if (key.character != 0){ + u32_to_utf8_unchecked(key.character, character, &result); } - return(character); + return(result); +} + +static bool32 +backspace_utf8(String *str){ + bool32 result = false; + uint8_t *s = (uint8_t*)str->str; + if (str->size > 0){ + uint32_t i = str->size-1; + for (; i > 0; --i){ + if (s[i] <= 0x7F || s[i] >= 0xC0){ + break; + } + } + str->size = i; + result = true; + } + return(result); } static bool32 @@ -71,18 +92,19 @@ query_user_general(Application_Links *app, Query_Bar *bar, bool32 force_number){ break; } - char character = 0; + uint8_t character[4]; + uint32_t length = 0; bool32 good_character = false; if (key_is_unmodified(&in.key)){ if (force_number){ if (in.key.character >= '0' && in.key.character <= '9'){ good_character = true; - character = (char)(in.key.character); + length = to_writable_character(in, character); } } else{ - character = to_writable_char(in.key.character); - if (character != 0){ + length = to_writable_character(in, character); + if (length != 0){ good_character = true; } } @@ -96,12 +118,10 @@ query_user_general(Application_Links *app, Query_Bar *bar, bool32 force_number){ break; } else if (in.key.keycode == key_back){ - if (bar->string.size > 0){ - --bar->string.size; - } + backspace_utf8(&bar->string); } else if (good_character){ - append_s_char(&bar->string, character); + append_ss(&bar->string, make_string(character, length)); } } } @@ -204,7 +224,7 @@ struct Buffer_Rect{ }; #ifndef Swap -#define Swap(T,a,b) do{ T t = a; a = b; b = t; } while(0) +# define Swap(T,a,b) do{ T t = a; a = b; b = t; } while(0) #endif static Buffer_Rect diff --git a/4coder_helper/4coder_jump_parsing.h b/4coder_helper/4coder_jump_parsing.h index 6f5dfea7..932da31a 100644 --- a/4coder_helper/4coder_jump_parsing.h +++ b/4coder_helper/4coder_jump_parsing.h @@ -12,32 +12,17 @@ #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 void -jump_to_location(Application_Links *app, View_Summary *view, Name_Based_Jump_Location *l){ - Buffer_Summary buffer = {0}; - if (open_file(app, &buffer, l->file.str, l->file.size, false, true)){ - View_Summary target_view = get_first_view_with_buffer(app, buffer.buffer_id); - if (!target_view.exists){ - view_set_buffer(app, view, buffer.buffer_id, 0); - target_view = *view; - } - view_set_cursor(app, &target_view, seek_line_char(l->line, l->column), true); - } -} - -static void -jump_to_location_always_use_view(Application_Links *app, View_Summary *view, Name_Based_Jump_Location *l){ - if (view_open_file(app, view, l->file.str, l->file.size, true)){ - view_set_cursor(app, view, seek_line_char(l->line, l->column), true); - } -} - static bool32 ms_style_verify(String line, int32_t paren_pos){ int32_t result = false; diff --git a/4coder_helper/4coder_long_seek.h b/4coder_helper/4coder_long_seek.h index 24de3b5c..59e024a8 100644 --- a/4coder_helper/4coder_long_seek.h +++ b/4coder_helper/4coder_long_seek.h @@ -938,12 +938,12 @@ buffer_seek_string_insensitive_backward(Application_Links *app, Buffer_Summary * // Buffer Line Positioning // -static int32_t +static bool32 read_line(Application_Links *app, Partition *part, Buffer_Summary *buffer, int32_t line, String *str){ Partial_Cursor begin = {0}; Partial_Cursor end = {0}; - int32_t success = 0; + bool32 success = false; if (buffer_compute_cursor(app, buffer, seek_line_char(line, 1), &begin)){ if (buffer_compute_cursor(app, buffer, seek_line_char(line, -1), &end)){ @@ -952,7 +952,7 @@ read_line(Application_Links *app, Partition *part, Buffer_Summary *buffer, int32 int32_t size = (end.pos - begin.pos); *str = make_string(push_array(part, char, size+1), size+1); if (str->str){ - success = 1; + success = true; buffer_read_range(app, buffer, begin.pos, end.pos, str->str); str->size = size; terminate_with_null(str); diff --git a/4coder_jump_parsing.cpp b/4coder_jump_parsing.cpp index 459e8b48..00af4919 100644 --- a/4coder_jump_parsing.cpp +++ b/4coder_jump_parsing.cpp @@ -7,15 +7,18 @@ TYPE: 'drop-in-command-pack' // TOP -#if !defined(FCODER_JUMP_PARSING) +#if !defined(FCODER_JUMP_PARSING) && !defined(FCODER_JUMP_COMMANDS) #define FCODER_JUMP_PARSING +#define FCODER_JUMP_COMMANDS + #include "4coder_default_framework.h" #include "4coder_helper/4coder_long_seek.h" #include "4coder_helper/4coder_helper.h" #include "4coder_helper/4coder_jump_parsing.h" #include "4coder_lib/4coder_mem.h" +#include "4coder_jumping.h" CUSTOM_COMMAND_SIG(goto_jump_at_cursor){ Temp_Memory temp = begin_temp_memory(&global_part); @@ -24,10 +27,12 @@ CUSTOM_COMMAND_SIG(goto_jump_at_cursor){ Name_Based_Jump_Location location = {0}; if (parse_jump_from_buffer_line(app, &global_part, view.buffer_id, view.cursor.line, false, &location)){ change_active_panel(app); - view = get_active_view(app, AccessAll); - jump_to_location(app, &view, &location); - if (auto_center_after_jumps){ - center_view(app); + View_Summary target_view = get_active_view(app, AccessAll); + + Buffer_Summary buffer = {0}; + if (get_jump_buffer(app, &buffer, &location)){ + switch_to_existing_view(app, &target_view, &buffer); + jump_to_location(app, &target_view, &buffer, location); } } @@ -40,150 +45,17 @@ CUSTOM_COMMAND_SIG(goto_jump_at_cursor_same_panel){ Name_Based_Jump_Location location = {0}; if (parse_jump_from_buffer_line(app, &global_part, view.buffer_id, view.cursor.line, false, &location)){ - view = get_active_view(app, AccessAll); - jump_to_location(app, &view, &location); - if (auto_center_after_jumps){ - center_view(app); + View_Summary target_view = view; + + Buffer_Summary buffer = {0}; + if (get_jump_buffer(app, &buffer, &location)){ + jump_to_location(app, &target_view, &buffer, location); } } end_temp_memory(temp); } -// -// Error Jumping -// - -static bool32 -seek_next_jump_in_buffer(Application_Links *app, Partition *part, int32_t buffer_id, int32_t first_line, bool32 skip_sub_errors, int32_t direction, int32_t *line_out, int32_t *colon_index_out, Name_Based_Jump_Location *location_out){ - - Assert(direction == 1 || direction == -1); - - bool32 result = false; - int32_t line = first_line; - String line_str = {0}; - Buffer_Summary buffer = get_buffer(app, buffer_id, AccessAll); - for (;;){ - if (read_line(app, part, &buffer, line, &line_str)){ - if (parse_jump_location(line_str, location_out, skip_sub_errors, colon_index_out)){ - result = true; - break; - } - line += direction; - } - else{ - break; - } - } - - if (line < 0){ - line = 0; - } - - *line_out = line; - - return(result); -} - -static ID_Based_Jump_Location -convert_name_based_to_id_based(Application_Links *app, Name_Based_Jump_Location loc){ - ID_Based_Jump_Location result = {0}; - Buffer_Summary buffer = - get_buffer_by_name(app, loc.file.str, loc.file.size, AccessAll); - - if (buffer.exists){ - result.buffer_id = buffer.buffer_id; - result.line = loc.line; - result.column = loc.column; - } - - return(result); -} - -static int32_t -seek_next_jump_in_view(Application_Links *app, Partition *part, View_Summary *view, int32_t skip_sub_errors, int32_t direction, int32_t *line_out, int32_t *colon_index_out, Name_Based_Jump_Location *location_out){ - int32_t result = false; - - Name_Based_Jump_Location location = {0}; - int32_t line = view->cursor.line; - int32_t colon_index = 0; - if (seek_next_jump_in_buffer(app, part, view->buffer_id, line+direction, skip_sub_errors, direction, &line, &colon_index, &location)){ - result = true; - *line_out = line; - *colon_index_out = colon_index; - *location_out = location; - } - - return(result); -} - -static int32_t -skip_this_jump(ID_Based_Jump_Location prev, ID_Based_Jump_Location jump){ - int32_t result = false; - if (prev.buffer_id != 0 && - prev.buffer_id == jump.buffer_id && - prev.line == jump.line && - prev.column <= jump.column){ - result = true; - } - return(result); -} - -static int32_t -advance_cursor_in_jump_view(Application_Links *app, Partition *part, View_Summary *view, int32_t skip_repeats, int32_t skip_sub_error, int32_t direction, Name_Based_Jump_Location *location_out){ - int32_t result = true; - - Name_Based_Jump_Location location = {0}; - ID_Based_Jump_Location jump = {0}; - int32_t line = 0, colon_index = 0; - - do{ - Temp_Memory temp = begin_temp_memory(part); - if (seek_next_jump_in_view(app, part, view, skip_sub_error, direction, &line, &colon_index, &location)){ - jump = convert_name_based_to_id_based(app, location); - view_set_cursor(app, view, seek_line_char(line, colon_index+1), true); - result = true; - } - else{ - jump.buffer_id = 0; - result = false; - } - end_temp_memory(temp); - }while(skip_repeats && skip_this_jump(prev_location, jump)); - - if (result){ - *location_out = location; - view_set_cursor(app, view, seek_line_char(line, colon_index+1), true); - } - - prev_location = jump; - - return(result); -} - -static bool32 -seek_jump(Application_Links *app, Partition *part, bool32 skip_repeats, bool32 skip_sub_errors, int32_t direction){ - bool32 result = false; - - View_Summary view = get_view_for_locked_jump_buffer(app); - if (view.exists){ - Name_Based_Jump_Location location = {0}; - if (advance_cursor_in_jump_view(app, &global_part, &view, skip_repeats, skip_sub_errors, direction, &location)){ - View_Summary active_view = get_active_view(app, AccessAll); - if (active_view.view_id == view.view_id){ - change_active_panel(app); - active_view = get_active_view(app, AccessAll); - } - - jump_to_location(app, &active_view, &location); - result = true; - } - } - - return(result); -} - - CUSTOM_COMMAND_SIG(goto_next_jump){ bool32 skip_repeats = true; bool32 skip_sub_errors = true; diff --git a/4coder_jumping.h b/4coder_jumping.h new file mode 100644 index 00000000..0f3ac735 --- /dev/null +++ b/4coder_jumping.h @@ -0,0 +1,200 @@ +/* +4coder_jumping.h - Routines commonly used when writing code to jump to locations and seek through jump lists. + +TYPE: 'helper-routines' +*/ + +// TOP + +#if !defined(FCODER_JUMPING) +#define FCODER_JUMPING + +static bool32 +get_jump_buffer(Application_Links *app, Buffer_Summary *buffer, Name_Based_Jump_Location *location){ + bool32 result = open_file(app, buffer, location->file.str, location->file.size, false, true); + return(result); +} + +static bool32 +get_jump_buffer(Application_Links *app, Buffer_Summary *buffer, ID_Pos_Jump_Location *location){ + *buffer = get_buffer(app, location->buffer_id, AccessAll); + bool32 result = false; + if (buffer->exists){ + result = true; + } + return(result); +} + +static void +switch_to_existing_view(Application_Links *app, View_Summary *view, Buffer_Summary *buffer){ + if (!(view->exists && view->buffer_id == buffer->buffer_id)){ + View_Summary existing_view = get_first_view_with_buffer(app, buffer->buffer_id); + if (existing_view.exists){ + *view = existing_view; + } + } +} + +static void +set_view_to_location(Application_Links *app, View_Summary *view, Buffer_Summary *buffer, Buffer_Seek seek){ + if (view->buffer_id != buffer->buffer_id){ + view_set_buffer(app, view, buffer->buffer_id, 0); + } + view_set_cursor(app, view, seek, true); +} + +static void +jump_to_location(Application_Links *app, View_Summary *view, Buffer_Summary *buffer, Name_Based_Jump_Location location){ + set_active_view(app, view); + set_view_to_location(app, view, buffer, seek_line_char(location.line, location.column)); + if (auto_center_after_jumps){ + center_view(app); + } +} + +static void +jump_to_location(Application_Links *app, View_Summary *view, Buffer_Summary *buffer, ID_Pos_Jump_Location location){ + set_active_view(app, view); + set_view_to_location(app, view, buffer, seek_pos(location.pos)); + if (auto_center_after_jumps){ + center_view(app); + } +} + +// +// Error Jumping +// + +static bool32 +seek_next_jump_in_buffer(Application_Links *app, Partition *part, int32_t buffer_id, int32_t first_line, bool32 skip_sub_errors, int32_t direction, int32_t *line_out, int32_t *colon_index_out, Name_Based_Jump_Location *location_out){ + + Assert(direction == 1 || direction == -1); + + bool32 result = false; + int32_t line = first_line; + String line_str = {0}; + Buffer_Summary buffer = get_buffer(app, buffer_id, AccessAll); + for (;;){ + if (read_line(app, part, &buffer, line, &line_str)){ + if (parse_jump_location(line_str, location_out, skip_sub_errors, colon_index_out)){ + result = true; + break; + } + line += direction; + } + else{ + break; + } + } + + if (line < 0){ + line = 0; + } + + *line_out = line; + + return(result); +} + +static ID_Based_Jump_Location +convert_name_based_to_id_based(Application_Links *app, Name_Based_Jump_Location loc){ + ID_Based_Jump_Location result = {0}; + Buffer_Summary buffer = get_buffer_by_name(app, loc.file.str, loc.file.size, AccessAll); + + if (buffer.exists){ + result.buffer_id = buffer.buffer_id; + result.line = loc.line; + result.column = loc.column; + } + + return(result); +} + +static int32_t +seek_next_jump_in_view(Application_Links *app, Partition *part, View_Summary *view, int32_t skip_sub_errors, int32_t direction, int32_t *line_out, int32_t *colon_index_out, Name_Based_Jump_Location *location_out){ + int32_t result = false; + + Name_Based_Jump_Location location = {0}; + int32_t line = view->cursor.line; + int32_t colon_index = 0; + if (seek_next_jump_in_buffer(app, part, view->buffer_id, line+direction, skip_sub_errors, direction, &line, &colon_index, &location)){ + result = true; + *line_out = line; + *colon_index_out = colon_index; + *location_out = location; + } + + return(result); +} + +static bool32 +skip_this_jump(ID_Based_Jump_Location prev, ID_Based_Jump_Location jump){ + bool32 result = false; + if (prev.buffer_id != 0 && prev.buffer_id == jump.buffer_id && prev.line == jump.line && prev.column <= jump.column){ + result = true; + } + return(result); +} + +static bool32 +advance_cursor_in_jump_view(Application_Links *app, Partition *part, View_Summary *view, int32_t skip_repeats, int32_t skip_sub_error, int32_t direction, Name_Based_Jump_Location *location_out){ + bool32 result = true; + + Name_Based_Jump_Location location = {0}; + ID_Based_Jump_Location jump = {0}; + int32_t line = 0, colon_index = 0; + + do{ + Temp_Memory temp = begin_temp_memory(part); + if (seek_next_jump_in_view(app, part, view, skip_sub_error, direction, &line, &colon_index, &location)){ + jump = convert_name_based_to_id_based(app, location); + view_set_cursor(app, view, seek_line_char(line, colon_index+1), true); + result = true; + } + else{ + jump.buffer_id = 0; + result = false; + } + end_temp_memory(temp); + }while(skip_repeats && skip_this_jump(prev_location, jump)); + + if (result){ + *location_out = location; + view_set_cursor(app, view, seek_line_char(line, colon_index+1), true); + } + + prev_location = jump; + + return(result); +} + +static bool32 +seek_jump(Application_Links *app, Partition *part, bool32 skip_repeats, bool32 skip_sub_errors, int32_t direction){ + bool32 result = false; + + View_Summary view = get_view_for_locked_jump_buffer(app); + if (view.exists){ + Name_Based_Jump_Location location = {0}; + if (advance_cursor_in_jump_view(app, &global_part, &view, skip_repeats, skip_sub_errors, direction, &location)){ + + Buffer_Summary buffer = {0}; + if (get_jump_buffer(app, &buffer, &location)){ + View_Summary target_view = get_active_view(app, AccessAll); + if (target_view.view_id == view.view_id){ + change_active_panel(app); + target_view = get_active_view(app, AccessAll); + } + switch_to_existing_view(app, &target_view, &buffer); + jump_to_location(app, &target_view, &buffer, location); + result = true; + } + } + } + + return(result); +} + +#endif + +// BOTTOM + diff --git a/4coder_lib/4coder_mem.h b/4coder_lib/4coder_mem.h index a7084b50..53b4e676 100644 --- a/4coder_lib/4coder_mem.h +++ b/4coder_lib/4coder_mem.h @@ -148,6 +148,8 @@ end_tail_part(Tail_Temp_Partition temp){ } } +#define reset_temp_memory end_temp_memory + /* NOTE(allen): This is a very week general purpose allocator system. @@ -339,8 +341,7 @@ general_memory_reallocate(General_Memory *general, void *old, i32_4tech old_size i32_4tech additional_space = size - bubble->size; if (additional_space > 0){ Bubble *next = bubble->next; - if (!(next->flags & MEM_BUBBLE_USED) && - next->size + (i32_4tech)sizeof(Bubble) >= additional_space){ + if (!(next->flags & MEM_BUBBLE_USED) && next->size + (i32_4tech)sizeof(Bubble) >= additional_space){ general_memory_do_merge(bubble, next); general_memory_attempt_split(general, bubble, size); } @@ -359,10 +360,11 @@ general_memory_reallocate_nocopy(General_Memory *general, void *old, i32_4tech s return(result); } -#define reset_temp_memory end_temp_memory #define gen_struct(g, T) (T*)general_memory_allocate(g, sizeof(T), 0) #define gen_array(g, T, size) (T*)general_memory_allocate(g, sizeof(T)*(size)) #define gen_block(g, size) general_memory_open(g, size, 0) +#define gen_realloc_array(g, T, old, old_size, size)\ +(T*)general_memory_reallocate(g, old, old_size*sizeof(T), size*sizeof(T)) #endif diff --git a/4coder_project_commands.cpp b/4coder_project_commands.cpp index 073dd94c..50767165 100644 --- a/4coder_project_commands.cpp +++ b/4coder_project_commands.cpp @@ -199,7 +199,7 @@ load_project_from_file(Application_Links *app, Partition *part, FILE *file, Stri array.max_count = (1 << 20)/sizeof(Cpp_Token); array.tokens = push_array(&global_part, Cpp_Token, array.max_count); - Cpp_Lex_Data S = cpp_lex_data_init(); + Cpp_Lex_Data S = cpp_lex_data_init(false); Cpp_Lex_Result result = cpp_lex_step(&S, mem, size+1, HAS_NULL_TERM, &array, NO_OUT_LIMIT); if (result == LexResult_Finished){ diff --git a/4cpp/4cpp_lexer.h b/4cpp/4cpp_lexer.h index 4a76b8ea..07d28e3e 100644 --- a/4cpp/4cpp_lexer.h +++ b/4cpp/4cpp_lexer.h @@ -1,5 +1,5 @@ /* -4cpp_lexer.h - Preversioning +4cpp_lexer.h - 1.0.2 no warranty implied; use at your own risk This software is in the public domain. Where that dedication is not @@ -66,6 +66,8 @@ struct String_And_Flag{ static String_And_Flag preprops[] = { {make_stafl("include" , CPP_PP_INCLUDE )} , {make_stafl("INCLUDE" , CPP_PP_INCLUDE )} , + {make_stafl("version" , CPP_PP_VERSION )} , + {make_stafl("VERSION" , CPP_PP_VERSION )} , {make_stafl("ifndef" , CPP_PP_IFNDEF )} , {make_stafl("IFNDEF" , CPP_PP_IFNDEF )} , {make_stafl("define" , CPP_PP_DEFINE )} , @@ -185,7 +187,7 @@ static String_And_Flag keywords[] = { {make_stafl("thread_local" , CPP_TOKEN_KEY_OTHER)}, #if defined(FCPP_LEXER_EXTRA_KEYWORDS) - FCPP_LEXER_EXTRA_KEYWORDS +#include FCPP_LEXER_EXTRA_KEYWORDS #endif }; static i32_4tech keywords_count = sizeof(keywords)/sizeof(keywords[0]); @@ -289,6 +291,7 @@ cpp_pp_directive_to_state(Cpp_Token_Type type){ result = LSPP_body; break; + case CPP_PP_VERSION: case CPP_PP_LINE: result = LSPP_number; break; @@ -383,6 +386,9 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, i32_4tech s S.pp_state -= LSPP_count; } + if (S.pp_state == LSPP_default && S.ignore_string_delims){ + S.pp_state = LSPP_no_strings; + } S.token.state_flags = S.pp_state; S.token_start = S.pos; @@ -448,7 +454,7 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, i32_4tech s #undef OperCase case '\\': - if (S.pp_state == LSPP_default){ + if (S.pp_state == LSPP_default || S.pp_state == LSPP_no_strings){ S.token.type = CPP_TOKEN_JUNK; } else{ @@ -873,6 +879,9 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, i32_4tech s --S.pos; } + if (S.pp_state == LSPP_default && S.ignore_string_delims){ + S.pp_state = LSPP_no_strings; + } if ((S.token.flags & CPP_TFLAG_PP_DIRECTIVE) == 0){ switch (S.pp_state){ case LSPP_macro_identifier: @@ -921,7 +930,7 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, i32_4tech s S.token.size = S.pos - S.token_start; } if ((S.token.flags & CPP_TFLAG_PP_DIRECTIVE) == 0){ - if (S.pp_state != LSPP_default){ + if (S.pp_state != LSPP_default && S.pp_state){ S.token.flags |= CPP_TFLAG_PP_BODY; } } @@ -1035,20 +1044,15 @@ CODE_EXAMPLE( Cpp_Token_Array lex_file(char *file_name){ File_Data file = read_whole_file(file_name); -char *temp = (char*)malloc(4096); // hopefully big enough -Cpp_Lex_Data lex_state = cpp_lex_data_init(temp); +Cpp_Lex_Data lex_state = cpp_lex_data_init(false); Cpp_Token_Array array = {0}; array.tokens = (Cpp_Token*)malloc(1 << 20); // hopefully big enough array.max_count = (1 << 20)/sizeof(Cpp_Token); -Cpp_Lex_Result result = -cpp_lex_step(&lex_state, file.data, file.size, file.size, -&array, NO_OUT_LIMIT); +Cpp_Lex_Result result = cpp_lex_step(&lex_state, file.data, file.size, file.size, &array, NO_OUT_LIMIT); Assert(result == LexResult_Finished); -free(temp); - return(array); }) @@ -1078,7 +1082,8 @@ DOC_SEE(Cpp_Lex_Result) } API_EXPORT FCPP_LINK Cpp_Lex_Data -cpp_lex_data_init()/* +cpp_lex_data_init(b32_4tech ignore_string_delims)/* +DOC_PARAM(ignore_string_delims, TODO) DOC_RETURN(A brand new lex state ready to begin lexing a file from the beginning.) DOC(Creates a new lex state in the form of a Cpp_Lex_Data struct and returns the struct. @@ -1087,6 +1092,7 @@ enough but the buffer is not checked, so to be 100% bullet proof it has to be th as the file being lexed.) */{ Cpp_Lex_Data data = {0}; + data.ignore_string_delims = ignore_string_delims; return(data); } @@ -1120,10 +1126,6 @@ DOC_SEE(cpp_lex_data_new_temp) } } -API_EXPORT FCPP_LINK void -cpp_lex_data_new_temp_DEP(Cpp_Lex_Data *lex_data, char *new_buffer) -/*DOC(Deprecated in 4cpp Lexer 1.0.1*/{} - FCPP_LINK char cpp_token_get_pp_state(u16_4tech bitfield){ return (char)(bitfield); @@ -1188,7 +1190,7 @@ The start and end points are based on the edited region of the file before the e } API_EXPORT FCPP_LINK Cpp_Relex_Data -cpp_relex_init(Cpp_Token_Array *array, i32_4tech start_pos, i32_4tech end_pos, i32_4tech character_shift_amount) +cpp_relex_init(Cpp_Token_Array *array, i32_4tech start_pos, i32_4tech end_pos, i32_4tech character_shift_amount, b32_4tech ignore_string_delims) /* DOC_PARAM(array, A pointer to the token array that will be modified by the relex, this array should already contain the tokens for the previous state of the file.) @@ -1199,6 +1201,7 @@ In particular, end_pos is the first character after the edited region not effect Thus if the edited region contained one character end_pos - start_pos should equal 1. The start and end points are based on the edited region of the file before the edit.) DOC_PARAM(character_shift_amount, The shift in the characters after the edited region.) +DOC_PARAM(ignore_string_delims, TODO) DOC_RETURN(Returns a partially initialized relex state.) DOC(This call does the first setup step of initializing a relex state. To finish initializing the relex state @@ -1224,7 +1227,7 @@ DOC_SEE(cpp_relex_is_start_chunk) state.character_shift_amount = character_shift_amount; - state.lex = cpp_lex_data_init(); + state.lex = cpp_lex_data_init(ignore_string_delims); state.lex.pp_state = cpp_token_get_pp_state(array->tokens[state.start_token_index].state_flags); state.lex.pos = state.relex_start_position; @@ -1581,7 +1584,7 @@ return(array); ) DOC_SEE(cpp_make_token_array) */{ - Cpp_Lex_Data S = cpp_lex_data_init(); + Cpp_Lex_Data S = cpp_lex_data_init(false); i32_4tech quit = 0; char empty = 0; diff --git a/4cpp/4cpp_lexer_tables.c b/4cpp/4cpp_lexer_tables.c index 65ff1064..6270c54d 100644 --- a/4cpp/4cpp_lexer_tables.c +++ b/4cpp/4cpp_lexer_tables.c @@ -1,13 +1,13 @@ uint16_t whitespace_fsm_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,18, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,10,20,10,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; const int32_t num_whitespace_fsm_eq_classes = 3; uint8_t whitespace_fsm_table[] = { - 9,10,11,12,13,14,15,16,17, - 0, 1, 2, 3, 4, 5, 6, 7, 8, - 0, 0, 0, 0, 0, 0, 0, 0, 0, +10,11,12,13,14,15,16,17,18,19, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; uint16_t int_fsm_eq_classes[] = { @@ -359,6 +359,44 @@ uint8_t pp_junk_fsm_table[] = { 31,41,42,43,44, 5, 6, 5, 8, 9, 8,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, }; +uint16_t no_string_fsm_eq_classes[] = { + 0,40,40,40,40,40,40,40,40,40,80,120,120,120,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,160,200,240,280,320,360,400,240,440,440,480,520,440,560,600,640,680,720,720,720,720,720,720,720,720,720,760,440,800,840,880,440,440,920,920,920,920,920,920,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,440,960,440,1000,320,40,920,920,920,920,1040,920,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,1080,240,240,440,1120,440,440,40,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920, +}; + +const int32_t num_no_string_fsm_eq_classes = 29; + +uint8_t no_string_fsm_table[] = { +40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, + 0,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, + 0,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,58,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, + 0,41,42, 3,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,19,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, + 0,41,42, 3,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +38,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, + 1, 1,42, 4, 4,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, + 3,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, + 1, 1,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +35,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +30,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +40,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +34,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,20,18,18,21,21,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +32,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +28,41,42,43,44,48,48,48,48,48,48,51,52,53,15,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +22,41,42,43,44,48,48,48,48,48,48,13,13,53,54,55,56,57,18,18,20,20,23,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +17,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,18,18,18,20,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +12, 1,42,43,44,48,48,48,48,48,48,11,11,13,15,15,16,57,18,18,20,20,13,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +11, 1,42,43,44,48,48,48,48,48,48,11,11,13,15,15,16,57,18,18,20,20,13,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +33,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +24,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,25,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +37,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +26,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,27,67,29,69,70,71,72,73,74,75,76,77,78,39, + 1, 1,42, 4, 4,48,48,48,48,48,48,51,52,53,54,55,16,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +40,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,19,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +36,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, + 1, 1,42, 4, 4,48,48,48,48,48,48,51,52,14,54,55,16,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, + 1, 1,42, 4, 4,48,48,48,48,48,48,51,16,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +31,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39, +}; + uint16_t * get_eq_classes[] = { main_fsm_eq_classes, pp_include_fsm_eq_classes, @@ -369,6 +407,7 @@ pp_body_fsm_eq_classes, pp_number_fsm_eq_classes, pp_error_fsm_eq_classes, pp_junk_fsm_eq_classes, +no_string_fsm_eq_classes, }; uint8_t * get_table[] = { @@ -381,5 +420,6 @@ pp_body_fsm_table, pp_number_fsm_table, pp_error_fsm_table, pp_junk_fsm_table, +no_string_fsm_table, }; diff --git a/4cpp/4cpp_lexer_types.h b/4cpp/4cpp_lexer_types.h index f53b3b26..80ffbeaf 100644 --- a/4cpp/4cpp_lexer_types.h +++ b/4cpp/4cpp_lexer_types.h @@ -23,211 +23,212 @@ ENUM(uint32_t, Cpp_Token_Type){ CPP_TOKEN_COMMENT = 1, CPP_PP_INCLUDE = 2, - CPP_PP_DEFINE = 3, - CPP_PP_UNDEF = 4, - CPP_PP_IF = 5, - CPP_PP_IFDEF = 6, - CPP_PP_IFNDEF = 7, - CPP_PP_ELSE = 8, - CPP_PP_ELIF = 9, - CPP_PP_ENDIF = 10, - CPP_PP_ERROR = 11, - CPP_PP_IMPORT = 12, - CPP_PP_USING = 13, - CPP_PP_LINE = 14, - CPP_PP_PRAGMA = 15, - CPP_PP_STRINGIFY = 16, - CPP_PP_CONCAT = 17, - CPP_PP_UNKNOWN = 18, + CPP_PP_VERSION = 3, + CPP_PP_DEFINE = 4, + CPP_PP_UNDEF = 5, + CPP_PP_IF = 6, + CPP_PP_IFDEF = 7, + CPP_PP_IFNDEF = 8, + CPP_PP_ELSE = 9, + CPP_PP_ELIF = 10, + CPP_PP_ENDIF = 11, + CPP_PP_ERROR = 12, + CPP_PP_IMPORT = 13, + CPP_PP_USING = 14, + CPP_PP_LINE = 15, + CPP_PP_PRAGMA = 16, + CPP_PP_STRINGIFY = 17, + CPP_PP_CONCAT = 18, + CPP_PP_UNKNOWN = 19, - CPP_PP_DEFINED = 19, - CPP_PP_INCLUDE_FILE = 20, - CPP_PP_ERROR_MESSAGE = 21, + CPP_PP_DEFINED = 20, + CPP_PP_INCLUDE_FILE = 21, + CPP_PP_ERROR_MESSAGE = 22, - CPP_TOKEN_KEY_TYPE = 22, - CPP_TOKEN_KEY_MODIFIER = 23, - CPP_TOKEN_KEY_QUALIFIER = 24, + CPP_TOKEN_KEY_TYPE = 23, + CPP_TOKEN_KEY_MODIFIER = 24, + CPP_TOKEN_KEY_QUALIFIER = 25, /* DOC(This type is not stored in token output from the lexer.) */ - CPP_TOKEN_KEY_OPERATOR = 25, - CPP_TOKEN_KEY_CONTROL_FLOW = 26, - CPP_TOKEN_KEY_CAST = 27, - CPP_TOKEN_KEY_TYPE_DECLARATION = 28, - CPP_TOKEN_KEY_ACCESS = 29, - CPP_TOKEN_KEY_LINKAGE = 30, - CPP_TOKEN_KEY_OTHER = 31, + CPP_TOKEN_KEY_OPERATOR = 26, + CPP_TOKEN_KEY_CONTROL_FLOW = 27, + CPP_TOKEN_KEY_CAST = 28, + CPP_TOKEN_KEY_TYPE_DECLARATION = 29, + CPP_TOKEN_KEY_ACCESS = 30, + CPP_TOKEN_KEY_LINKAGE = 31, + CPP_TOKEN_KEY_OTHER = 32, - CPP_TOKEN_IDENTIFIER = 32, - CPP_TOKEN_INTEGER_CONSTANT = 33, - CPP_TOKEN_CHARACTER_CONSTANT = 34, - CPP_TOKEN_FLOATING_CONSTANT = 35, - CPP_TOKEN_STRING_CONSTANT = 36, - CPP_TOKEN_BOOLEAN_CONSTANT = 37, + CPP_TOKEN_IDENTIFIER = 33, + CPP_TOKEN_INTEGER_CONSTANT = 34, + CPP_TOKEN_CHARACTER_CONSTANT = 35, + CPP_TOKEN_FLOATING_CONSTANT = 36, + CPP_TOKEN_STRING_CONSTANT = 37, + CPP_TOKEN_BOOLEAN_CONSTANT = 38, - CPP_TOKEN_STATIC_ASSERT = 38, + CPP_TOKEN_STATIC_ASSERT = 39, - CPP_TOKEN_BRACKET_OPEN = 39, - CPP_TOKEN_BRACKET_CLOSE = 40, - CPP_TOKEN_PARENTHESE_OPEN = 41, - CPP_TOKEN_PARENTHESE_CLOSE = 42, - CPP_TOKEN_BRACE_OPEN = 43, - CPP_TOKEN_BRACE_CLOSE = 44, - CPP_TOKEN_SEMICOLON = 45, - CPP_TOKEN_ELLIPSIS = 46, + CPP_TOKEN_BRACKET_OPEN = 40, + CPP_TOKEN_BRACKET_CLOSE = 41, + CPP_TOKEN_PARENTHESE_OPEN = 42, + CPP_TOKEN_PARENTHESE_CLOSE = 43, + CPP_TOKEN_BRACE_OPEN = 44, + CPP_TOKEN_BRACE_CLOSE = 45, + CPP_TOKEN_SEMICOLON = 46, + CPP_TOKEN_ELLIPSIS = 47, /* DOC(This is an 'ambiguous' token type because it requires parsing to determine the full nature of the token.) */ - CPP_TOKEN_STAR = 47, + CPP_TOKEN_STAR = 48, /* DOC(This is an 'ambiguous' token type because it requires parsing to determine the full nature of the token.) */ - CPP_TOKEN_AMPERSAND = 48, + CPP_TOKEN_AMPERSAND = 49, /* DOC(This is an 'ambiguous' token type because it requires parsing to determine the full nature of the token.) */ - CPP_TOKEN_TILDE = 49, + CPP_TOKEN_TILDE = 50, /* DOC(This is an 'ambiguous' token type because it requires parsing to determine the full nature of the token.) */ - CPP_TOKEN_PLUS = 50, + CPP_TOKEN_PLUS = 51, /* DOC(This is an 'ambiguous' token type because it requires parsing to determine the full nature of the token.) */ - CPP_TOKEN_MINUS = 51, + CPP_TOKEN_MINUS = 52, /* DOC(This is an 'ambiguous' token type because it requires parsing to determine the full nature of the token.) */ - CPP_TOKEN_INCREMENT = 52, + CPP_TOKEN_INCREMENT = 53, /* DOC(This is an 'ambiguous' token type because it requires parsing to determine the full nature of the token.) */ - CPP_TOKEN_DECREMENT = 53, + CPP_TOKEN_DECREMENT = 54, // NOTE(allen): Precedence 1, LtoR - CPP_TOKEN_SCOPE = 54, + CPP_TOKEN_SCOPE = 55, // NOTE(allen): Precedence 2, LtoR /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_POSTINC = 55, + CPP_TOKEN_POSTINC = 56, /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_POSTDEC = 56, + CPP_TOKEN_POSTDEC = 57, /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_FUNC_STYLE_CAST = 57, - CPP_TOKEN_CPP_STYLE_CAST = 58, + CPP_TOKEN_FUNC_STYLE_CAST = 58, + CPP_TOKEN_CPP_STYLE_CAST = 59, /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_CALL = 59, + CPP_TOKEN_CALL = 60, /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_INDEX = 60, - CPP_TOKEN_DOT = 61, - CPP_TOKEN_ARROW = 62, + CPP_TOKEN_INDEX = 61, + CPP_TOKEN_DOT = 62, + CPP_TOKEN_ARROW = 63, // NOTE(allen): Precedence 3, RtoL /* DOC(This token is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_PREINC = 63, + CPP_TOKEN_PREINC = 64, /* DOC(This token is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_PREDEC = 64, + CPP_TOKEN_PREDEC = 65, /* DOC(This token is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_POSITIVE = 65, + CPP_TOKEN_POSITIVE = 66, /* DOC(This token is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_NEGAITVE = 66, - CPP_TOKEN_NOT = 67, + CPP_TOKEN_NEGAITVE = 67, + CPP_TOKEN_NOT = 68, /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_BIT_NOT = 68, + CPP_TOKEN_BIT_NOT = 69, /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_CAST = 69, + CPP_TOKEN_CAST = 70, /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_DEREF = 70, + CPP_TOKEN_DEREF = 71, /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_TYPE_PTR = 71, + CPP_TOKEN_TYPE_PTR = 72, /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_ADDRESS = 72, + CPP_TOKEN_ADDRESS = 73, /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_TYPE_REF = 73, - CPP_TOKEN_SIZEOF = 74, - CPP_TOKEN_ALIGNOF = 75, - CPP_TOKEN_DECLTYPE = 76, - CPP_TOKEN_TYPEID = 77, - CPP_TOKEN_NEW = 78, - CPP_TOKEN_DELETE = 79, + CPP_TOKEN_TYPE_REF = 74, + CPP_TOKEN_SIZEOF = 75, + CPP_TOKEN_ALIGNOF = 76, + CPP_TOKEN_DECLTYPE = 77, + CPP_TOKEN_TYPEID = 78, + CPP_TOKEN_NEW = 79, + CPP_TOKEN_DELETE = 80, /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_NEW_ARRAY = 80, + CPP_TOKEN_NEW_ARRAY = 81, /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_DELETE_ARRAY = 81, + CPP_TOKEN_DELETE_ARRAY = 82, // NOTE(allen): Precedence 4, LtoR - CPP_TOKEN_PTRDOT = 82, - CPP_TOKEN_PTRARROW = 83, + CPP_TOKEN_PTRDOT = 83, + CPP_TOKEN_PTRARROW = 84, // NOTE(allen): Precedence 5, LtoR /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_MUL = 84, - CPP_TOKEN_DIV = 85, - CPP_TOKEN_MOD = 86, + CPP_TOKEN_MUL = 85, + CPP_TOKEN_DIV = 86, + CPP_TOKEN_MOD = 87, // NOTE(allen): Precedence 6, LtoR /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_ADD = 87, + CPP_TOKEN_ADD = 88, /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_SUB = 88, + CPP_TOKEN_SUB = 89, // NOTE(allen): Precedence 7, LtoR - CPP_TOKEN_LSHIFT = 89, - CPP_TOKEN_RSHIFT = 90, + CPP_TOKEN_LSHIFT = 90, + CPP_TOKEN_RSHIFT = 91, // NOTE(allen): Precedence 8, LtoR - CPP_TOKEN_LESS = 91, - CPP_TOKEN_GRTR = 92, - CPP_TOKEN_GRTREQ = 93, - CPP_TOKEN_LESSEQ = 94, + CPP_TOKEN_LESS = 92, + CPP_TOKEN_GRTR = 93, + CPP_TOKEN_GRTREQ = 94, + CPP_TOKEN_LESSEQ = 95, // NOTE(allen): Precedence 9, LtoR - CPP_TOKEN_EQEQ = 95, - CPP_TOKEN_NOTEQ = 96, + CPP_TOKEN_EQEQ = 96, + CPP_TOKEN_NOTEQ = 97, // NOTE(allen): Precedence 10, LtoR /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_BIT_AND = 97, + CPP_TOKEN_BIT_AND = 98, // NOTE(allen): Precedence 11, LtoR - CPP_TOKEN_BIT_XOR = 98, + CPP_TOKEN_BIT_XOR = 99, // NOTE(allen): Precedence 12, LtoR - CPP_TOKEN_BIT_OR = 99, + CPP_TOKEN_BIT_OR = 100, // NOTE(allen): Precedence 13, LtoR - CPP_TOKEN_AND = 100, + CPP_TOKEN_AND = 101, // NOTE(allen): Precedence 14, LtoR - CPP_TOKEN_OR = 101, + CPP_TOKEN_OR = 102, // NOTE(allen): Precedence 15, RtoL - CPP_TOKEN_TERNARY_QMARK = 102, - CPP_TOKEN_COLON = 103, - CPP_TOKEN_THROW = 104, - CPP_TOKEN_EQ = 105, - CPP_TOKEN_ADDEQ = 106, - CPP_TOKEN_SUBEQ = 107, - CPP_TOKEN_MULEQ = 108, - CPP_TOKEN_DIVEQ = 109, - CPP_TOKEN_MODEQ = 110, - CPP_TOKEN_LSHIFTEQ = 111, - CPP_TOKEN_RSHIFTEQ = 112, - CPP_TOKEN_ANDEQ = 113, - CPP_TOKEN_OREQ = 114, - CPP_TOKEN_XOREQ = 115, + CPP_TOKEN_TERNARY_QMARK = 103, + CPP_TOKEN_COLON = 104, + CPP_TOKEN_THROW = 105, + CPP_TOKEN_EQ = 106, + CPP_TOKEN_ADDEQ = 107, + CPP_TOKEN_SUBEQ = 108, + CPP_TOKEN_MULEQ = 109, + CPP_TOKEN_DIVEQ = 110, + CPP_TOKEN_MODEQ = 111, + CPP_TOKEN_LSHIFTEQ = 112, + CPP_TOKEN_RSHIFTEQ = 113, + CPP_TOKEN_ANDEQ = 114, + CPP_TOKEN_OREQ = 115, + CPP_TOKEN_XOREQ = 116, // NOTE(allen): Precedence 16, LtoR - CPP_TOKEN_COMMA = 116, + CPP_TOKEN_COMMA = 117, /* DOC(This type is for parser use, it is not output by the lexer.) */ - CPP_TOKEN_EOF = 117, + CPP_TOKEN_EOF = 118, - CPP_TOKEN_TYPE_COUNT = 118 + CPP_TOKEN_TYPE_COUNT = 119 }; /* DOC(Cpp_Token represents a single lexed token. It is the primary output of the lexing system.) @@ -335,6 +336,8 @@ STRUCT Cpp_Lex_Data{ Cpp_Token token; + int32_t ignore_string_delims; + int32_t __pc__; }; @@ -374,61 +377,61 @@ STRUCT Cpp_Relex_Data{ }; ENUM_INTERNAL(uint16_t, Cpp_Preprocessor_State){ - CPP_LEX_PP_DEFAULT, - CPP_LEX_PP_IDENTIFIER, - CPP_LEX_PP_MACRO_IDENTIFIER, - CPP_LEX_PP_INCLUDE, - CPP_LEX_PP_BODY, - CPP_LEX_PP_BODY_IF, - CPP_LEX_PP_NUMBER, - CPP_LEX_PP_ERROR, - CPP_LEX_PP_JUNK, - CPP_LEX_PP_COUNT + CPP_LEX_PP_DEFAULT = 0, + CPP_LEX_PP_IDENTIFIER = 1, + CPP_LEX_PP_MACRO_IDENTIFIER = 2, + CPP_LEX_PP_INCLUDE = 3, + CPP_LEX_PP_BODY = 4, + CPP_LEX_PP_BODY_IF = 5, + CPP_LEX_PP_NUMBER = 6, + CPP_LEX_PP_ERROR = 7, + CPP_LEX_PP_JUNK = 8, + CPP_LEX_PP_COUNT = 9 }; ENUM_INTERNAL(uint8_t, Cpp_Lex_State){ - LS_default, - LS_identifier, - LS_pound, - LS_pp, - LS_ppdef, - LS_char, - LS_char_multiline, - LS_char_slashed, - LS_string, - LS_string_multiline, - LS_string_slashed, - LS_number, - LS_number0, - LS_float, - LS_crazy_float0, - LS_crazy_float1, - LS_hex, - LS_comment_pre, - LS_comment, - LS_comment_slashed, - LS_comment_block, - LS_comment_block_ending, - LS_dot, - LS_ellipsis, - LS_less, - LS_less_less, - LS_more, - LS_more_more, - LS_minus, - LS_arrow, - LS_and, - LS_or, - LS_plus, - LS_colon, - LS_star, - LS_modulo, - LS_caret, - LS_eq, - LS_bang, - LS_error_message, + LS_default = 0, + LS_identifier = 1, + LS_pound = 2, + LS_pp = 3, + LS_ppdef = 4, + LS_char = 5, + LS_char_multiline = 6, + LS_char_slashed = 7, + LS_string = 8, + LS_string_multiline = 9, + LS_string_slashed = 10, + LS_number = 11, + LS_number0 = 12, + LS_float = 13, + LS_crazy_float0 = 14, + LS_crazy_float1 = 15, + LS_hex = 16, + LS_comment_pre = 17, + LS_comment = 18, + LS_comment_slashed = 19, + LS_comment_block = 20, + LS_comment_block_ending = 21, + LS_dot = 22, + LS_ellipsis = 23, + LS_less = 24, + LS_less_less = 25, + LS_more = 26, + LS_more_more = 27, + LS_minus = 28, + LS_arrow = 29, + LS_and = 30, + LS_or = 31, + LS_plus = 32, + LS_colon = 33, + LS_star = 34, + LS_modulo = 35, + LS_caret = 36, + LS_eq = 37, + LS_bang = 38, + LS_error_message = 39, // - LS_count + LS_count = 40 }; ENUM_INTERNAL(uint8_t, Cpp_Lex_Int_State){ @@ -454,6 +457,7 @@ ENUM_INTERNAL(uint8_t, Cpp_Lex_PP_State){ LSPP_number, LSPP_error, LSPP_junk, + LSPP_no_strings, // LSPP_count }; diff --git a/4ed.cpp b/4ed.cpp index a4a25098..f2a89949 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -1679,15 +1679,15 @@ App_Step_Sig(app_step){ } } - b32 mouse_on_divider = 0; - b32 mouse_divider_vertical = 0; + b32 mouse_on_divider = false; + b32 mouse_divider_vertical = false; i32 mouse_divider_id = 0; i32 mouse_divider_side = 0; if (mouse_in_margin_area){ Panel *panel = mouse_panel; if (mx >= panel->inner.x0 && mx < panel->inner.x1){ - mouse_divider_vertical = 0; + mouse_divider_vertical = false; if (my > panel->inner.y0){ mouse_divider_side = -1; } @@ -1696,7 +1696,7 @@ App_Step_Sig(app_step){ } } else{ - mouse_divider_vertical = 1; + mouse_divider_vertical = true; if (mx > panel->inner.x0){ mouse_divider_side = -1; } @@ -1706,15 +1706,14 @@ App_Step_Sig(app_step){ } if (models->layout.panel_count > 1){ - i32 which_child; mouse_divider_id = panel->parent; - which_child = panel->which_child; + i32 which_child = panel->which_child; for (;;){ Divider_And_ID div =layout_get_divider(&models->layout, mouse_divider_id); if (which_child == mouse_divider_side && div.divider->v_divider == mouse_divider_vertical){ - mouse_on_divider = 1; + mouse_on_divider = true; break; } @@ -1775,8 +1774,6 @@ App_Step_Sig(app_step){ cmd->key = null_key_event_data; - Temp_Memory param_stack_temp = begin_temp_memory(&models->mem.part); - if (input->first_step){ #if 0 @@ -1887,12 +1884,9 @@ App_Step_Sig(app_step){ for (i32 i = 0; i < 128 && command_coroutine; ++i){ User_Input user_in = {0}; - user_in.abort = 1; + user_in.abort = true; - command_coroutine = - app_resume_coroutine(system, &models->app_links, Co_Command, - command_coroutine, &user_in, - models->command_coroutine_flags); + command_coroutine = app_resume_coroutine(system, &models->app_links, Co_Command, command_coroutine, &user_in, models->command_coroutine_flags); } if (command_coroutine != 0){ // TODO(allen): post grave warning @@ -1970,35 +1964,33 @@ App_Step_Sig(app_step){ if (map == 0) map = &models->map_top; Command_Binding cmd_bind = map_extract_recursive(map, key); - User_Input user_in; + User_Input user_in = {0}; user_in.type = UserInputKey; user_in.key = key; user_in.command.command = cmd_bind.custom; - user_in.abort = 0; if ((EventOnEsc & abort_flags) && key.keycode == key_esc){ - user_in.abort = 1; + user_in.abort = true; } else if (EventOnAnyKey & abort_flags){ - user_in.abort = 1; + user_in.abort = true; } if (EventOnAnyKey & get_flags){ - pass_in = 1; + pass_in = true; consume_input(&vars->available_input, Input_AnyKey, "command coroutine"); } if (key.keycode == key_esc){ if (EventOnEsc & get_flags){ - pass_in = 1; + pass_in = true; } consume_input(&vars->available_input, Input_Esc, "command coroutine"); } if (pass_in){ - models->command_coroutine = - app_resume_coroutine(system, &models->app_links, Co_Command, command_coroutine, &user_in, models->command_coroutine_flags); + models->command_coroutine = app_resume_coroutine(system, &models->app_links, Co_Command, command_coroutine, &user_in, models->command_coroutine_flags); - app_result.animating = 1; + app_result.animating = true; // TOOD(allen): Deduplicate // TODO(allen): Should I somehow allow a view to clean up however it wants after a @@ -2017,55 +2009,52 @@ App_Step_Sig(app_step){ USE_VIEW(view); b32 pass_in = 0; - User_Input user_in; + User_Input user_in = {0}; user_in.type = UserInputMouse; user_in.mouse = input->mouse; - user_in.command.cmdid = 0; - user_in.abort = 0; if (abort_flags & EventOnMouseMove){ - user_in.abort = 1; + user_in.abort = true; } if (get_flags & EventOnMouseMove){ - pass_in = 1; + pass_in = true; consume_input(&vars->available_input, Input_MouseMove, "command coroutine"); } if (input->mouse.press_l || input->mouse.release_l || input->mouse.l){ if (abort_flags & EventOnLeftButton){ - user_in.abort = 1; + user_in.abort = true; } if (get_flags & EventOnLeftButton){ - pass_in = 1; + pass_in = true; consume_input(&vars->available_input, Input_MouseLeftButton, "command coroutine"); } } if (input->mouse.press_r || input->mouse.release_r || input->mouse.r){ if (abort_flags & EventOnRightButton){ - user_in.abort = 1; + user_in.abort = true; } if (get_flags & EventOnRightButton){ - pass_in = 1; + pass_in = true; consume_input(&vars->available_input, Input_MouseRightButton, "command coroutine"); } } if (input->mouse.wheel != 0){ if (abort_flags & EventOnWheel){ - user_in.abort = 1; + user_in.abort = true; } if (get_flags & EventOnWheel){ - pass_in = 1; + pass_in = true; consume_input(&vars->available_input, Input_MouseWheel, "command coroutine"); } } if (pass_in){ - models->command_coroutine = - app_resume_coroutine(system, &models->app_links, Co_Command, command_coroutine, &user_in, models->command_coroutine_flags); + models->command_coroutine = app_resume_coroutine(system, &models->app_links, Co_Command, command_coroutine, &user_in, models->command_coroutine_flags); - app_result.animating = 1; + app_result.animating = true; // TOOD(allen): Deduplicate // TODO(allen): Should I somehow allow a view to clean up however it wants after a @@ -2514,11 +2503,31 @@ App_Step_Sig(app_step){ } if (mouse_in_edit_area && mouse_panel != 0 && input->mouse.press_l){ - models->layout.active_panel = (i32)(mouse_panel - models->layout.panels); + i32 new_panel_id = (i32)(mouse_panel - models->layout.panels); + if (models->layout.active_panel != new_panel_id){ + if (models->command_coroutine != 0){ + User_Input user_in = {0}; + user_in.abort = true; + + for (u32 j = 0; j < 10 && models->command_coroutine != 0; ++j){ + models->command_coroutine = app_resume_coroutine(system, &models->app_links, Co_Command, models->command_coroutine, &user_in, models->command_coroutine_flags); + } + + if (models->command_coroutine != 0){ + // TODO(allen): post grave warning + models->command_coroutine = 0; + } + + Panel *active_panel = &models->layout.panels[models->layout.active_panel]; + View *view = active_panel->view; + init_query_set(&view->query_set); + } + + models->layout.active_panel = new_panel_id; + app_result.animating = true; + } } - end_temp_memory(param_stack_temp); - // NOTE(allen): on the first frame there should be no scrolling if (input->first_step){ Panel *panel = 0, *used_panels = &models->layout.used_sentinel; diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index b4a1a667..2d840ed7 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -514,10 +514,9 @@ DOC_SEE(Buffer_ID) Command_Data *cmd = (Command_Data*)app->cmd_context; Working_Set *working_set = &cmd->models->working_set; Buffer_Summary buffer = {}; - Editing_File *file; - file = working_set_get_active_file(working_set, buffer_id); - if (file){ + Editing_File *file = working_set_get_active_file(working_set, buffer_id); + if (file != 0){ fill_buffer_summary(&buffer, file, working_set); if (!access_test(buffer.lock_flags, access)){ buffer = null_buffer_summary; @@ -539,11 +538,9 @@ DOC_SEE(Access_Flag) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; Buffer_Summary buffer = {}; - Editing_File *file; Working_Set *working_set = &cmd->models->working_set; - String str = make_string(name, len); - file = working_set_name_contains(working_set, str); + Editing_File *file = working_set_name_contains(working_set, make_string(name, len)); if (file && !file->is_dummy){ fill_buffer_summary(&buffer, file, working_set); if (!access_test(buffer.lock_flags, access)){ @@ -728,6 +725,18 @@ DOC_SEE(Marker) return(result); } +API_EXPORT Buffer_Summary +Get_Buffer_By_Marker_Handle(Application_Links *app, Marker_Handle marker, Access_Flag access) +/* +DOC_PARAM(marker, The marker handle to query.) +DOC_PARAM(access, The access parameter determines what levels of protection this call can access.) +DOC_SEE(Marker) +*/{ + Buffer_ID buffer_id = get_buffer_id_from_marker_handle(marker); + Buffer_Summary buffer = Get_Buffer(app, buffer_id, access); + return(buffer); +} + API_EXPORT bool32 Buffer_Set_Markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers) /* @@ -817,6 +826,7 @@ DOC_RETURN(returns non-zero on success) result = 1; switch (setting){ case BufferSetting_Lex: *value_out = file->settings.tokens_exist; break; + case BufferSetting_LexWithoutStrings: *value_out = file->settings.tokens_without_strings; break; case BufferSetting_WrapLine: *value_out = !file->settings.unwrapped_lines; break; case BufferSetting_WrapPosition: *value_out = file->settings.display_width; break; case BufferSetting_MinimumBaseWrapPosition: *value_out = file->settings.minimum_base_display_width; break; @@ -845,12 +855,12 @@ DOC_SEE(Buffer_Setting_ID) Models *models = cmd->models; Editing_File *file = imp_get_file(cmd, buffer); - bool32 result = 0; + bool32 result = false; i32 new_mapid = 0; - if (file){ - result = 11; + if (file != 0){ + result = true; switch (setting){ case BufferSetting_Lex: { @@ -871,6 +881,25 @@ DOC_SEE(Buffer_Setting_ID) } }break; + case BufferSetting_LexWithoutStrings: + { + if (file->settings.tokens_exist){ + if ((b8)value != file->settings.tokens_without_strings){ + file_kill_tokens(system, &models->mem.general, file); + file->settings.tokens_without_strings = (b8)value; + if (!file->settings.virtual_white){ + file_first_lex_parallel(system, &models->mem, file); + } + else{ + file_first_lex_serial(&models->mem, file); + } + } + } + else{ + file->settings.tokens_without_strings = (b8)value; + } + }break; + case BufferSetting_WrapLine: { file->settings.unwrapped_lines = !value; @@ -2267,17 +2296,21 @@ DOC(After this call the file list passed in should not be read or written to.) } API_EXPORT void -Set_GUI_Up_Down_Keys(Application_Links *app, int16_t up_key, int16_t down_key) +Set_GUI_Up_Down_Keys(Application_Links *app, Key_Code up_key, Key_Modifier up_key_modifier, Key_Code down_key, Key_Modifier down_key_modifier) /* DOC_PARAM(up_key, the code of the key that should be interpreted as an up key) +DOC_PARAM(up_key_modifier, the modifier for the key that should be interpreted as an up key) DOC_PARAM(down_key, the code of the key that should be interpreted as a down key) +DOC_PARAM(down_key_modifier, the modifier for the key that should be interpreted as a down key) DOC(This is a temporary ad-hoc solution to allow some customization of the behavior of the built in GUI. There is a high chance that it will be removed and not replaced at some point, so it is not recommended that it be heavily used.) */ { Command_Data *cmd = (Command_Data*)app->cmd_context; Models *models = cmd->models; models->user_up_key = up_key; + models->user_up_key_modifier = up_key_modifier; models->user_down_key = down_key; + models->user_down_key_modifier = down_key_modifier; } API_EXPORT void* diff --git a/4ed_app_models.h b/4ed_app_models.h index a69c1833..dbcecda9 100644 --- a/4ed_app_models.h +++ b/4ed_app_models.h @@ -91,6 +91,8 @@ struct Models{ Key_Code user_up_key; Key_Code user_down_key; + Key_Modifier user_up_key_modifier; + Key_Modifier user_down_key_modifier; }; // BOTTOM diff --git a/4ed_file.cpp b/4ed_file.cpp index 6250f708..11fc83b4 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -64,7 +64,7 @@ struct Text_Effect{ // union Buffer_Slot_ID{ - i32 id; + Buffer_ID id; i16 part[2]; }; inline Buffer_Slot_ID @@ -98,11 +98,12 @@ struct Editing_File_Settings{ Font_ID font_id; b8 unwrapped_lines; b8 tokens_exist; + b8 tokens_without_strings; b8 is_initialized; b8 unimportant; b8 read_only; b8 never_kill; - u8 pad[2]; + u8 pad[1]; }; global_const Editing_File_Settings null_editing_file_settings = {0}; @@ -229,6 +230,13 @@ allocate_markers_state(General_Memory *general, Editing_File *file, u32 new_arra return(array); } +internal Buffer_ID +get_buffer_id_from_marker_handle(void *handle){ + Marker_Array *markers = (Marker_Array*)handle; + Buffer_Slot_ID result = markers->buffer_id; + return(result.id); +} + internal b32 markers_set(Editing_File *file, void *handle, u32 first_index, u32 count, Marker *source){ Assert(file != 0); diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index acb2f3ad..87920d9a 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -2147,7 +2147,7 @@ Job_Callback_Sig(job_full_lex){ b32 still_lexing = 1; - Cpp_Lex_Data lex = cpp_lex_data_init(); + Cpp_Lex_Data lex = cpp_lex_data_init(file->settings.tokens_without_strings); // TODO(allen): deduplicate this against relex char *chunks[3]; @@ -2289,7 +2289,7 @@ file_first_lex_serial(Mem_Options *mem, Editing_File *file){ b32 still_lexing = 1; - Cpp_Lex_Data lex = cpp_lex_data_init(); + Cpp_Lex_Data lex = cpp_lex_data_init(file->settings.tokens_without_strings); // TODO(allen): deduplicate this against relex char *chunks[3]; @@ -2398,7 +2398,7 @@ file_relex_parallel(System_Functions *system, Mem_Options *mem, Editing_File *fi i32 size = buffer_size(buffer); - Cpp_Relex_Data state = cpp_relex_init(array, start_i, end_i, shift_amount); + Cpp_Relex_Data state = cpp_relex_init(array, start_i, end_i, shift_amount, file->settings.tokens_without_strings); char *chunks[3]; i32 chunk_sizes[3]; @@ -2518,7 +2518,7 @@ file_relex_serial(Mem_Options *mem, Editing_File *file, i32 start_i, i32 end_i, i32 size = buffer_size(buffer); - Cpp_Relex_Data state = cpp_relex_init(array, start_i, end_i, shift_amount); + Cpp_Relex_Data state = cpp_relex_init(array, start_i, end_i, shift_amount, file->settings.tokens_without_strings); char *chunks[3]; i32 chunk_sizes[3]; @@ -4908,6 +4908,8 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su Key_Code user_up_key = models->user_up_key; Key_Code user_down_key = models->user_down_key; + Key_Modifier user_up_key_modifier = models->user_up_key_modifier; + Key_Modifier user_down_key_modifier = models->user_down_key_modifier; switch (view->interaction){ case IInt_Sys_File_List: @@ -4966,7 +4968,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su if (gui_begin_list(target, id, view->list_i, 0, snap_into_view, &update)){ // TODO(allen): Allow me to handle key consumption correctly here! - gui_standard_list(target, id, &view->gui_scroll, view->scroll_region, &keys, &view->list_i, &update, user_up_key, user_down_key); + gui_standard_list(target, id, &view->gui_scroll, view->scroll_region, &keys, &view->list_i, &update, user_up_key, user_up_key_modifier, user_down_key, user_down_key_modifier); } b32 do_new_directory = false; @@ -5063,7 +5065,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su id.id[0] = (u64)(working_set) + 1; if (gui_begin_list(target, id, view->list_i, 0, snap_into_view, &update)){ - gui_standard_list(target, id, &view->gui_scroll, view->scroll_region, &keys, &view->list_i, &update, user_up_key, user_down_key); + gui_standard_list(target, id, &view->gui_scroll, view->scroll_region, &keys, &view->list_i, &update, user_up_key, user_up_key_modifier, user_down_key, user_down_key_modifier); } { @@ -5648,21 +5650,13 @@ struct Input_Process_Result{ i32 max_y; }; -static char -to_writable_char(Key_Code long_character){ - char character = 0; - if (long_character < ' '){ - if (long_character == '\n'){ - character = '\n'; - } - else if (long_character == '\t'){ - character = '\t'; - } +static u32 +to_writable_character(Key_Code long_character, u8 *character){ + u32 result = 0; + if (long_character != 0){ + u32_to_utf8_unchecked(long_character, character, &result); } - else if (long_character >= ' ' && long_character <= 255 && long_character != 127){ - character = (char)long_character; - } - return(character); + return(result); } internal Input_Process_Result @@ -5775,11 +5769,15 @@ do_step_file_view(System_Functions *system, View *view, i32_Rect rect, b32 is_ac i32 count = keys->count; for (i32 i = 0; i < count; ++i){ Key_Event_Data key = get_single_key(keys, i); - char character = to_writable_char(key.character); - if (char_to_upper(character) == activation_key){ - target->active = b->id; - result.is_animating = 1; - break; + + u8 character[4]; + u32 length = to_writable_character(key.character, character); + if (length == 1){ + if (char_to_upper(character[0]) == activation_key){ + target->active = b->id; + result.is_animating = 1; + break; + } } } } diff --git a/4ed_gui.cpp b/4ed_gui.cpp index 521bf4f7..389ceb4c 100644 --- a/4ed_gui.cpp +++ b/4ed_gui.cpp @@ -1254,31 +1254,50 @@ gui_do_jump(GUI_Target *target, GUI_View_Jump jump, GUI_Scroll_Vars vars){ } internal void -gui_standard_list(GUI_Target *target, GUI_id id, GUI_Scroll_Vars *vars, i32_Rect scroll_region, Key_Input_Data *keys, i32 *list_i, GUI_Item_Update *update, Key_Code user_up_key, Key_Code user_down_key){ - +gui_standard_list(GUI_Target *target, GUI_id id, GUI_Scroll_Vars *vars, i32_Rect scroll_region, Key_Input_Data *keys, i32 *list_i, GUI_Item_Update *update, Key_Code user_up_key, Key_Modifier user_up_key_modifier, Key_Code user_down_key, Key_Modifier user_down_key_modifier){ if (update->has_adjustment){ *list_i = update->adjustment_value; } if (update->has_index_position){ - GUI_View_Jump jump = - gui_compute_view_jump(scroll_region, update->index_position); + GUI_View_Jump jump = gui_compute_view_jump(scroll_region, update->index_position); jump.view_min = jump.view_min + 45; jump.view_max = jump.view_max - 45; *vars = gui_do_jump(target, jump, *vars); } + i8 modifiers_up[3]; + modifiers_up[0] = ((user_up_key_modifier & MDFR_CTRL) != 0); + modifiers_up[1] = ((user_up_key_modifier & MDFR_ALT) != 0); + modifiers_up[2] = ((user_up_key_modifier & MDFR_SHIFT) != 0); + + i8 modifiers_down[3]; + modifiers_down[0] = ((user_down_key_modifier & MDFR_CTRL) != 0); + modifiers_down[1] = ((user_down_key_modifier & MDFR_ALT) != 0); + modifiers_down[2] = ((user_down_key_modifier & MDFR_SHIFT) != 0); + b32 indirectly_activate = 0; for (i32 j = 0; j < keys->count; ++j){ - Key_Code key = keys->keys[j].keycode; + Key_Event_Data key = keys->keys[j]; + b32 modifiers_match_up = false; + b32 modifiers_match_down = false; - if (key == user_up_key){ + if (modifiers_up[0] == key.modifiers[MDFR_CONTROL_INDEX] && modifiers_up[1] == key.modifiers[MDFR_ALT_INDEX] && modifiers_up[2] == key.modifiers[MDFR_SHIFT_INDEX]){ + modifiers_match_up = true; + } + + if (modifiers_down[0] == key.modifiers[MDFR_CONTROL_INDEX] && modifiers_down[1] == key.modifiers[MDFR_ALT_INDEX] && modifiers_down[2] == key.modifiers[MDFR_SHIFT_INDEX]){ + modifiers_match_down = true; + } + + if (key.keycode == user_up_key && modifiers_match_up){ --*list_i; } - else if (key == user_down_key){ + else if (key.keycode == user_down_key && modifiers_match_down){ ++*list_i; } - else if (key == '\n' || key == '\t'){ + + else if (key.keycode == '\n' || key.keycode == '\t'){ indirectly_activate = 1; } } diff --git a/4ed_site.ctm b/4ed_site.ctm index f9650050..1462a540 100644 Binary files a/4ed_site.ctm and b/4ed_site.ctm differ diff --git a/meta/fsm_table_generator.cpp b/meta/fsm_table_generator.cpp index 2cb34ee3..9b1f54ec 100644 --- a/meta/fsm_table_generator.cpp +++ b/meta/fsm_table_generator.cpp @@ -11,6 +11,8 @@ #include #include +typedef int32_t bool32; + #define Assert(n) do{ if (!(n)) { *(int*)0 = 0xA11E; } }while(0) #define ArrayCount(a) (sizeof(a)/sizeof(*a)) @@ -100,7 +102,7 @@ int_fsm(Cpp_Lex_FSM fsm, char c){ } Cpp_Lex_FSM -main_fsm(Cpp_Lex_FSM fsm, uint8_t pp_state, uint8_t c){ +main_fsm(Cpp_Lex_FSM fsm, uint8_t pp_state, uint8_t c, bool32 ignore_string_delims){ if (c == 0){ fsm.emit_token = 1; } @@ -125,15 +127,32 @@ main_fsm(Cpp_Lex_FSM fsm, uint8_t pp_state, uint8_t c){ } else{ switch (c){ - case '\'': fsm.state = LS_char; break; - case '"': fsm.state = LS_string; break; + case '\'': + { + if (ignore_string_delims){ + fsm.state = LS_identifier; + } + else{ + fsm.state = LS_char; + } + }break; + + case '"': + { + if (ignore_string_delims){ + fsm.state = LS_identifier; + } + else{ + fsm.state = LS_string; + } + }break; case '/': fsm.state = LS_comment_pre; break; case '.': fsm.state = LS_dot; break; case '<': - if (pp_state == LSPP_include){ + if (pp_state == LSPP_include && !ignore_string_delims){ fsm.state = LS_string; } else{ @@ -193,7 +212,8 @@ main_fsm(Cpp_Lex_FSM fsm, uint8_t pp_state, uint8_t c){ case LS_identifier: { - int is_ident = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == '$' || c >= 128; + int is_ident = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == '$' || c >= 128 || (ignore_string_delims && (c == '\'' || c == '"')); + if (!is_ident){ fsm.emit_token = 1; } @@ -210,7 +230,7 @@ main_fsm(Cpp_Lex_FSM fsm, uint8_t pp_state, uint8_t c){ if (c == ' ' || c == '\r' || c == '\v' || c == '\f'){ // NOTE(allen): do nothing } - else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c >= 128){ + else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c >= 128 || (ignore_string_delims && (c == '\'' || c == '"'))){ fsm.state = LS_ppdef; } else{ @@ -220,47 +240,75 @@ main_fsm(Cpp_Lex_FSM fsm, uint8_t pp_state, uint8_t c){ case LS_ppdef: { - int is_ident = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c >= 128; + int is_ident = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c >= 128 || (ignore_string_delims && (c == '\'' || c == '"')); if (!is_ident){ fsm.emit_token = 1; } }break; case LS_char: case LS_char_multiline: - switch(c){ - case '\n': case '\'': fsm.emit_token = 1; break; - case '\\': fsm.state = LS_char_slashed; break; - } - break; + { + if (ignore_string_delims){ + fsm.state = LS_string; + fsm.emit_token = 1; + } + else{ + switch(c){ + case '\n': case '\'': fsm.emit_token = 1; break; + case '\\': fsm.state = LS_char_slashed; break; + } + } + }break; case LS_char_slashed: - switch (c){ - case '\r': case '\f': case '\v': break; - case '\n': fsm.state = LS_char_multiline; break; - default: fsm.state = LS_char; break; - } - break; + { + if (ignore_string_delims){ + fsm.state = LS_string; + fsm.emit_token = 1; + } + else{ + switch (c){ + case '\r': case '\f': case '\v': break; + case '\n': fsm.state = LS_char_multiline; break; + default: fsm.state = LS_char; break; + } + } + }break; case LS_string: case LS_string_multiline: - switch(c){ - case '\n': case '\"': fsm.emit_token = 1; break; - case '>': - if (pp_state == LSPP_include){ + { + if (ignore_string_delims){ + fsm.state = LS_string; fsm.emit_token = 1; } - break; - case '\\': fsm.state = LS_string_slashed; break; - } - break; + else{ + switch(c){ + case '\n': case '"': fsm.emit_token = 1; break; + case '>': + if (pp_state == LSPP_include){ + fsm.emit_token = 1; + } + break; + case '\\': fsm.state = LS_string_slashed; break; + } + } + }break; case LS_string_slashed: - switch (c){ - case '\r': case '\f': case '\v': break; - case '\n': fsm.state = LS_string_multiline; break; - default: fsm.state = LS_string; break; - } - break; + { + if (ignore_string_delims){ + fsm.state = LS_string; + fsm.emit_token = 1; + } + else{ + switch (c){ + case '\r': case '\f': case '\v': break; + case '\n': fsm.state = LS_string_multiline; break; + default: fsm.state = LS_string; break; + } + } + }break; case LS_number: if (c >= '0' && c <= '9'){ @@ -633,7 +681,7 @@ generate_int_table(){ } static FSM_Tables -generate_fsm_table(uint8_t pp_state){ +generate_fsm_table(uint8_t pp_state, bool32 ignore_string_delims){ uint8_t state_count = LS_count; FSM_Tables table; allocate_full_tables(&table, state_count); @@ -645,7 +693,7 @@ generate_fsm_table(uint8_t pp_state){ for (uint8_t state = 0; state < state_count; ++state){ fsm.state = state; fsm.emit_token = 0; - new_fsm = main_fsm(fsm, pp_state, (uint8_t)c); + new_fsm = main_fsm(fsm, pp_state, (uint8_t)c, ignore_string_delims); table.full_transition_table[i++] = new_fsm.state + state_count*new_fsm.emit_token; } } @@ -690,24 +738,25 @@ render_comment(FILE *file, char *comment){ typedef struct PP_Names{ uint8_t pp_state; char *name; + bool32 ignore_string_delims; } PP_Names; static PP_Names pp_names[] = { - {LSPP_default, "main_fsm"}, - {LSPP_include, "pp_include_fsm"}, - {LSPP_macro_identifier, "pp_macro_fsm"}, - {LSPP_identifier, "pp_identifier_fsm"}, - {LSPP_body_if, "pp_body_if_fsm"}, - {LSPP_body, "pp_body_fsm"}, - {LSPP_number, "pp_number_fsm"}, - {LSPP_error, "pp_error_fsm"}, - {LSPP_junk, "pp_junk_fsm"}, + {LSPP_default, "main_fsm", false}, + {LSPP_include, "pp_include_fsm", false}, + {LSPP_macro_identifier, "pp_macro_fsm", false}, + {LSPP_identifier, "pp_identifier_fsm", false}, + {LSPP_body_if, "pp_body_if_fsm", false}, + {LSPP_body, "pp_body_fsm", false}, + {LSPP_number, "pp_number_fsm", false}, + {LSPP_error, "pp_error_fsm", false}, + {LSPP_junk, "pp_junk_fsm", false}, + {LSPP_default, "no_string_fsm", true}, }; int main(){ - FILE *file; - file = fopen(LEXER_TABLE_FILE, "wb"); + FILE *file = fopen(LEXER_TABLE_FILE, "wb"); FSM_Tables wtables = generate_whitespace_skip_table(); render_fsm_table(file, wtables, "whitespace_fsm"); @@ -723,8 +772,7 @@ main(){ end_table(file); for (int32_t i = 0; i < ArrayCount(pp_names); ++i){ - Assert(i == pp_names[i].pp_state); - FSM_Tables tables = generate_fsm_table(pp_names[i].pp_state); + FSM_Tables tables = generate_fsm_table(pp_names[i].pp_state, pp_names[i].ignore_string_delims); render_fsm_table(file, tables, pp_names[i].name); } diff --git a/power/4coder_experiments.cpp b/power/4coder_experiments.cpp index b9c941f9..7d6f12b1 100644 --- a/power/4coder_experiments.cpp +++ b/power/4coder_experiments.cpp @@ -9,8 +9,11 @@ TYPE: 'build-target' #if !defined(FCODER_EXPERIMENTS_CPP) #define FCODER_EXPERIMENTS_CPP +#define FCODER_JUMP_COMMANDS #include "4coder_default_include.cpp" #include "4coder_miblo_numbers.cpp" +#undef FCODER_JUMP_COMMANDS +#include "4coder_sticky_jump.cpp" #define NO_BINDING #include "4coder_default_bindings.cpp" diff --git a/power/4coder_sticky_jump.cpp b/power/4coder_sticky_jump.cpp new file mode 100644 index 00000000..e5ddbea1 --- /dev/null +++ b/power/4coder_sticky_jump.cpp @@ -0,0 +1,518 @@ +/* +4coder_sticky_jump.cpp - Commands and helpers for parsing jump locations from +compiler errors, sticking markers on jump locations, and jumping to them. + +TYPE: 'drop-in-command-pack' +*/ + +// TOP + +#if !defined(FCODER_STICKY_JUMP) && !defined(FCODER_JUMP_COMMANDS) +#define FCODER_STICKY_JUMP + +#define FCODER_JUMP_COMMANDS + +#include "4coder_default_framework.h" +#include "4coder_helper/4coder_long_seek.h" +#include "4coder_helper/4coder_helper.h" +#include "4coder_helper/4coder_jump_parsing.h" + +#include "4coder_lib/4coder_mem.h" +#include "4coder_jumping.h" + +static uint32_t +binary_search(uint32_t *array, uint32_t count, uint32_t x){ + uint32_t i = 0; + uint32_t first = 0; + uint32_t last = count; + if (first < last){ + for (;;){ + i = (first + last)/2; + if (array[i] < x){ + first = i; + } + else if (array[i] > x){ + last = i; + } + else{ // NOTE(allen): array[i] == x + break; + } + if (first+1 >= last){ + i = first; + break; + } + } + } + return(i); +} + +struct Marker_List{ + uint32_t *handle_starts; + Marker_Handle *handles; + uint32_t *jump_line_numbers; + uint32_t handle_count; + uint32_t handle_max; + int32_t jump_max; + int32_t jump_count; +}; + +static void +double_jump_max(General_Memory *general, Marker_List *list){ + uint32_t new_jump_max = list->jump_max*2; + list->jump_line_numbers = gen_realloc_array(general, uint32_t, list->jump_line_numbers, list->jump_max, new_jump_max); + list->jump_max = new_jump_max; +} + +static void +double_handle_max(General_Memory *general, Marker_List *list){ + uint32_t new_handle_max = list->handle_max*2; + list->handle_starts = gen_realloc_array(general, uint32_t, list->handle_starts, list->handle_max, new_handle_max); + list->handles = gen_realloc_array(general, Marker_Handle, list->handles, list->handle_max, new_handle_max); + list->handle_max = new_handle_max; +} + +// TODO(allen): what to do when a push returns 0? +static Marker_List +make_marker_list(Application_Links *app, Partition *part, General_Memory *general, int32_t buffer_id){ + Marker_List list = {0}; + + int32_t line = 1; + + Temp_Memory temp = begin_temp_memory(part); + ID_Based_Jump_Location *location_list = (ID_Based_Jump_Location*)partition_current(part); + uint32_t location_count = 0; + + list.handle_max = 64; + list.handle_starts = gen_array(general, uint32_t, list.handle_max); + list.handles = gen_array(general, Marker_Handle, list.handle_max); + + list.jump_max = 64; + list.jump_line_numbers = gen_array(general, uint32_t, list.jump_max); + + uint32_t prev_jump_count = 0; + for (;;){ + int32_t this_jump_line = 0; + int32_t colon_index = 0; + Name_Based_Jump_Location location = {0}; + + Temp_Memory temp_name = begin_temp_memory(part); + if (seek_next_jump_in_buffer(app, part, buffer_id, line, false, 1, &this_jump_line, &colon_index, &location)){ + Buffer_Summary jump_buffer = {0}; + if (open_file(app, &jump_buffer, location.file.str, location.file.size, false, true)){ + ID_Based_Jump_Location id_location = {0}; + end_temp_memory(temp_name); + id_location.buffer_id = jump_buffer.buffer_id; + id_location.line = location.line; + id_location.column = location.column; + + if (id_location.buffer_id != 0){ + if (location_count > 0){ + ID_Based_Jump_Location *prev_location = &location_list[location_count-1]; + if (prev_location->buffer_id != id_location.buffer_id){ + Buffer_Summary location_buffer = get_buffer(app, prev_location->buffer_id, AccessAll); + + if (location_buffer.exists){ + if (list.handle_count >= list.handle_max){ + double_handle_max(general, &list); + } + + Marker_Handle new_handle = buffer_add_markers(app, &location_buffer, location_count); + + list.handle_starts[list.handle_count] = prev_jump_count; + list.handles[list.handle_count] = new_handle; + ++list.handle_count; + + prev_jump_count = list.jump_count; + + Marker *markers = push_array(part, Marker, location_count); + for (uint32_t i = 0; i < location_count; ++i){ + ID_Based_Jump_Location *location = &location_list[i]; + Partial_Cursor cursor = {0}; + Buffer_Seek seek = seek_line_char(location->line, location->column); + if (buffer_compute_cursor(app, &location_buffer, seek, &cursor)){ + markers[i].pos = cursor.pos; + markers[i].lean_right = false; + } + } + + buffer_set_markers(app, &location_buffer, new_handle, 0, location_count, markers); + + location_count = 0; + reset_temp_memory(temp); + } + } + } + + ID_Based_Jump_Location *new_id_location = push_struct(part, ID_Based_Jump_Location); + *new_id_location = id_location; + ++location_count; + + if (list.jump_count >= list.jump_max){ + double_jump_max(general, &list); + } + list.jump_line_numbers[list.jump_count] = this_jump_line; + ++list.jump_count; + } + } + else{ + end_temp_memory(temp_name); + } + + line = this_jump_line+1; + } + else{ + end_temp_memory(temp_name); + break; + } + } + + if (location_count > 0){ + ID_Based_Jump_Location *prev_location = &location_list[location_count-1]; + Buffer_Summary location_buffer = get_buffer(app, prev_location->buffer_id, AccessAll); + + if (list.handle_count >= list.handle_max){ + double_handle_max(general, &list); + } + + Marker_Handle new_handle = buffer_add_markers(app, &location_buffer, location_count); + + list.handle_starts[list.handle_count] = prev_jump_count; + list.handles[list.handle_count] = new_handle; + ++list.handle_count; + + prev_jump_count = list.jump_count; + + Marker *markers = push_array(part, Marker, location_count); + for (uint32_t i = 0; i < location_count; ++i){ + ID_Based_Jump_Location *location = &location_list[i]; + Partial_Cursor cursor = {0}; + Buffer_Seek seek = seek_line_char(location->line, location->column); + if (buffer_compute_cursor(app, &location_buffer, seek, &cursor)){ + markers[i].pos = cursor.pos; + markers[i].lean_right = false; + } + } + + buffer_set_markers(app, &location_buffer, new_handle, 0, location_count, markers); + + location_count = 0; + reset_temp_memory(temp); + } + + end_temp_memory(temp); + + return(list); +} + +static void +free_marker_list(General_Memory *general, Marker_List list){ + general_memory_free(general, list.handle_starts); + general_memory_free(general, list.handles); + general_memory_free(general, list.jump_line_numbers); +} + +struct Marker_List_Slot{ + Marker_List list; + int32_t buffer_id; +}; + +static Marker_List_Slot *marker_list_slots = 0; +static uint32_t marker_list_slot_count = 0; +static uint32_t marker_list_slot_max = 0; + +static Marker_List* +set_marker_list_for_buffer(int32_t buffer_id, Marker_List *list){ + Marker_List *result = 0; + General_Memory *general = &global_general; + + bool32 found_slot = false; + for (uint32_t i = 0; i < marker_list_slot_count; ++i){ + if (buffer_id == marker_list_slots[i].buffer_id){ + if (list != 0){ + marker_list_slots[i].list = *list; + result = &marker_list_slots[i].list; + } + else{ + void *dst = marker_list_slots+i; + void *src = marker_list_slots+i+1; + size_t amount = (marker_list_slot_count-i-1)*sizeof(Marker_List_Slot); + memmove(dst, src, amount); + --marker_list_slot_count; + } + found_slot = true; + break; + } + } + + if (!found_slot && list != 0){ + if (marker_list_slot_count >= marker_list_slot_max){ + if (marker_list_slots == 0){ + uint32_t new_max = 64; + marker_list_slots = gen_array(general, Marker_List_Slot, new_max); + marker_list_slot_max = new_max; + } + else{ + uint32_t new_max = 2*marker_list_slot_max; + marker_list_slots = gen_realloc_array(general, Marker_List_Slot, marker_list_slots, marker_list_slot_count, new_max); + marker_list_slot_max = new_max; + } + } + + marker_list_slots[marker_list_slot_count].buffer_id = buffer_id; + marker_list_slots[marker_list_slot_count].list = *list; + result = &marker_list_slots[marker_list_slot_count].list; + ++marker_list_slot_count; + } + return(result); +} + +static Marker_List* +get_marker_list_for_buffer(int32_t buffer_id){ + Marker_List *result = 0; + for (uint32_t i = 0; i < marker_list_slot_count; ++i){ + if (buffer_id == marker_list_slots[i].buffer_id){ + result = &marker_list_slots[i].list; + break; + } + } + return(result); +} + +static Marker_List* +get_or_make_list_for_buffer(Application_Links *app, Partition *part, General_Memory *general, int32_t buffer_id){ + Marker_List *result = get_marker_list_for_buffer(buffer_id); + if (result == 0){ + Marker_List new_list = make_marker_list(app, part, general, buffer_id); + result = set_marker_list_for_buffer(buffer_id, &new_list); + } + return(result); +} + +static bool32 +get_jump_from_list(Application_Links *app, Marker_List *list, int32_t index, ID_Pos_Jump_Location *location){ + bool32 result = false; + if (index >= 0 && index < list->jump_count){ + uint32_t handle_index = binary_search(list->handle_starts, list->handle_count, index); + uint32_t handle_start = list->handle_starts[handle_index]; + uint32_t marker_index = index - handle_start; + Marker_Handle handle = list->handles[handle_index]; + Buffer_Summary buffer = get_buffer_by_marker_handle(app, handle, AccessAll); + if (buffer.exists){ + Marker marker; + buffer_get_markers(app, &buffer, handle, marker_index, 1, &marker); + location->buffer_id = buffer.buffer_id; + location->pos = marker.pos; + result = true; + } + } + return(result); +} + +static int32_t +get_index_exact_from_list(Marker_List *list, int32_t line){ + int32_t result = -1; + uint32_t jump_index = binary_search(list->jump_line_numbers, list->jump_count, line); + if (list->jump_line_numbers[jump_index] == (uint32_t)line){ + result = jump_index; + } + return(result); +} + +static int32_t +get_index_nearest_from_list(Marker_List *list, int32_t line){ + int32_t result = binary_search(list->jump_line_numbers, list->jump_count, line); + return(result); +} + +static int32_t +get_line_from_list(Marker_List *list, int32_t index){ + int32_t result = 0; + if (index >= 0 && index < list->jump_count){ + result = list->jump_line_numbers[index]; + } + return(result); +} + +CUSTOM_COMMAND_SIG(goto_jump_at_cursor){ + General_Memory *general = &global_general; + Partition *part = &global_part; + + Temp_Memory temp = begin_temp_memory(part); + View_Summary view = get_active_view(app, AccessProtected); + Marker_List *list = get_or_make_list_for_buffer(app, part, general, view.buffer_id); + + int32_t list_index = get_index_exact_from_list(list, view.cursor.line); + + if (list_index >= 0){ + ID_Pos_Jump_Location location = {0}; + if (get_jump_from_list(app, list, list_index, &location)){ + Buffer_Summary buffer = {0}; + if (get_jump_buffer(app, &buffer, &location)){ + change_active_panel(app); + View_Summary target_view = get_active_view(app, AccessAll); + switch_to_existing_view(app, &target_view, &buffer); + jump_to_location(app, &target_view, &buffer, location); + } + } + } + + end_temp_memory(temp); +} + +CUSTOM_COMMAND_SIG(goto_jump_at_cursor_same_panel){ + General_Memory *general = &global_general; + Partition *part = &global_part; + + Temp_Memory temp = begin_temp_memory(part); + View_Summary view = get_active_view(app, AccessProtected); + Marker_List *list = get_or_make_list_for_buffer(app, part, general, view.buffer_id); + int32_t list_index = get_index_exact_from_list(list, view.cursor.line); + + if (list_index >= 0){ + ID_Pos_Jump_Location location = {0}; + if (get_jump_from_list(app, list, list_index, &location)){ + Buffer_Summary buffer = {0}; + if (get_jump_buffer(app, &buffer, &location)){ + View_Summary target_view = view; + jump_to_location(app, &target_view, &buffer, location); + } + } + } + + end_temp_memory(temp); +} + +// TODO(allen): MASSIVELY DEDUPLICATE THIS PLEASE. +CUSTOM_COMMAND_SIG(goto_next_jump){ + General_Memory *general = &global_general; + Partition *part = &global_part; + + View_Summary view = get_view_for_locked_jump_buffer(app); + if (view.exists){ + Marker_List *list = get_or_make_list_for_buffer(app, part, general, view.buffer_id); + int32_t list_index = get_index_nearest_from_list(list, view.cursor.line); + ++list_index; + + if (list_index >= 0 && list_index < list->jump_count){ + ID_Pos_Jump_Location location = {0}; + if (get_jump_from_list(app, list, list_index, &location)){ + Buffer_Summary buffer = {0}; + if (get_jump_buffer(app, &buffer, &location)){ + View_Summary target_view = get_active_view(app, AccessAll); + if (target_view.view_id == view.view_id){ + change_active_panel(app); + target_view = get_active_view(app, AccessAll); + } + switch_to_existing_view(app, &target_view, &buffer); + jump_to_location(app, &target_view, &buffer, location); + } + + int32_t updated_line = get_line_from_list(list, list_index); + view_set_cursor(app, &view, seek_line_char(updated_line, 1), true); + } + } + } +} + +CUSTOM_COMMAND_SIG(goto_prev_jump){ + General_Memory *general = &global_general; + Partition *part = &global_part; + + View_Summary view = get_view_for_locked_jump_buffer(app); + if (view.exists){ + Marker_List *list = get_or_make_list_for_buffer(app, part, general, view.buffer_id); + int32_t list_index = get_index_nearest_from_list(list, view.cursor.line); + --list_index; + + if (list_index >= 0 && list_index < list->jump_count){ + ID_Pos_Jump_Location location = {0}; + if (get_jump_from_list(app, list, list_index, &location)){ + Buffer_Summary buffer = {0}; + if (get_jump_buffer(app, &buffer, &location)){ + View_Summary target_view = get_active_view(app, AccessAll); + if (target_view.view_id == view.view_id){ + change_active_panel(app); + target_view = get_active_view(app, AccessAll); + } + switch_to_existing_view(app, &target_view, &buffer); + jump_to_location(app, &target_view, &buffer, location); + } + + int32_t updated_line = get_line_from_list(list, list_index); + view_set_cursor(app, &view, seek_line_char(updated_line, 1), true); + } + } + } +} + +CUSTOM_COMMAND_SIG(goto_first_jump){ + General_Memory *general = &global_general; + Partition *part = &global_part; + + View_Summary view = get_view_for_locked_jump_buffer(app); + if (view.exists){ + Marker_List *list = get_or_make_list_for_buffer(app, part, general, view.buffer_id); + int32_t list_index = 0; + + ID_Pos_Jump_Location location = {0}; + if (get_jump_from_list(app, list, list_index, &location)){ + Buffer_Summary buffer = {0}; + if (get_jump_buffer(app, &buffer, &location)){ + View_Summary target_view = get_active_view(app, AccessAll); + if (target_view.view_id == view.view_id){ + change_active_panel(app); + target_view = get_active_view(app, AccessAll); + } + switch_to_existing_view(app, &target_view, &buffer); + jump_to_location(app, &target_view, &buffer, location); + } + + int32_t updated_line = get_line_from_list(list, list_index); + view_set_cursor(app, &view, seek_line_char(updated_line, 1), true); + } + } +} + +// +// Insert Newline or Tigger Jump on Read Only Buffer +// + +CUSTOM_COMMAND_SIG(newline_or_goto_position){ + View_Summary view = get_active_view(app, AccessProtected); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); + + if (buffer.lock_flags & AccessProtected){ + goto_jump_at_cursor(app); + lock_jump_buffer(buffer); + } + else{ + write_character(app); + } +} + +CUSTOM_COMMAND_SIG(newline_or_goto_position_same_panel){ + View_Summary view = get_active_view(app, AccessProtected); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); + + if (buffer.lock_flags & AccessProtected){ + goto_jump_at_cursor_same_panel(app); + lock_jump_buffer(buffer); + } + else{ + write_character(app); + } +} + + +#define goto_next_jump_no_skips goto_next_jump +#define goto_prev_jump_no_skips goto_prev_jump +#define seek_error seek_jump +#define goto_next_error goto_next_jump +#define goto_prev_error goto_prev_jump +#define goto_next_error_no_skips goto_next_jump_no_skips +#define goto_first_error goto_first_jump + +#endif + +// BOTTOM +