From a5a07c16f88563b8762d1bd5b0b0b358fadfc9ec Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sun, 20 Oct 2019 19:02:58 -0700 Subject: [PATCH] Setup for the async --- 4ed.cpp | 30 - 4ed_api_implementation.cpp | 3 + 4ed_coroutine.cpp | 3 +- 4ed_system_api.cpp | 10 + custom/4coder_async_tasks.cpp | 53 + custom/4coder_async_tasks.h | 17 + custom/4coder_base_types.cpp | 3 +- custom/4coder_base_types.h | 8 + custom/4coder_config.cpp | 3172 +++++++++-------- custom/4coder_default_bindings.cpp | 1 + custom/4coder_default_framework.cpp | 1 + custom/4coder_default_framework_variables.cpp | 1 + custom/4coder_default_hooks.cpp | 31 +- custom/4coder_default_include.cpp | 2 + custom/4coder_profile_inspect.cpp | 2 - custom/4coder_types.h | 9 +- custom/generated/command_metadata.h | 422 +-- custom/generated/system_api.cpp | 4 + custom/generated/system_api.h | 10 + custom/generated/system_api_master_list.h | 2 + platform_win32/win32_4ed.cpp | 25 +- ship_files/release-config.4coder | 5 +- 22 files changed, 1979 insertions(+), 1835 deletions(-) create mode 100644 custom/4coder_async_tasks.cpp create mode 100644 custom/4coder_async_tasks.h diff --git a/4ed.cpp b/4ed.cpp index 650cc138..d52c7a56 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -775,36 +775,6 @@ App_Step_Sig(app_step){ } } -#if 0 - // NOTE(allen): apply pending smooth deltas - { - Delta_Rule_Function *delta_rule = models->delta_rule; - for (Panel *panel = layout_get_first_open_panel(layout); - panel != 0; - panel = layout_get_next_open_panel(layout, panel)){ - View *view = panel->view; - - View_ID view_id = view_get_id(&models->live_set, view); - b32 new_target = (b32)view->new_scroll_target; - - File_Edit_Positions edit_pos = view_get_edit_pos(view); - Vec2_f32 pending = view_buffer_point_difference(models, view, - edit_pos.scroll.target, edit_pos.scroll.position); - if (!near_zero(pending, 0.5f)){ - Vec2_f32 partial = scroll_rule(pending, view_id, new_target, animation_dt); - edit_pos.scroll.position = view_move_buffer_point(models, view, - edit_pos.scroll.position, partial); - view_set_edit_pos(view, edit_pos); - models->animate_next_frame = true; - } - else{ - edit_pos.scroll.position = edit_pos.scroll.target; - view_set_edit_pos(view, edit_pos); - } - } - } -#endif - // NOTE(allen): hook for files reloaded { Working_Set *working_set = &models->working_set; diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 8a40d859..f82a0a7e 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -78,6 +78,9 @@ get_thread_context(Application_Links *app){ Models *models = (Models*)app->cmd_context; tctx = models->tctx; } + else if (app->current_thread != 0){ + tctx = (Thread_Context*)app->current_thread; + } else{ Coroutine *coroutine = (Coroutine*)app->current_coroutine; tctx = coroutine->tctx; diff --git a/4ed_coroutine.cpp b/4ed_coroutine.cpp index 105f5ccb..d14823a5 100644 --- a/4ed_coroutine.cpp +++ b/4ed_coroutine.cpp @@ -31,7 +31,8 @@ coroutine_main(void *ptr){ Coroutine *me = (Coroutine*)ptr; Thread_Context tctx_ = {}; - thread_ctx_init(&tctx_, get_base_allocator_system(), get_base_allocator_system()); + thread_ctx_init(&tctx_, ThreadKind_MainCoroutine, + get_base_allocator_system(), get_base_allocator_system()); me->tctx = &tctx_; // NOTE(allen): Init handshake diff --git a/4ed_system_api.cpp b/4ed_system_api.cpp index 8674c435..ce70b9f5 100644 --- a/4ed_system_api.cpp +++ b/4ed_system_api.cpp @@ -177,6 +177,16 @@ define_api(Arena *arena){ API_Call *call = api_call(arena, api, "thread_get_id", "i32"); } + { + API_Call *call = api_call(arena, api, "acquire_global_frame_mutex", "void"); + api_param(arena, call, "Thread_Context*", "tctx"); + } + + { + API_Call *call = api_call(arena, api, "release_global_frame_mutex", "void"); + api_param(arena, call, "Thread_Context*", "tctx"); + } + { API_Call *call = api_call(arena, api, "mutex_make", "System_Mutex"); } diff --git a/custom/4coder_async_tasks.cpp b/custom/4coder_async_tasks.cpp new file mode 100644 index 00000000..9ae53ece --- /dev/null +++ b/custom/4coder_async_tasks.cpp @@ -0,0 +1,53 @@ +/* + * 4coder_async_tasks.cpp - Implementation of the custom layer asynchronous task system. + */ + +// TOP + +Application_Links *dummy_async_app = 0; + +function void +async_task_handler_init(Application_Links *app){ + //NotImplemented; + dummy_async_app = app; +} + +function Async_Task +async_task_no_dep(Async_Task_Function_Type *func, Data data){ + //NotImplemented; + func(dummy_async_app, data); + return(0); +} + +function Async_Task +async_task_single_dep(Async_Task_Function_Type *func, Data data, Async_Task dependency){ + NotImplemented; +} + +function b32 +async_task_is_pending(Async_Task task){ + NotImplemented; +} + +function b32 +async_task_is_running(Async_Task task){ + NotImplemented; +} + +function b32 +async_task_is_running_or_pending(Async_Task task){ + NotImplemented; +} + +function void +async_task_cancel(Async_Task task){ + NotImplemented; +} + +function void +async_task_join(Async_Task task){ + NotImplemented; +} + +// BOTTOM + diff --git a/custom/4coder_async_tasks.h b/custom/4coder_async_tasks.h new file mode 100644 index 00000000..8dae24f8 --- /dev/null +++ b/custom/4coder_async_tasks.h @@ -0,0 +1,17 @@ +/* + * 4coder_async_tasks.cpp - Types for the custom layer asynchronous task system. + */ + +// TOP + +#if !defined(FCODER_ASYNC_TASKS_H) +#define FCODER_ASYNC_TASKS_H + +typedef void Async_Task_Function_Type(Application_Links *app, Data data); + +typedef u64 Async_Task; + +#endif + +// BOTTOM + diff --git a/custom/4coder_base_types.cpp b/custom/4coder_base_types.cpp index 989e7f3b..b320c7c5 100644 --- a/custom/4coder_base_types.cpp +++ b/custom/4coder_base_types.cpp @@ -2834,9 +2834,10 @@ end_temp(Temp_Memory temp){ //////////////////////////////// internal void -thread_ctx_init(Thread_Context *tctx, Base_Allocator *allocator, +thread_ctx_init(Thread_Context *tctx, Thread_Kind kind, Base_Allocator *allocator, Base_Allocator *prof_allocator){ block_zero_struct(tctx); + tctx->kind = kind; tctx->allocator = allocator; tctx->node_arena = make_arena(allocator, KB(4), 8); diff --git a/custom/4coder_base_types.h b/custom/4coder_base_types.h index efeb62b2..6b3ae3af 100644 --- a/custom/4coder_base_types.h +++ b/custom/4coder_base_types.h @@ -1168,7 +1168,15 @@ struct Profile_Global_List{ //////////////////////////////// +typedef i32 Thread_Kind; +enum{ + ThreadKind_Main, + ThreadKind_MainCoroutine, + ThreadKind_AsyncTasks, +}; + struct Thread_Context{ + Thread_Kind kind; Base_Allocator *allocator; Arena node_arena; Arena_Node *free_arenas; diff --git a/custom/4coder_config.cpp b/custom/4coder_config.cpp index 5efb988b..c3cb6c99 100644 --- a/custom/4coder_config.cpp +++ b/custom/4coder_config.cpp @@ -1,1578 +1,1594 @@ -/* -4coder_config.cpp - Parsing *.4coder files. -*/ - -// TOP - -function String_Const_u8_Array -parse_extension_line_to_extension_list(Arena *arena, String_Const_u8 str){ - i32 count = 0; - for (umem i = 0; i < str.size; i += 1){ - if (str.str[i] == '.'){ - count += 1; - } - } - - String_Const_u8_Array array = {}; - array.count = count; - array.strings = push_array(arena, String_Const_u8, count); - - push_align(arena, 1); - str = string_skip(str, string_find_first(str, '.') + 1); - for (i32 i = 0; i < count; i += 1){ - umem next_period = string_find_first(str, '.'); - String_Const_u8 extension = string_prefix(str, next_period); - str = string_skip(str, next_period + 1); - array.strings[i] = push_string_copy(arena, extension); - } - push_align(arena, 8); - - return(array); -} - -//////////////////////////////// - -function Error_Location -get_error_location(u8 *base, u8 *pos){ - Error_Location location = {}; - location.line_number = 1; - location.column_number = 1; - for (u8 *ptr = base; - ptr < pos; - ptr += 1){ - if (*ptr == '\n'){ - location.line_number += 1; - location.column_number = 1; - } - else{ - location.column_number += 1; - } - } - return(location); -} - -function String_Const_u8 -config_stringize_errors(Arena *arena, Config *parsed){ - String_Const_u8 result = {}; - if (parsed->errors.first != 0){ - List_String_Const_u8 list = {}; - for (Config_Error *error = parsed->errors.first; - error != 0; - error = error->next){ - Error_Location location = get_error_location(parsed->data.str, error->pos); - string_list_pushf(arena, &list, "%.*s:%d:%d: %.*s\n", - string_expand(error->file_name), location.line_number, location.column_number, string_expand(error->text)); - } - result = string_list_flatten(arena, list); - } - return(result); -} - -//////////////////////////////// - -function void -config_parser__advance_to_next(Config_Parser *ctx){ - Token *t = ctx->token; - Token *e = ctx->end; - for (t += 1; - t < e && (t->kind == TokenBaseKind_Comment || - t->kind == TokenBaseKind_Whitespace); - t += 1); - ctx->token = t; -} - -function Config_Parser -make_config_parser(Arena *arena, String_Const_u8 file_name, String_Const_u8 data, Token_Array array){ - Config_Parser ctx = {}; - ctx.start = array.tokens; - ctx.token = ctx.start - 1; - ctx.end = ctx.start + array.count; - ctx.file_name = file_name; - ctx.data = data; - ctx.arena = arena; - config_parser__advance_to_next(&ctx); - return(ctx); -} - -function b32 -config_parser__recognize_base_token(Config_Parser *ctx, Token_Base_Kind kind){ - b32 result = false; - if (ctx->start <= ctx->token && ctx->token < ctx->end){ - result = (ctx->token->kind == kind); - } - else if (kind == TokenBaseKind_EOF){ - result = true; - } - return(result); -} - -function b32 -config_parser__recognize_token(Config_Parser *ctx, Token_Cpp_Kind kind){ - b32 result = false; - if (ctx->start <= ctx->token && ctx->token < ctx->end){ - result = (ctx->token->sub_kind == kind); - } - else if (kind == TokenCppKind_EOF){ - result = true; - } - return(result); -} - -function b32 -config_parser__recognize_boolean(Config_Parser *ctx){ - b32 result = false; - Token *token = ctx->token; - if (ctx->start <= ctx->token && ctx->token < ctx->end){ - result = (token->sub_kind == TokenCppKind_LiteralTrue || - token->sub_kind == TokenCppKind_LiteralFalse); - } - return(result); -} - -function String_Const_u8 -config_parser__get_lexeme(Config_Parser *ctx){ - String_Const_u8 lexeme = {}; - Token *token = ctx->token; - if (ctx->start <= token && token < ctx->end){ - lexeme = SCu8(ctx->data.str + token->pos, token->size); - } - return(lexeme); -} - -function Config_Integer -config_parser__get_int(Config_Parser *ctx){ - Config_Integer config_integer = {}; - String_Const_u8 str = config_parser__get_lexeme(ctx); - if (string_match(string_prefix(str, 2), string_u8_litexpr("0x"))){ - config_integer.is_signed = false; - config_integer.uinteger = (u32)(string_to_integer(string_skip(str, 2), 16)); - } - else{ - b32 is_negative = (string_get_character(str, 0) == '-'); - if (is_negative){ - str = string_skip(str, 1); - } - config_integer.is_signed = true; - config_integer.integer = (i32)(string_to_integer(str, 10)); - if (is_negative){ - config_integer.integer *= -1; - } - } - return(config_integer); -} - -function b32 -config_parser__get_boolean(Config_Parser *ctx){ - String_Const_u8 str = config_parser__get_lexeme(ctx); - return(string_match(str, string_u8_litexpr("true"))); -} - -function b32 -config_parser__recognize_text(Config_Parser *ctx, String_Const_u8 text){ - String_Const_u8 lexeme = config_parser__get_lexeme(ctx); - return(lexeme.str != 0 && string_match(lexeme, text)); -} - -function b32 -config_parser__match_token(Config_Parser *ctx, Token_Cpp_Kind kind){ - b32 result = config_parser__recognize_token(ctx, kind); - if (result){ - config_parser__advance_to_next(ctx); - } - return(result); -} - -function b32 -config_parser__match_text(Config_Parser *ctx, String_Const_u8 text){ - b32 result = config_parser__recognize_text(ctx, text); - if (result){ - config_parser__advance_to_next(ctx); - } - return(result); -} - -#define config_parser__match_text_lit(c,s) config_parser__match_text((c), string_u8_litexpr(s)) - -function Config *config_parser__config (Config_Parser *ctx); -function i32 *config_parser__version (Config_Parser *ctx); -function Config_Assignment *config_parser__assignment(Config_Parser *ctx); -function Config_LValue *config_parser__lvalue (Config_Parser *ctx); -function Config_RValue *config_parser__rvalue (Config_Parser *ctx); -function Config_Compound *config_parser__compound (Config_Parser *ctx); -function Config_Compound_Element *config_parser__element (Config_Parser *ctx); - -function Config* -text_data_and_token_array_to_parse_data(Arena *arena, String_Const_u8 file_name, String_Const_u8 data, Token_Array array){ - Temp_Memory restore_point = begin_temp(arena); - Config_Parser ctx = make_config_parser(arena, file_name, data, array); - Config *config = config_parser__config(&ctx); - if (config == 0){ - end_temp(restore_point); - } - return(config); -} - -// TODO(allen): Move to string library -function Config_Error* -config_error_push(Arena *arena, Config_Error_List *list, String_Const_u8 file_name, u8 *pos, char *error_text){ - Config_Error *error = push_array(arena, Config_Error, 1); - zdll_push_back(list->first, list->last, error); - list->count += 1; - error->file_name = file_name; - error->pos = pos; - error->text = push_string_copy(arena, SCu8(error_text)); - return(error); -} - -function u8* -config_parser__get_pos(Config_Parser *ctx){ - return(ctx->data.str + ctx->token->pos); -} - -function void -config_parser__log_error_pos(Config_Parser *ctx, u8 *pos, char *error_text){ - config_error_push(ctx->arena, &ctx->errors, ctx->file_name, pos, error_text); -} - -function void -config_parser__log_error(Config_Parser *ctx, char *error_text){ - config_parser__log_error_pos(ctx, config_parser__get_pos(ctx), error_text); -} - -function Config* -config_parser__config(Config_Parser *ctx){ - i32 *version = config_parser__version(ctx); - - Config_Assignment *first = 0; - Config_Assignment *last = 0; - i32 count = 0; - for (;!config_parser__recognize_token(ctx, TokenCppKind_EOF);){ - Config_Assignment *assignment = config_parser__assignment(ctx); - if (assignment != 0){ - zdll_push_back(first, last, assignment); - count += 1; - } - } - - Config *config = push_array(ctx->arena, Config, 1); - block_zero_struct(config); - config->version = version; - config->first = first; - config->last = last; - config->count = count; - config->errors = ctx->errors; - config->file_name = ctx->file_name; - config->data = ctx->data; - return(config); -} - -function void -config_parser__recover_parse(Config_Parser *ctx){ - for (;;){ - if (config_parser__match_token(ctx, TokenCppKind_Semicolon)){ - break; - } - if (config_parser__recognize_token(ctx, TokenCppKind_EOF)){ - break; - } - config_parser__advance_to_next(ctx); - } -} - -function i32* -config_parser__version(Config_Parser *ctx){ - require(config_parser__match_text_lit(ctx, "version")); - - if (!config_parser__match_token(ctx, TokenCppKind_ParenOp)){ - config_parser__log_error(ctx, "expected token '(' for version specifier: 'version(#)'"); - config_parser__recover_parse(ctx); - return(0); - } - - if (!config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)){ - config_parser__log_error(ctx, "expected an integer constant for version specifier: 'version(#)'"); - config_parser__recover_parse(ctx); - return(0); - } - - Config_Integer value = config_parser__get_int(ctx); - config_parser__advance_to_next(ctx); - - if (!config_parser__match_token(ctx, TokenCppKind_ParenCl)){ - config_parser__log_error(ctx, "expected token ')' for version specifier: 'version(#)'"); - config_parser__recover_parse(ctx); - return(0); - } - - if (!config_parser__match_token(ctx, TokenCppKind_Semicolon)){ - config_parser__log_error(ctx, "expected token ';' for version specifier: 'version(#)'"); - config_parser__recover_parse(ctx); - return(0); - } - - i32 *ptr = push_array(ctx->arena, i32, 1); - *ptr = value.integer; - return(ptr); -} - -function Config_Assignment* -config_parser__assignment(Config_Parser *ctx){ - u8 *pos = config_parser__get_pos(ctx); - - Config_LValue *l = config_parser__lvalue(ctx); - if (l == 0){ - config_parser__log_error(ctx, "expected an l-value; l-value formats: 'identifier', 'identifier[#]'"); - config_parser__recover_parse(ctx); - return(0); - } - - if (!config_parser__match_token(ctx, TokenCppKind_Eq)){ - config_parser__log_error(ctx, "expected token '=' for assignment: 'l-value = r-value;'"); - config_parser__recover_parse(ctx); - return(0); - } - - Config_RValue *r = config_parser__rvalue(ctx); - if (r == 0){ - config_parser__log_error(ctx, "expected an r-value; r-value formats:\n" - "\tconstants (true, false, integers, hexadecimal integers, strings, characters)\n" - "\tany l-value that is set in the file\n" - "\tcompound: '{ compound-element, compound-element, compound-element ...}'\n" - "\ta compound-element is an r-value, and can have a layout specifier\n" - "\tcompound-element with layout specifier: .name = r-value, .integer = r-value"); - config_parser__recover_parse(ctx); - return(0); - } - - if (!config_parser__match_token(ctx, TokenCppKind_Semicolon)){ - config_parser__log_error(ctx, "expected token ';' for assignment: 'l-value = r-value;'"); - config_parser__recover_parse(ctx); - return(0); - } - - Config_Assignment *assignment = push_array_zero(ctx->arena, Config_Assignment, 1); - assignment->pos = pos; - assignment->l = l; - assignment->r = r; - return(assignment); -} - -function Config_LValue* -config_parser__lvalue(Config_Parser *ctx){ - require(config_parser__recognize_token(ctx, TokenCppKind_Identifier)); - String_Const_u8 identifier = config_parser__get_lexeme(ctx); - config_parser__advance_to_next(ctx); - - i32 index = 0; - if (config_parser__match_token(ctx, TokenCppKind_BrackOp)){ - require(config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)); - Config_Integer value = config_parser__get_int(ctx); - index = value.integer; - config_parser__advance_to_next(ctx); - require(config_parser__match_token(ctx, TokenCppKind_BrackCl)); - } - - Config_LValue *lvalue = push_array_zero(ctx->arena, Config_LValue, 1); - lvalue->identifier = identifier; - lvalue->index = index; - return(lvalue); -} - -function Config_RValue* -config_parser__rvalue(Config_Parser *ctx){ - Config_RValue *rvalue = 0; - if (config_parser__recognize_token(ctx, TokenCppKind_Identifier)){ - Config_LValue *l = config_parser__lvalue(ctx); - require(l != 0); - rvalue = push_array_zero(ctx->arena, Config_RValue, 1); - rvalue->type = ConfigRValueType_LValue; - rvalue->lvalue = l; - } - else if (config_parser__recognize_token(ctx, TokenCppKind_BraceOp)){ - config_parser__advance_to_next(ctx); - Config_Compound *compound = config_parser__compound(ctx); - require(compound != 0); - rvalue = push_array_zero(ctx->arena, Config_RValue, 1); - rvalue->type = ConfigRValueType_Compound; - rvalue->compound = compound; - } - else if (config_parser__recognize_boolean(ctx)){ - b32 b = config_parser__get_boolean(ctx); - config_parser__advance_to_next(ctx); - rvalue = push_array_zero(ctx->arena, Config_RValue, 1); - rvalue->type = ConfigRValueType_Boolean; - rvalue->boolean = b; - } - else if (config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)){ - Config_Integer value = config_parser__get_int(ctx); - config_parser__advance_to_next(ctx); - rvalue = push_array_zero(ctx->arena, Config_RValue, 1); - rvalue->type = ConfigRValueType_Integer; - if (value.is_signed){ - rvalue->integer = value.integer; - } - else{ - rvalue->uinteger = value.uinteger; - } - } - else if (config_parser__recognize_token(ctx, TokenCppKind_LiteralString)){ - String_Const_u8 s = config_parser__get_lexeme(ctx); - config_parser__advance_to_next(ctx); - s = string_chop(string_skip(s, 1), 1); - String_Const_u8 interpreted = string_interpret_escapes(ctx->arena, s); - rvalue = push_array_zero(ctx->arena, Config_RValue, 1); - rvalue->type = ConfigRValueType_String; - rvalue->string = interpreted; - } - else if (config_parser__recognize_token(ctx, TokenCppKind_LiteralCharacter)){ - String_Const_u8 s = config_parser__get_lexeme(ctx); - config_parser__advance_to_next(ctx); - s = string_chop(string_skip(s, 1), 1); - String_Const_u8 interpreted = string_interpret_escapes(ctx->arena, s); - rvalue = push_array_zero(ctx->arena, Config_RValue, 1); - rvalue->type = ConfigRValueType_Character; - rvalue->character = string_get_character(interpreted, 0); - } - return(rvalue); -} - -function void -config_parser__compound__check(Config_Parser *ctx, Config_Compound *compound){ - b32 implicit_index_allowed = true; - for (Config_Compound_Element *node = compound->first; - node != 0; - node = node->next){ - if (node->l.type != ConfigLayoutType_Unset){ - implicit_index_allowed = false; - } - else if (!implicit_index_allowed){ - config_parser__log_error_pos(ctx, node->l.pos, - "encountered unlabeled member after one or more labeled members"); - } - } -} - -function Config_Compound* -config_parser__compound(Config_Parser *ctx){ - Config_Compound_Element *first = 0; - Config_Compound_Element *last = 0; - i32 count = 0; - - Config_Compound_Element *element = config_parser__element(ctx); - require(element != 0); - zdll_push_back(first, last, element); - count += 1; - - for (;config_parser__match_token(ctx, TokenCppKind_Comma);){ - if (config_parser__recognize_token(ctx, TokenCppKind_BraceCl)){ - break; - } - element = config_parser__element(ctx); - require(element != 0); - zdll_push_back(first, last, element); - count += 1; - } - - require(config_parser__match_token(ctx, TokenCppKind_BraceCl)); - - Config_Compound *compound = push_array(ctx->arena, Config_Compound, 1); - block_zero_struct(compound); - compound->first = first; - compound->last = last; - compound->count = count; - config_parser__compound__check(ctx, compound); - return(compound); -} - -function Config_Compound_Element* -config_parser__element(Config_Parser *ctx){ - Config_Layout layout = {}; - layout.pos = config_parser__get_pos(ctx); - if (config_parser__match_token(ctx, TokenCppKind_Dot)){ - if (config_parser__recognize_token(ctx, TokenCppKind_Identifier)){ - layout.type = ConfigLayoutType_Identifier; - layout.identifier = config_parser__get_lexeme(ctx); - config_parser__advance_to_next(ctx); - } - else if (config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)){ - layout.type = ConfigLayoutType_Integer; - Config_Integer value = config_parser__get_int(ctx); - layout.integer = value.integer; - config_parser__advance_to_next(ctx); - } - else{ - return(0); - } - require(config_parser__match_token(ctx, TokenCppKind_Eq)); - } - Config_RValue *rvalue = config_parser__rvalue(ctx); - require(rvalue != 0); - Config_Compound_Element *element = push_array(ctx->arena, Config_Compound_Element, 1); - block_zero_struct(element); - element->l = layout; - element->r = rvalue; - return(element); -} - -//////////////////////////////// - -function Config_Error* -config_add_error(Arena *arena, Config *config, u8 *pos, char *error_text){ - return(config_error_push(arena, &config->errors, config->file_name, pos, error_text)); -} - -//////////////////////////////// - -function Config_Assignment* -config_lookup_assignment(Config *config, String_Const_u8 var_name, i32 subscript){ - Config_Assignment *assignment = 0; - for (assignment = config->first; - assignment != 0; - assignment = assignment->next){ - Config_LValue *l = assignment->l; - if (l != 0 && string_match(l->identifier, var_name) && l->index == subscript){ - break; - } - } - return(assignment); -} - -function Config_Get_Result -config_var(Config *config, String_Const_u8 var_name, i32 subscript); - -function Config_Get_Result -config_evaluate_rvalue(Config *config, Config_Assignment *assignment, Config_RValue *r){ - Config_Get_Result result = {}; - if (r != 0 && !assignment->visited){ - if (r->type == ConfigRValueType_LValue){ - assignment->visited = true; - Config_LValue *l = r->lvalue; - result = config_var(config, l->identifier, l->index); - assignment->visited = false; - } - else{ - result.success = true; - result.pos = assignment->pos; - result.type = r->type; - switch (r->type){ - case ConfigRValueType_Boolean: - { - result.boolean = r->boolean; - }break; - - case ConfigRValueType_Integer: - { - result.integer = r->integer; - }break; - - case ConfigRValueType_String: - { - result.string = r->string; - }break; - - case ConfigRValueType_Character: - { - result.character = r->character; - }break; - - case ConfigRValueType_Compound: - { - result.compound = r->compound; - }break; - } - } - } - return(result); -} - -function Config_Get_Result -config_var(Config *config, String_Const_u8 var_name, i32 subscript){ - Config_Get_Result result = {}; - Config_Assignment *assignment = config_lookup_assignment(config, var_name, subscript); - if (assignment != 0){ - result = config_evaluate_rvalue(config, assignment, assignment->r); - } - return(result); -} - -function Config_Get_Result -config_compound_member(Config *config, Config_Compound *compound, String_Const_u8 var_name, i32 index){ - Config_Get_Result result = {}; - i32 implicit_index = 0; - b32 implicit_index_is_valid = true; - for (Config_Compound_Element *element = compound->first; - element != 0; - element = element->next, implicit_index += 1){ - b32 element_matches_query = false; - switch (element->l.type){ - case ConfigLayoutType_Unset: - { - if (implicit_index_is_valid && index == implicit_index){ - element_matches_query = true; - } - }break; - - case ConfigLayoutType_Identifier: - { - implicit_index_is_valid = false; - if (string_match(element->l.identifier, var_name)){ - element_matches_query = true; - } - }break; - - case ConfigLayoutType_Integer: - { - implicit_index_is_valid = false; - if (element->l.integer == index){ - element_matches_query = true; - } - }break; - } - if (element_matches_query){ - Config_Assignment dummy_assignment = {}; - dummy_assignment.pos = element->l.pos; - result = config_evaluate_rvalue(config, &dummy_assignment, element->r); - break; - } - } - return(result); -} - -function Config_Iteration_Step_Result -typed_array_iteration_step(Config *parsed, Config_Compound *compound, Config_RValue_Type type, i32 index); - -function i32 -typed_array_get_count(Config *parsed, Config_Compound *compound, Config_RValue_Type type); - -function Config_Get_Result_List -typed_array_reference_list(Arena *arena, Config *parsed, Config_Compound *compound, Config_RValue_Type type); - -#define config_fixed_string_var(c,v,s,o,a) config_placed_string_var((c),(v),(s),(o),(a),sizeof(a)) - -//////////////////////////////// - -function b32 -config_has_var(Config *config, String_Const_u8 var_name, i32 subscript){ - Config_Get_Result result = config_var(config, var_name, subscript); - return(result.success && result.type == ConfigRValueType_NoType); -} - -function b32 -config_has_var(Config *config, char *var_name, i32 subscript){ - return(config_has_var(config, SCu8(var_name), subscript)); -} - -function b32 -config_bool_var(Config *config, String_Const_u8 var_name, i32 subscript, b32* var_out){ - Config_Get_Result result = config_var(config, var_name, subscript); - b32 success = (result.success && result.type == ConfigRValueType_Boolean); - if (success){ - *var_out = result.boolean; - } - return(success); -} -function b32 -config_bool_var(Config *config, String_Const_u8 var_name, i32 subscript, b8 *var_out){ - b32 temp = false; - b32 success = config_bool_var(config, var_name, subscript, &temp); - if (success){ - *var_out = (temp != false); - } - return(success); -} -function b32 -config_bool_var(Config *config, char *var_name, i32 subscript, b32* var_out){ - return(config_bool_var(config, SCu8(var_name), subscript, var_out)); -} -function b32 -config_bool_var(Config *config, char* var_name, i32 subscript, b8 *var_out){ - b32 temp = false; - b32 success = config_bool_var(config, SCu8(var_name), subscript, &temp); - if (success){ - *var_out = (temp != false); - } - return(success); -} - -function b32 -config_int_var(Config *config, String_Const_u8 var_name, i32 subscript, i32* var_out){ - Config_Get_Result result = config_var(config, var_name, subscript); - b32 success = result.success && result.type == ConfigRValueType_Integer; - if (success){ - *var_out = result.integer; - } - return(success); -} - -function b32 -config_int_var(Config *config, char *var_name, i32 subscript, i32* var_out){ - return(config_int_var(config, SCu8(var_name), subscript, var_out)); -} - -function b32 -config_uint_var(Config *config, String_Const_u8 var_name, i32 subscript, u32* var_out){ - Config_Get_Result result = config_var(config, var_name, subscript); - b32 success = result.success && result.type == ConfigRValueType_Integer; - if (success){ - *var_out = result.uinteger; - } - return(success); -} - -function b32 -config_uint_var(Config *config, char *var_name, i32 subscript, u32* var_out){ - return(config_uint_var(config, SCu8(var_name), subscript, var_out)); -} - -function b32 -config_string_var(Config *config, String_Const_u8 var_name, i32 subscript, String_Const_u8* var_out){ - Config_Get_Result result = config_var(config, var_name, subscript); - b32 success = result.success && result.type == ConfigRValueType_String; - if (success){ - *var_out = result.string; - } - return(success); -} - -function b32 -config_string_var(Config *config, char *var_name, i32 subscript, String_Const_u8* var_out){ - return(config_string_var(config, SCu8(var_name), subscript, var_out)); -} - -function b32 -config_placed_string_var(Config *config, String_Const_u8 var_name, i32 subscript, String_Const_u8* var_out, u8 *space, umem space_size){ - Config_Get_Result result = config_var(config, var_name, subscript); - b32 success = (result.success && result.type == ConfigRValueType_String); - if (success){ - umem size = result.string.size; - size = clamp_top(size, space_size); - block_copy(space, result.string.str, size); - *var_out = SCu8(space, size); - } - return(success); -} - -function b32 -config_placed_string_var(Config *config, char *var_name, i32 subscript, String_Const_u8* var_out, u8 *space, umem space_size){ - return(config_placed_string_var(config, SCu8(var_name), subscript, var_out, space, space_size)); -} - -function b32 -config_char_var(Config *config, String_Const_u8 var_name, i32 subscript, char* var_out){ - Config_Get_Result result = config_var(config, var_name, subscript); - b32 success = result.success && result.type == ConfigRValueType_Character; - if (success){ - *var_out = result.character; - } - return(success); -} - -function b32 -config_char_var(Config *config, char *var_name, i32 subscript, char* var_out){ - return(config_char_var(config, SCu8(var_name), subscript, var_out)); -} - -function b32 -config_compound_var(Config *config, String_Const_u8 var_name, i32 subscript, Config_Compound** var_out){ - Config_Get_Result result = config_var(config, var_name, subscript); - b32 success = result.success && result.type == ConfigRValueType_Compound; - if (success){ - *var_out = result.compound; - } - return(success); -} - -function b32 -config_compound_var(Config *config, char *var_name, i32 subscript, Config_Compound** var_out){ - return(config_compound_var(config, SCu8(var_name), subscript, var_out)); -} - -function b32 -config_compound_has_member(Config *config, Config_Compound *compound, - String_Const_u8 var_name, i32 index){ - Config_Get_Result result = config_compound_member(config, compound, var_name, index); - b32 success = result.success && result.type == ConfigRValueType_NoType; - return(success); -} - -function b32 -config_compound_has_member(Config *config, Config_Compound *compound, - char *var_name, i32 index){ - return(config_compound_has_member(config, compound, SCu8(var_name), index)); -} - -function b32 -config_compound_bool_member(Config *config, Config_Compound *compound, - String_Const_u8 var_name, i32 index, b32* var_out){ - Config_Get_Result result = config_compound_member(config, compound, var_name, index); - b32 success = result.success && result.type == ConfigRValueType_Boolean; - if (success){ - *var_out = result.boolean; - } - return(success); -} - -function b32 -config_compound_bool_member(Config *config, Config_Compound *compound, - char *var_name, i32 index, b32* var_out){ - return(config_compound_bool_member(config, compound, SCu8(var_name), index, var_out)); -} - -function b32 -config_compound_int_member(Config *config, Config_Compound *compound, - String_Const_u8 var_name, i32 index, i32* var_out){ - Config_Get_Result result = config_compound_member(config, compound, var_name, index); - b32 success = result.success && result.type == ConfigRValueType_Integer; - if (success){ - *var_out = result.integer; - } - return(success); -} - -function b32 -config_compound_int_member(Config *config, Config_Compound *compound, - char *var_name, i32 index, i32* var_out){ - return(config_compound_int_member(config, compound, SCu8(var_name), index, var_out)); -} - -function b32 -config_compound_uint_member(Config *config, Config_Compound *compound, - String_Const_u8 var_name, i32 index, u32* var_out){ - Config_Get_Result result = config_compound_member(config, compound, var_name, index); - b32 success = result.success && result.type == ConfigRValueType_Integer; - if (success){ - *var_out = result.uinteger; - } - return(success); -} - -function b32 -config_compound_uint_member(Config *config, Config_Compound *compound, - char *var_name, i32 index, u32* var_out){ - return(config_compound_uint_member(config, compound, SCu8(var_name), index, var_out)); -} - -function b32 -config_compound_string_member(Config *config, Config_Compound *compound, - String_Const_u8 var_name, i32 index, String_Const_u8* var_out){ - Config_Get_Result result = config_compound_member(config, compound, var_name, index); - b32 success = (result.success && result.type == ConfigRValueType_String); - if (success){ - *var_out = result.string; - } - return(success); -} - -function b32 -config_compound_string_member(Config *config, Config_Compound *compound, - char *var_name, i32 index, String_Const_u8* var_out){ - return(config_compound_string_member(config, compound, SCu8(var_name), index, var_out)); -} - -function b32 -config_compound_placed_string_member(Config *config, Config_Compound *compound, - String_Const_u8 var_name, i32 index, String_Const_u8* var_out, u8 *space, umem space_size){ - Config_Get_Result result = config_compound_member(config, compound, var_name, index); - b32 success = (result.success && result.type == ConfigRValueType_String); - if (success){ - umem size = result.string.size; - size = clamp_top(size, space_size); - block_copy(space, result.string.str, size); - *var_out = SCu8(space, size); - } - return(success); -} - -function b32 -config_compound_placed_string_member(Config *config, Config_Compound *compound, - char *var_name, i32 index, String_Const_u8* var_out, u8 *space, umem space_size){ - return(config_compound_placed_string_member(config, compound, SCu8(var_name), index, var_out, space, space_size)); -} - -function b32 -config_compound_char_member(Config *config, Config_Compound *compound, - String_Const_u8 var_name, i32 index, char* var_out){ - Config_Get_Result result = config_compound_member(config, compound, var_name, index); - b32 success = result.success && result.type == ConfigRValueType_Character; - if (success){ - *var_out = result.character; - } - return(success); -} - -function b32 -config_compound_char_member(Config *config, Config_Compound *compound, - char *var_name, i32 index, char* var_out){ - return(config_compound_char_member(config, compound, SCu8(var_name), index, var_out)); -} - -function b32 -config_compound_compound_member(Config *config, Config_Compound *compound, - String_Const_u8 var_name, i32 index, Config_Compound** var_out){ - Config_Get_Result result = config_compound_member(config, compound, var_name, index); - b32 success = result.success && result.type == ConfigRValueType_Compound; - if (success){ - *var_out = result.compound; - } - return(success); -} - -function b32 -config_compound_compound_member(Config *config, Config_Compound *compound, - char *var_name, i32 index, Config_Compound** var_out){ - return(config_compound_compound_member(config, compound, SCu8(var_name), index, var_out)); -} - -function Iteration_Step_Result -typed_has_array_iteration_step(Config *config, Config_Compound *compound, i32 index){ - Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_NoType, index); - return(result.step); -} - -function Iteration_Step_Result -typed_bool_array_iteration_step(Config *config, Config_Compound *compound, i32 index, b32* var_out){ - Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Boolean, index); - b32 success = (result.step == Iteration_Good); - if (success){ - *var_out = result.get.boolean; - } - return(result.step); -} - -function Iteration_Step_Result -typed_int_array_iteration_step(Config *config, Config_Compound *compound, i32 index, i32* var_out){ - Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Integer, index); - b32 success = (result.step == Iteration_Good); - if (success){ - *var_out = result.get.integer; - } - return(result.step); -} - -function Iteration_Step_Result -typed_uint_array_iteration_step(Config *config, Config_Compound *compound, i32 index, u32* var_out){ - Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Integer, index); - b32 success = (result.step == Iteration_Good); - if (success){ - *var_out = result.get.uinteger; - } - return(result.step); -} - -function Iteration_Step_Result -typed_string_array_iteration_step(Config *config, Config_Compound *compound, i32 index, String_Const_u8* var_out){ - Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_String, index); - b32 success = (result.step == Iteration_Good); - if (success){ - *var_out = result.get.string; - } - return(result.step); -} - -function Iteration_Step_Result -typed_placed_string_array_iteration_step(Config *config, Config_Compound *compound, i32 index, String_Const_u8* var_out, u8 *space, umem space_size){ - Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_String, index); - b32 success = (result.step == Iteration_Good); - if (success){ - umem size = result.get.string.size; - size = clamp_top(size, space_size); - block_copy(space, result.get.string.str, size); - *var_out = SCu8(space, size); - } - return(result.step); -} - -function Iteration_Step_Result -typed_char_array_iteration_step(Config *config, Config_Compound *compound, i32 index, char* var_out){ - Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Character, index); - b32 success = (result.step == Iteration_Good); - if (success){ - *var_out = result.get.character; - } - return(result.step); -} - -function Iteration_Step_Result -typed_compound_array_iteration_step(Config *config, Config_Compound *compound, i32 index, Config_Compound** var_out){ - Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Compound, index); - b32 success = (result.step == Iteration_Good); - if (success){ - *var_out = result.get.compound; - } - return(result.step); -} - -function i32 -typed_bool_array_get_count(Config *config, Config_Compound *compound){ - i32 count = typed_array_get_count(config, compound, ConfigRValueType_Boolean); - return(count); -} - -function i32 -typed_int_array_get_count(Config *config, Config_Compound *compound){ - i32 count = typed_array_get_count(config, compound, ConfigRValueType_Integer); - return(count); -} - -function i32 -typed_float_array_get_count(Config *config, Config_Compound *compound){ - i32 count = typed_array_get_count(config, compound, ConfigRValueType_Float); - return(count); -} - -function i32 -typed_string_array_get_count(Config *config, Config_Compound *compound){ - i32 count = typed_array_get_count(config, compound, ConfigRValueType_String); - return(count); -} - -function i32 -typed_character_array_get_count(Config *config, Config_Compound *compound){ - i32 count = typed_array_get_count(config, compound, ConfigRValueType_Character); - return(count); -} - -function i32 -typed_compound_array_get_count(Config *config, Config_Compound *compound){ - i32 count = typed_array_get_count(config, compound, ConfigRValueType_Compound); - return(count); -} - -function i32 -typed_no_type_array_get_count(Config *config, Config_Compound *compound){ - i32 count = typed_array_get_count(config, compound, ConfigRValueType_NoType); - return(count); -} - -function Config_Get_Result_List -typed_bool_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ - Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Boolean); - return(list); -} - -function Config_Get_Result_List -typed_int_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ - Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Integer); - return(list); -} - -function Config_Get_Result_List -typed_float_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ - Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Float); - return(list); -} - -function Config_Get_Result_List -typed_string_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ - Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_String); - return(list); -} - -function Config_Get_Result_List -typed_character_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ - Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Character); - return(list); -} - -function Config_Get_Result_List -typed_compound_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ - Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Compound); - return(list); -} - -function Config_Get_Result_List -typed_no_type_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ - Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_NoType); - return(list); -} - -//////////////////////////////// - -function Config_Iteration_Step_Result -typed_array_iteration_step(Config *parsed, Config_Compound *compound, Config_RValue_Type type, i32 index){ - Config_Iteration_Step_Result result = {}; - result.step = Iteration_Quit; - Config_Get_Result get_result = config_compound_member(parsed, compound, string_u8_litexpr("~"), index); - if (get_result.success){ - if (get_result.type == type || type == ConfigRValueType_NoType){ - result.step = Iteration_Good; - result.get = get_result; - } - else{ - result.step = Iteration_Skip; - } - } - return(result); -} - -function i32 -typed_array_get_count(Config *parsed, Config_Compound *compound, Config_RValue_Type type){ - i32 count = 0; - for (i32 i = 0;; ++i){ - Config_Iteration_Step_Result result = typed_array_iteration_step(parsed, compound, type, i); - if (result.step == Iteration_Skip){ - continue; - } - else if (result.step == Iteration_Quit){ - break; - } - count += 1; - } - return(count); -} - -function Config_Get_Result_List -typed_array_reference_list(Arena *arena, Config *parsed, Config_Compound *compound, Config_RValue_Type type){ - Config_Get_Result_List list = {}; - for (i32 i = 0;; ++i){ - Config_Iteration_Step_Result result = typed_array_iteration_step(parsed, compound, type, i); - if (result.step == Iteration_Skip){ - continue; - } - else if (result.step == Iteration_Quit){ - break; - } - Config_Get_Result_Node *node = push_array(arena, Config_Get_Result_Node, 1); - node->result = result.get; - zdll_push_back(list.first, list.last, node); - list.count += 1; - } - return(list); -} - -//////////////////////////////// - -function void -change_mode(Application_Links *app, String_Const_u8 mode){ - fcoder_mode = FCoderMode_Original; - if (string_match(mode, string_u8_litexpr("4coder"))){ - fcoder_mode = FCoderMode_Original; - } - else if (string_match(mode, string_u8_litexpr("notepad-like"))){ - begin_notepad_mode(app); - } - else{ - print_message(app, string_u8_litexpr("Unknown mode.\n")); - } -} - -//////////////////////////////// - -function Token_Array -token_array_from_text(Arena *arena, String_Const_u8 data){ - Token_List list = lex_full_input_cpp(arena, data); - return(token_array_from_list(arena, &list)); -} - -function Config* -text_data_to_parsed_data(Arena *arena, String_Const_u8 file_name, String_Const_u8 data){ - Config *parsed = 0; - Temp_Memory restore_point = begin_temp(arena); - Token_Array array = token_array_from_text(arena, data); - if (array.tokens != 0){ - parsed = text_data_and_token_array_to_parse_data(arena, file_name, data, array); - if (parsed == 0){ - end_temp(restore_point); - } - } - return(parsed); -} - -//////////////////////////////// - -function void -config_init_default(Config_Data *config){ - config->user_name = SCu8(config->user_name_space, (umem)0); - - block_zero_struct(&config->code_exts); - - config->mode = SCu8(config->mode_space, (umem)0); - - config->use_scroll_bars = false; - config->use_file_bars = true; - config->hide_file_bar_in_ui = true; - config->use_error_highlight = true; - config->use_jump_highlight = true; - config->use_scope_highlight = true; - config->use_paren_helper = true; - config->use_comment_keyword = true; - config->lister_whole_word_backspace_when_modified = false; - config->show_line_number_margins = false; - - config->enable_virtual_whitespace = true; - config->enable_code_wrapping = true; - config->automatically_adjust_wrapping = true; - config->automatically_indent_text_on_save = true; - config->automatically_save_changes_on_build = true; - config->automatically_load_project = false; - - config->indent_with_tabs = false; - config->indent_width = 4; - - config->default_wrap_width = 672; - config->default_min_base_width = 550; - - config->default_theme_name = SCu8(config->default_theme_name_space, sizeof("4coder") - 1); - block_copy(config->default_theme_name.str, "4coder", config->default_theme_name.size); - config->highlight_line_at_cursor = true; - - config->default_font_name = SCu8(config->default_font_name_space, (umem)0); - config->default_font_size = 16; - config->default_font_hinting = false; - - config->default_compiler_bat = SCu8(config->default_compiler_bat_space, 2); - block_copy(config->default_compiler_bat.str, "cl", 2); - - config->default_flags_bat = SCu8(config->default_flags_bat_space, (umem)0); - - config->default_compiler_sh = SCu8(config->default_compiler_sh_space, 3); - block_copy(config->default_compiler_sh.str, "g++", 3); - - config->default_flags_sh = SCu8(config->default_flags_sh_space, (umem)0); - - config->lalt_lctrl_is_altgr = false; -} - -function Config* -config_parse__data(Arena *arena, String_Const_u8 file_name, String_Const_u8 data, Config_Data *config){ - config_init_default(config); - - b32 success = false; - - Config *parsed = text_data_to_parsed_data(arena, file_name, data); - if (parsed != 0){ - success = true; - - config_fixed_string_var(parsed, "user_name", 0, - &config->user_name, config->user_name_space); - - String_Const_u8 str = {}; - if (config_string_var(parsed, "treat_as_code", 0, &str)){ - config->code_exts = parse_extension_line_to_extension_list(arena, str); - } - - config_fixed_string_var(parsed, "mode", 0, - &config->mode, config->mode_space); - - config_bool_var(parsed, "use_scroll_bars", 0, &config->use_scroll_bars); - config_bool_var(parsed, "use_file_bars", 0, &config->use_file_bars); - config_bool_var(parsed, "hide_file_bar_in_ui", 0, &config->hide_file_bar_in_ui); - config_bool_var(parsed, "use_error_highlight", 0, &config->use_error_highlight); - config_bool_var(parsed, "use_jump_highlight", 0, &config->use_jump_highlight); - config_bool_var(parsed, "use_scope_highlight", 0, &config->use_scope_highlight); - config_bool_var(parsed, "use_paren_helper", 0, &config->use_paren_helper); - config_bool_var(parsed, "use_comment_keyword", 0, &config->use_comment_keyword); - config_bool_var(parsed, "lister_whole_word_backspace_when_modified", 0, &config->lister_whole_word_backspace_when_modified); - config_bool_var(parsed, "show_line_number_margins", 0, &config->show_line_number_margins); - - - config_bool_var(parsed, "enable_virtual_whitespace", 0, &config->enable_virtual_whitespace); - config_bool_var(parsed, "enable_code_wrapping", 0, &config->enable_code_wrapping); - config_bool_var(parsed, "automatically_adjust_wrapping", 0, &config->automatically_adjust_wrapping); - config_bool_var(parsed, "automatically_indent_text_on_save", 0, &config->automatically_indent_text_on_save); - config_bool_var(parsed, "automatically_save_changes_on_build", 0, &config->automatically_save_changes_on_build); - config_bool_var(parsed, "automatically_load_project", 0, &config->automatically_load_project); - - config_bool_var(parsed, "indent_with_tabs", 0, &config->indent_with_tabs); - config_int_var(parsed, "indent_width", 0, &config->indent_width); - - config_int_var(parsed, "default_wrap_width", 0, &config->default_wrap_width); - config_int_var(parsed, "default_min_base_width", 0, &config->default_min_base_width); - - config_fixed_string_var(parsed, "default_theme_name", 0, - &config->default_theme_name, config->default_theme_name_space); - config_bool_var(parsed, "highlight_line_at_cursor", 0, &config->highlight_line_at_cursor); - - config_fixed_string_var(parsed, "default_font_name", 0, - &config->default_font_name, config->default_font_name_space); - config_int_var(parsed, "default_font_size", 0, &config->default_font_size); - config_bool_var(parsed, "default_font_hinting", 0, &config->default_font_hinting); - - config_fixed_string_var(parsed, "default_compiler_bat", 0, - &config->default_compiler_bat, config->default_compiler_bat_space); - config_fixed_string_var(parsed, "default_flags_bat", 0, - &config->default_flags_bat, config->default_flags_bat_space); - config_fixed_string_var(parsed, "default_compiler_sh", 0, - &config->default_compiler_sh, config->default_compiler_sh_space); - config_fixed_string_var(parsed, "default_flags_sh", 0, - &config->default_flags_sh, config->default_flags_sh_space); - - config_bool_var(parsed, "lalt_lctrl_is_altgr", 0, &config->lalt_lctrl_is_altgr); - } - - if (!success){ - config_init_default(config); - } - - return(parsed); -} - -function Config* -config_parse__file_handle(Arena *arena, String_Const_u8 file_name, FILE *file, Config_Data *config){ - Config *parsed = 0; - Data data = dump_file_handle(arena, file); - if (data.data != 0){ - parsed = config_parse__data(arena, file_name, SCu8(data), config); - } - else{ - config_init_default(config); - } - return(parsed); -} - -function Config* -config_parse__file_name(Application_Links *app, Arena *arena, char *file_name, Config_Data *config){ - Config *parsed = 0; - b32 success = false; - FILE *file = open_file_try_current_path_then_binary_path(app, file_name); - if (file != 0){ - Data data = dump_file_handle(arena, file); - fclose(file); - if (data.data != 0){ - parsed = config_parse__data(arena, SCu8(file_name), SCu8(data), config); - success = true; - } - } - if (!success){ - config_init_default(config); - } - return(parsed); -} - -#if 0 -function void -init_theme_zero(Theme *theme){ - for (i32 i = 0; i < Stag_COUNT; ++i){ - theme->colors[i] = 0; - } -} - -function Config* -theme_parse__data(Partition *arena, String file_name, String data, Theme_Data *theme){ - theme->name = make_fixed_width_string(theme->space); - copy(&theme->name, "unnamed"); - init_theme_zero(&theme->theme); - - Config *parsed = text_data_to_parsed_data(arena, file_name, data); - if (parsed != 0){ - config_fixed_string_var(parsed, "name", 0, &theme->name, theme->space); - - for (i32 i = 0; i < Stag_COUNT; ++i){ - char *name = style_tag_names[i]; - u32 color = 0; - if (!config_uint_var(parsed, name, 0, &color)){ - color = 0xFFFF00FF; - } - theme->theme.colors[i] = color; - } - } - - return(parsed); -} - -function Config* -theme_parse__file_handle(Partition *arena, String file_name, FILE *file, Theme_Data *theme){ - String data = dump_file_handle(arena, file); - Config *parsed = 0; - if (data.str != 0){ - parsed = theme_parse__data(arena, file_name, data, theme); - } - return(parsed); -} - -function Config* -theme_parse__file_name(Application_Links *app, Partition *arena, - char *file_name, Theme_Data *theme){ - Config *parsed = 0; - FILE *file = open_file_try_current_path_then_binary_path(app, file_name); - if (file != 0){ - String data = dump_file_handle(arena, file); - fclose(file); - parsed = theme_parse__data(arena, make_string_slowly(file_name), data, theme); - } - if (parsed == 0){ - char space[256]; - String str = make_fixed_width_string(space); - append(&str, "Did not find "); - append(&str, file_name); - append(&str, ", color scheme not loaded"); - print_message(app, str.str, str.size); - } - return(parsed); -} -#endif - -//////////////////////////////// - -function void -config_feedback_bool(Arena *arena, List_String_Const_u8 *list, char *name, b32 val){ - string_list_pushf(arena, list, "%s = %s;\n", name, (char*)(val?"true":"false")); -} - -function void -config_feedback_string(Arena *arena, List_String_Const_u8 *list, char *name, String_Const_u8 val){ - val.size = clamp_bot(0, val.size); - string_list_pushf(arena, list, "%s = \"%.*s\";\n", name, string_expand(val)); -} - -function void -config_feedback_string(Arena *arena, List_String_Const_u8 *list, char *name, char *val){ - string_list_pushf(arena, list, "%s = \"%s\";\n", name, val); -} - -function void -config_feedback_extension_list(Arena *arena, List_String_Const_u8 *list, char *name, String_Const_u8_Array *extensions){ - string_list_pushf(arena, list, "%s = \"", name); - for (i32 i = 0; i < extensions->count; ++i){ - String_Const_u8 ext = extensions->strings[i]; - string_list_pushf(arena, list, ".%.*s", string_expand(ext)); - } - string_list_push_u8_lit(arena, list, "\";\n"); -} - -function void -config_feedback_int(Arena *arena, List_String_Const_u8 *list, char *name, i32 val){ - string_list_pushf(arena, list, "%s = %d;\n", name, val); -} - -//////////////////////////////// - -function void -load_config_and_apply(Application_Links *app, Arena *out_arena, Config_Data *config, i32 override_font_size, b32 override_hinting){ - Scratch_Block scratch(app); - - linalloc_clear(out_arena); - Config *parsed = config_parse__file_name(app, out_arena, "config.4coder", config); - - if (parsed != 0){ - // Top - print_message(app, string_u8_litexpr("Loaded config file:\n")); - - // Errors - String_Const_u8 error_text = config_stringize_errors(scratch, parsed); - if (error_text.str != 0){ - print_message(app, error_text); - } - - // Values - Temp_Memory temp2 = begin_temp(scratch); - // TODO(allen): switch to List_String_Const_u8 for the whole config system - List_String_Const_u8 list = {}; - - { - config_feedback_string(scratch, &list, "user_name", config->user_name); - config_feedback_extension_list(scratch, &list, "treat_as_code", &config->code_exts); - - config_feedback_string(scratch, &list, "mode", config->mode); - - config_feedback_bool(scratch, &list, "use_scroll_bars", config->use_scroll_bars); - config_feedback_bool(scratch, &list, "use_file_bars", config->use_file_bars); - config_feedback_bool(scratch, &list, "hide_file_bar_in_ui", config->hide_file_bar_in_ui); - config_feedback_bool(scratch, &list, "use_error_highlight", config->use_error_highlight); - config_feedback_bool(scratch, &list, "use_jump_highlight", config->use_jump_highlight); - config_feedback_bool(scratch, &list, "use_scope_highlight", config->use_scope_highlight); - config_feedback_bool(scratch, &list, "use_paren_helper", config->use_paren_helper); - config_feedback_bool(scratch, &list, "use_comment_keyword", config->use_comment_keyword); - config_feedback_bool(scratch, &list, "lister_whole_word_backspace_when_modified", config->lister_whole_word_backspace_when_modified); - config_feedback_bool(scratch, &list, "show_line_number_margins", config->show_line_number_margins); - - config_feedback_bool(scratch, &list, "enable_virtual_whitespace", config->enable_virtual_whitespace); - config_feedback_bool(scratch, &list, "enable_code_wrapping", config->enable_code_wrapping); - config_feedback_bool(scratch, &list, "automatically_indent_text_on_save", config->automatically_indent_text_on_save); - config_feedback_bool(scratch, &list, "automatically_save_changes_on_build", config->automatically_save_changes_on_build); - config_feedback_bool(scratch, &list, "automatically_adjust_wrapping", config->automatically_adjust_wrapping); - config_feedback_bool(scratch, &list, "automatically_load_project", config->automatically_load_project); - - config_feedback_bool(scratch, &list, "indent_with_tabs", config->indent_with_tabs); - config_feedback_int(scratch, &list, "indent_width", config->indent_width); - - config_feedback_int(scratch, &list, "default_wrap_width", config->default_wrap_width); - config_feedback_int(scratch, &list, "default_min_base_width", config->default_min_base_width); - - config_feedback_string(scratch, &list, "default_theme_name", config->default_theme_name); - config_feedback_bool(scratch, &list, "highlight_line_at_cursor", config->highlight_line_at_cursor); - - config_feedback_string(scratch, &list, "default_font_name", config->default_font_name); - config_feedback_int(scratch, &list, "default_font_size", config->default_font_size); - config_feedback_bool(scratch, &list, "default_font_hinting", config->default_font_hinting); - - config_feedback_string(scratch, &list, "default_compiler_bat", config->default_compiler_bat); - config_feedback_string(scratch, &list, "default_flags_bat", config->default_flags_bat); - config_feedback_string(scratch, &list, "default_compiler_sh", config->default_compiler_sh); - config_feedback_string(scratch, &list, "default_flags_sh", config->default_flags_sh); - - config_feedback_bool(scratch, &list, "lalt_lctrl_is_altgr", config->lalt_lctrl_is_altgr); - } - - string_list_push_u8_lit(scratch, &list, "\n"); - String_Const_u8 message = string_list_flatten(scratch, list); - print_message(app, message); - end_temp(temp2); - - // Apply config - change_mode(app, config->mode); - global_set_setting(app, GlobalSetting_LAltLCtrlIsAltGr, config->lalt_lctrl_is_altgr); - - //change_theme(app, config->default_theme_name.str, config->default_theme_name.size); - - Face_Description description = {}; - description.font.file_name = config->default_font_name; - description.font.in_4coder_font_folder = true; - if (override_font_size != 0){ - description.parameters.pt_size = override_font_size; - } - else{ - description.parameters.pt_size = config->default_font_size; - } - description.parameters.hinting = config->default_font_hinting || override_hinting; - if (!modify_global_face_by_description(app, description)){ - description.font.in_4coder_font_folder = !description.font.in_4coder_font_folder; - modify_global_face_by_description(app, description); - } - } -} - -#if 0 -function void -load_theme_file_into_live_set(Application_Links *app, Partition *scratch, char *file_name){ - Temp_Memory temp = begin_temp_memory(scratch); - Theme_Data theme = {}; - Config *config = theme_parse__file_name(app, scratch, file_name, &theme); - String error_text = config_stringize_errors(scratch, config); - print_message(app, error_text.str, error_text.size); - end_temp_memory(temp); - create_theme(app, &theme.theme, theme.name.str, theme.name.size); -} - -function void -load_folder_of_themes_into_live_set(Application_Links *app, Partition *scratch, - char *folder_name){ - char path_space[512]; - String path = make_fixed_width_string(path_space); - path.size = get_4ed_path(app, path_space, sizeof(path_space)); - append(&path, folder_name); - - if (path.size < path.memory_size){ - File_List list = get_file_list(app, path.str, path.size); - for (u32 i = 0; i < list.count; ++i){ - File_Info *info = &list.infos[i]; - if (info->folder){ - continue; - } - String info_file_name = make_string(info->filename, info->filename_len); - char file_name_space[512]; - String file_name = make_fixed_width_string(file_name_space); - copy(&file_name, path); - append(&file_name, "/"); - append(&file_name, info_file_name); - if (terminate_with_null(&file_name)){ - load_theme_file_into_live_set(app, scratch, file_name.str); - } - } - free_file_list(app, list); - } -} -#endif - -// BOTTOM - +/* +4coder_config.cpp - Parsing *.4coder files. +*/ + +// TOP + +function String_Const_u8_Array +parse_extension_line_to_extension_list(Arena *arena, String_Const_u8 str){ + i32 count = 0; + for (umem i = 0; i < str.size; i += 1){ + if (str.str[i] == '.'){ + count += 1; + } + } + + String_Const_u8_Array array = {}; + array.count = count; + array.strings = push_array(arena, String_Const_u8, count); + + push_align(arena, 1); + str = string_skip(str, string_find_first(str, '.') + 1); + for (i32 i = 0; i < count; i += 1){ + umem next_period = string_find_first(str, '.'); + String_Const_u8 extension = string_prefix(str, next_period); + str = string_skip(str, next_period + 1); + array.strings[i] = push_string_copy(arena, extension); + } + push_align(arena, 8); + + return(array); +} + +//////////////////////////////// + +function Error_Location +get_error_location(u8 *base, u8 *pos){ + Error_Location location = {}; + location.line_number = 1; + location.column_number = 1; + for (u8 *ptr = base; + ptr < pos; + ptr += 1){ + if (*ptr == '\n'){ + location.line_number += 1; + location.column_number = 1; + } + else{ + location.column_number += 1; + } + } + return(location); +} + +function String_Const_u8 +config_stringize_errors(Arena *arena, Config *parsed){ + String_Const_u8 result = {}; + if (parsed->errors.first != 0){ + List_String_Const_u8 list = {}; + for (Config_Error *error = parsed->errors.first; + error != 0; + error = error->next){ + Error_Location location = get_error_location(parsed->data.str, error->pos); + string_list_pushf(arena, &list, "%.*s:%d:%d: %.*s\n", + string_expand(error->file_name), location.line_number, location.column_number, string_expand(error->text)); + } + result = string_list_flatten(arena, list); + } + return(result); +} + +//////////////////////////////// + +function void +config_parser__advance_to_next(Config_Parser *ctx){ + Token *t = ctx->token; + Token *e = ctx->end; + for (t += 1; + t < e && (t->kind == TokenBaseKind_Comment || + t->kind == TokenBaseKind_Whitespace); + t += 1); + ctx->token = t; +} + +function Config_Parser +make_config_parser(Arena *arena, String_Const_u8 file_name, String_Const_u8 data, Token_Array array){ + Config_Parser ctx = {}; + ctx.start = array.tokens; + ctx.token = ctx.start - 1; + ctx.end = ctx.start + array.count; + ctx.file_name = file_name; + ctx.data = data; + ctx.arena = arena; + config_parser__advance_to_next(&ctx); + return(ctx); +} + +function b32 +config_parser__recognize_base_token(Config_Parser *ctx, Token_Base_Kind kind){ + b32 result = false; + if (ctx->start <= ctx->token && ctx->token < ctx->end){ + result = (ctx->token->kind == kind); + } + else if (kind == TokenBaseKind_EOF){ + result = true; + } + return(result); +} + +function b32 +config_parser__recognize_token(Config_Parser *ctx, Token_Cpp_Kind kind){ + b32 result = false; + if (ctx->start <= ctx->token && ctx->token < ctx->end){ + result = (ctx->token->sub_kind == kind); + } + else if (kind == TokenCppKind_EOF){ + result = true; + } + return(result); +} + +function b32 +config_parser__recognize_boolean(Config_Parser *ctx){ + b32 result = false; + Token *token = ctx->token; + if (ctx->start <= ctx->token && ctx->token < ctx->end){ + result = (token->sub_kind == TokenCppKind_LiteralTrue || + token->sub_kind == TokenCppKind_LiteralFalse); + } + return(result); +} + +function String_Const_u8 +config_parser__get_lexeme(Config_Parser *ctx){ + String_Const_u8 lexeme = {}; + Token *token = ctx->token; + if (ctx->start <= token && token < ctx->end){ + lexeme = SCu8(ctx->data.str + token->pos, token->size); + } + return(lexeme); +} + +function Config_Integer +config_parser__get_int(Config_Parser *ctx){ + Config_Integer config_integer = {}; + String_Const_u8 str = config_parser__get_lexeme(ctx); + if (string_match(string_prefix(str, 2), string_u8_litexpr("0x"))){ + config_integer.is_signed = false; + config_integer.uinteger = (u32)(string_to_integer(string_skip(str, 2), 16)); + } + else{ + b32 is_negative = (string_get_character(str, 0) == '-'); + if (is_negative){ + str = string_skip(str, 1); + } + config_integer.is_signed = true; + config_integer.integer = (i32)(string_to_integer(str, 10)); + if (is_negative){ + config_integer.integer *= -1; + } + } + return(config_integer); +} + +function b32 +config_parser__get_boolean(Config_Parser *ctx){ + String_Const_u8 str = config_parser__get_lexeme(ctx); + return(string_match(str, string_u8_litexpr("true"))); +} + +function b32 +config_parser__recognize_text(Config_Parser *ctx, String_Const_u8 text){ + String_Const_u8 lexeme = config_parser__get_lexeme(ctx); + return(lexeme.str != 0 && string_match(lexeme, text)); +} + +function b32 +config_parser__match_token(Config_Parser *ctx, Token_Cpp_Kind kind){ + b32 result = config_parser__recognize_token(ctx, kind); + if (result){ + config_parser__advance_to_next(ctx); + } + return(result); +} + +function b32 +config_parser__match_text(Config_Parser *ctx, String_Const_u8 text){ + b32 result = config_parser__recognize_text(ctx, text); + if (result){ + config_parser__advance_to_next(ctx); + } + return(result); +} + +#define config_parser__match_text_lit(c,s) config_parser__match_text((c), string_u8_litexpr(s)) + +function Config *config_parser__config (Config_Parser *ctx); +function i32 *config_parser__version (Config_Parser *ctx); +function Config_Assignment *config_parser__assignment(Config_Parser *ctx); +function Config_LValue *config_parser__lvalue (Config_Parser *ctx); +function Config_RValue *config_parser__rvalue (Config_Parser *ctx); +function Config_Compound *config_parser__compound (Config_Parser *ctx); +function Config_Compound_Element *config_parser__element (Config_Parser *ctx); + +function Config* +text_data_and_token_array_to_parse_data(Arena *arena, String_Const_u8 file_name, String_Const_u8 data, Token_Array array){ + Temp_Memory restore_point = begin_temp(arena); + Config_Parser ctx = make_config_parser(arena, file_name, data, array); + Config *config = config_parser__config(&ctx); + if (config == 0){ + end_temp(restore_point); + } + return(config); +} + +// TODO(allen): Move to string library +function Config_Error* +config_error_push(Arena *arena, Config_Error_List *list, String_Const_u8 file_name, u8 *pos, char *error_text){ + Config_Error *error = push_array(arena, Config_Error, 1); + zdll_push_back(list->first, list->last, error); + list->count += 1; + error->file_name = file_name; + error->pos = pos; + error->text = push_string_copy(arena, SCu8(error_text)); + return(error); +} + +function u8* +config_parser__get_pos(Config_Parser *ctx){ + return(ctx->data.str + ctx->token->pos); +} + +function void +config_parser__log_error_pos(Config_Parser *ctx, u8 *pos, char *error_text){ + config_error_push(ctx->arena, &ctx->errors, ctx->file_name, pos, error_text); +} + +function void +config_parser__log_error(Config_Parser *ctx, char *error_text){ + config_parser__log_error_pos(ctx, config_parser__get_pos(ctx), error_text); +} + +function Config* +config_parser__config(Config_Parser *ctx){ + i32 *version = config_parser__version(ctx); + + Config_Assignment *first = 0; + Config_Assignment *last = 0; + i32 count = 0; + for (;!config_parser__recognize_token(ctx, TokenCppKind_EOF);){ + Config_Assignment *assignment = config_parser__assignment(ctx); + if (assignment != 0){ + zdll_push_back(first, last, assignment); + count += 1; + } + } + + Config *config = push_array(ctx->arena, Config, 1); + block_zero_struct(config); + config->version = version; + config->first = first; + config->last = last; + config->count = count; + config->errors = ctx->errors; + config->file_name = ctx->file_name; + config->data = ctx->data; + return(config); +} + +function void +config_parser__recover_parse(Config_Parser *ctx){ + for (;;){ + if (config_parser__match_token(ctx, TokenCppKind_Semicolon)){ + break; + } + if (config_parser__recognize_token(ctx, TokenCppKind_EOF)){ + break; + } + config_parser__advance_to_next(ctx); + } +} + +function i32* +config_parser__version(Config_Parser *ctx){ + require(config_parser__match_text_lit(ctx, "version")); + + if (!config_parser__match_token(ctx, TokenCppKind_ParenOp)){ + config_parser__log_error(ctx, "expected token '(' for version specifier: 'version(#)'"); + config_parser__recover_parse(ctx); + return(0); + } + + if (!config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)){ + config_parser__log_error(ctx, "expected an integer constant for version specifier: 'version(#)'"); + config_parser__recover_parse(ctx); + return(0); + } + + Config_Integer value = config_parser__get_int(ctx); + config_parser__advance_to_next(ctx); + + if (!config_parser__match_token(ctx, TokenCppKind_ParenCl)){ + config_parser__log_error(ctx, "expected token ')' for version specifier: 'version(#)'"); + config_parser__recover_parse(ctx); + return(0); + } + + if (!config_parser__match_token(ctx, TokenCppKind_Semicolon)){ + config_parser__log_error(ctx, "expected token ';' for version specifier: 'version(#)'"); + config_parser__recover_parse(ctx); + return(0); + } + + i32 *ptr = push_array(ctx->arena, i32, 1); + *ptr = value.integer; + return(ptr); +} + +function Config_Assignment* +config_parser__assignment(Config_Parser *ctx){ + u8 *pos = config_parser__get_pos(ctx); + + Config_LValue *l = config_parser__lvalue(ctx); + if (l == 0){ + config_parser__log_error(ctx, "expected an l-value; l-value formats: 'identifier', 'identifier[#]'"); + config_parser__recover_parse(ctx); + return(0); + } + + if (!config_parser__match_token(ctx, TokenCppKind_Eq)){ + config_parser__log_error(ctx, "expected token '=' for assignment: 'l-value = r-value;'"); + config_parser__recover_parse(ctx); + return(0); + } + + Config_RValue *r = config_parser__rvalue(ctx); + if (r == 0){ + config_parser__log_error(ctx, "expected an r-value; r-value formats:\n" + "\tconstants (true, false, integers, hexadecimal integers, strings, characters)\n" + "\tany l-value that is set in the file\n" + "\tcompound: '{ compound-element, compound-element, compound-element ...}'\n" + "\ta compound-element is an r-value, and can have a layout specifier\n" + "\tcompound-element with layout specifier: .name = r-value, .integer = r-value"); + config_parser__recover_parse(ctx); + return(0); + } + + if (!config_parser__match_token(ctx, TokenCppKind_Semicolon)){ + config_parser__log_error(ctx, "expected token ';' for assignment: 'l-value = r-value;'"); + config_parser__recover_parse(ctx); + return(0); + } + + Config_Assignment *assignment = push_array_zero(ctx->arena, Config_Assignment, 1); + assignment->pos = pos; + assignment->l = l; + assignment->r = r; + return(assignment); +} + +function Config_LValue* +config_parser__lvalue(Config_Parser *ctx){ + require(config_parser__recognize_token(ctx, TokenCppKind_Identifier)); + String_Const_u8 identifier = config_parser__get_lexeme(ctx); + config_parser__advance_to_next(ctx); + + i32 index = 0; + if (config_parser__match_token(ctx, TokenCppKind_BrackOp)){ + require(config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)); + Config_Integer value = config_parser__get_int(ctx); + index = value.integer; + config_parser__advance_to_next(ctx); + require(config_parser__match_token(ctx, TokenCppKind_BrackCl)); + } + + Config_LValue *lvalue = push_array_zero(ctx->arena, Config_LValue, 1); + lvalue->identifier = identifier; + lvalue->index = index; + return(lvalue); +} + +function Config_RValue* +config_parser__rvalue(Config_Parser *ctx){ + Config_RValue *rvalue = 0; + if (config_parser__recognize_token(ctx, TokenCppKind_Identifier)){ + Config_LValue *l = config_parser__lvalue(ctx); + require(l != 0); + rvalue = push_array_zero(ctx->arena, Config_RValue, 1); + rvalue->type = ConfigRValueType_LValue; + rvalue->lvalue = l; + } + else if (config_parser__recognize_token(ctx, TokenCppKind_BraceOp)){ + config_parser__advance_to_next(ctx); + Config_Compound *compound = config_parser__compound(ctx); + require(compound != 0); + rvalue = push_array_zero(ctx->arena, Config_RValue, 1); + rvalue->type = ConfigRValueType_Compound; + rvalue->compound = compound; + } + else if (config_parser__recognize_boolean(ctx)){ + b32 b = config_parser__get_boolean(ctx); + config_parser__advance_to_next(ctx); + rvalue = push_array_zero(ctx->arena, Config_RValue, 1); + rvalue->type = ConfigRValueType_Boolean; + rvalue->boolean = b; + } + else if (config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)){ + Config_Integer value = config_parser__get_int(ctx); + config_parser__advance_to_next(ctx); + rvalue = push_array_zero(ctx->arena, Config_RValue, 1); + rvalue->type = ConfigRValueType_Integer; + if (value.is_signed){ + rvalue->integer = value.integer; + } + else{ + rvalue->uinteger = value.uinteger; + } + } + else if (config_parser__recognize_token(ctx, TokenCppKind_LiteralString)){ + String_Const_u8 s = config_parser__get_lexeme(ctx); + config_parser__advance_to_next(ctx); + s = string_chop(string_skip(s, 1), 1); + String_Const_u8 interpreted = string_interpret_escapes(ctx->arena, s); + rvalue = push_array_zero(ctx->arena, Config_RValue, 1); + rvalue->type = ConfigRValueType_String; + rvalue->string = interpreted; + } + else if (config_parser__recognize_token(ctx, TokenCppKind_LiteralCharacter)){ + String_Const_u8 s = config_parser__get_lexeme(ctx); + config_parser__advance_to_next(ctx); + s = string_chop(string_skip(s, 1), 1); + String_Const_u8 interpreted = string_interpret_escapes(ctx->arena, s); + rvalue = push_array_zero(ctx->arena, Config_RValue, 1); + rvalue->type = ConfigRValueType_Character; + rvalue->character = string_get_character(interpreted, 0); + } + return(rvalue); +} + +function void +config_parser__compound__check(Config_Parser *ctx, Config_Compound *compound){ + b32 implicit_index_allowed = true; + for (Config_Compound_Element *node = compound->first; + node != 0; + node = node->next){ + if (node->l.type != ConfigLayoutType_Unset){ + implicit_index_allowed = false; + } + else if (!implicit_index_allowed){ + config_parser__log_error_pos(ctx, node->l.pos, + "encountered unlabeled member after one or more labeled members"); + } + } +} + +function Config_Compound* +config_parser__compound(Config_Parser *ctx){ + Config_Compound_Element *first = 0; + Config_Compound_Element *last = 0; + i32 count = 0; + + Config_Compound_Element *element = config_parser__element(ctx); + require(element != 0); + zdll_push_back(first, last, element); + count += 1; + + for (;config_parser__match_token(ctx, TokenCppKind_Comma);){ + if (config_parser__recognize_token(ctx, TokenCppKind_BraceCl)){ + break; + } + element = config_parser__element(ctx); + require(element != 0); + zdll_push_back(first, last, element); + count += 1; + } + + require(config_parser__match_token(ctx, TokenCppKind_BraceCl)); + + Config_Compound *compound = push_array(ctx->arena, Config_Compound, 1); + block_zero_struct(compound); + compound->first = first; + compound->last = last; + compound->count = count; + config_parser__compound__check(ctx, compound); + return(compound); +} + +function Config_Compound_Element* +config_parser__element(Config_Parser *ctx){ + Config_Layout layout = {}; + layout.pos = config_parser__get_pos(ctx); + if (config_parser__match_token(ctx, TokenCppKind_Dot)){ + if (config_parser__recognize_token(ctx, TokenCppKind_Identifier)){ + layout.type = ConfigLayoutType_Identifier; + layout.identifier = config_parser__get_lexeme(ctx); + config_parser__advance_to_next(ctx); + } + else if (config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)){ + layout.type = ConfigLayoutType_Integer; + Config_Integer value = config_parser__get_int(ctx); + layout.integer = value.integer; + config_parser__advance_to_next(ctx); + } + else{ + return(0); + } + require(config_parser__match_token(ctx, TokenCppKind_Eq)); + } + Config_RValue *rvalue = config_parser__rvalue(ctx); + require(rvalue != 0); + Config_Compound_Element *element = push_array(ctx->arena, Config_Compound_Element, 1); + block_zero_struct(element); + element->l = layout; + element->r = rvalue; + return(element); +} + +//////////////////////////////// + +function Config_Error* +config_add_error(Arena *arena, Config *config, u8 *pos, char *error_text){ + return(config_error_push(arena, &config->errors, config->file_name, pos, error_text)); +} + +//////////////////////////////// + +function Config_Assignment* +config_lookup_assignment(Config *config, String_Const_u8 var_name, i32 subscript){ + Config_Assignment *assignment = 0; + for (assignment = config->first; + assignment != 0; + assignment = assignment->next){ + Config_LValue *l = assignment->l; + if (l != 0 && string_match(l->identifier, var_name) && l->index == subscript){ + break; + } + } + return(assignment); +} + +function Config_Get_Result +config_var(Config *config, String_Const_u8 var_name, i32 subscript); + +function Config_Get_Result +config_evaluate_rvalue(Config *config, Config_Assignment *assignment, Config_RValue *r){ + Config_Get_Result result = {}; + if (r != 0 && !assignment->visited){ + if (r->type == ConfigRValueType_LValue){ + assignment->visited = true; + Config_LValue *l = r->lvalue; + result = config_var(config, l->identifier, l->index); + assignment->visited = false; + } + else{ + result.success = true; + result.pos = assignment->pos; + result.type = r->type; + switch (r->type){ + case ConfigRValueType_Boolean: + { + result.boolean = r->boolean; + }break; + + case ConfigRValueType_Integer: + { + result.integer = r->integer; + }break; + + case ConfigRValueType_String: + { + result.string = r->string; + }break; + + case ConfigRValueType_Character: + { + result.character = r->character; + }break; + + case ConfigRValueType_Compound: + { + result.compound = r->compound; + }break; + } + } + } + return(result); +} + +function Config_Get_Result +config_var(Config *config, String_Const_u8 var_name, i32 subscript){ + Config_Get_Result result = {}; + Config_Assignment *assignment = config_lookup_assignment(config, var_name, subscript); + if (assignment != 0){ + result = config_evaluate_rvalue(config, assignment, assignment->r); + } + return(result); +} + +function Config_Get_Result +config_compound_member(Config *config, Config_Compound *compound, String_Const_u8 var_name, i32 index){ + Config_Get_Result result = {}; + i32 implicit_index = 0; + b32 implicit_index_is_valid = true; + for (Config_Compound_Element *element = compound->first; + element != 0; + element = element->next, implicit_index += 1){ + b32 element_matches_query = false; + switch (element->l.type){ + case ConfigLayoutType_Unset: + { + if (implicit_index_is_valid && index == implicit_index){ + element_matches_query = true; + } + }break; + + case ConfigLayoutType_Identifier: + { + implicit_index_is_valid = false; + if (string_match(element->l.identifier, var_name)){ + element_matches_query = true; + } + }break; + + case ConfigLayoutType_Integer: + { + implicit_index_is_valid = false; + if (element->l.integer == index){ + element_matches_query = true; + } + }break; + } + if (element_matches_query){ + Config_Assignment dummy_assignment = {}; + dummy_assignment.pos = element->l.pos; + result = config_evaluate_rvalue(config, &dummy_assignment, element->r); + break; + } + } + return(result); +} + +function Config_Iteration_Step_Result +typed_array_iteration_step(Config *parsed, Config_Compound *compound, Config_RValue_Type type, i32 index); + +function i32 +typed_array_get_count(Config *parsed, Config_Compound *compound, Config_RValue_Type type); + +function Config_Get_Result_List +typed_array_reference_list(Arena *arena, Config *parsed, Config_Compound *compound, Config_RValue_Type type); + +#define config_fixed_string_var(c,v,s,o,a) config_placed_string_var((c),(v),(s),(o),(a),sizeof(a)) + +//////////////////////////////// + +function b32 +config_has_var(Config *config, String_Const_u8 var_name, i32 subscript){ + Config_Get_Result result = config_var(config, var_name, subscript); + return(result.success && result.type == ConfigRValueType_NoType); +} + +function b32 +config_has_var(Config *config, char *var_name, i32 subscript){ + return(config_has_var(config, SCu8(var_name), subscript)); +} + +function b32 +config_bool_var(Config *config, String_Const_u8 var_name, i32 subscript, b32* var_out){ + Config_Get_Result result = config_var(config, var_name, subscript); + b32 success = (result.success && result.type == ConfigRValueType_Boolean); + if (success){ + *var_out = result.boolean; + } + return(success); +} +function b32 +config_bool_var(Config *config, String_Const_u8 var_name, i32 subscript, b8 *var_out){ + b32 temp = false; + b32 success = config_bool_var(config, var_name, subscript, &temp); + if (success){ + *var_out = (temp != false); + } + return(success); +} +function b32 +config_bool_var(Config *config, char *var_name, i32 subscript, b32* var_out){ + return(config_bool_var(config, SCu8(var_name), subscript, var_out)); +} +function b32 +config_bool_var(Config *config, char* var_name, i32 subscript, b8 *var_out){ + b32 temp = false; + b32 success = config_bool_var(config, SCu8(var_name), subscript, &temp); + if (success){ + *var_out = (temp != false); + } + return(success); +} + +function b32 +config_int_var(Config *config, String_Const_u8 var_name, i32 subscript, i32* var_out){ + Config_Get_Result result = config_var(config, var_name, subscript); + b32 success = result.success && result.type == ConfigRValueType_Integer; + if (success){ + *var_out = result.integer; + } + return(success); +} + +function b32 +config_int_var(Config *config, char *var_name, i32 subscript, i32* var_out){ + return(config_int_var(config, SCu8(var_name), subscript, var_out)); +} + +function b32 +config_uint_var(Config *config, String_Const_u8 var_name, i32 subscript, u32* var_out){ + Config_Get_Result result = config_var(config, var_name, subscript); + b32 success = result.success && result.type == ConfigRValueType_Integer; + if (success){ + *var_out = result.uinteger; + } + return(success); +} + +function b32 +config_uint_var(Config *config, char *var_name, i32 subscript, u32* var_out){ + return(config_uint_var(config, SCu8(var_name), subscript, var_out)); +} + +function b32 +config_string_var(Config *config, String_Const_u8 var_name, i32 subscript, String_Const_u8* var_out){ + Config_Get_Result result = config_var(config, var_name, subscript); + b32 success = result.success && result.type == ConfigRValueType_String; + if (success){ + *var_out = result.string; + } + return(success); +} + +function b32 +config_string_var(Config *config, char *var_name, i32 subscript, String_Const_u8* var_out){ + return(config_string_var(config, SCu8(var_name), subscript, var_out)); +} + +function b32 +config_placed_string_var(Config *config, String_Const_u8 var_name, i32 subscript, String_Const_u8* var_out, u8 *space, umem space_size){ + Config_Get_Result result = config_var(config, var_name, subscript); + b32 success = (result.success && result.type == ConfigRValueType_String); + if (success){ + umem size = result.string.size; + size = clamp_top(size, space_size); + block_copy(space, result.string.str, size); + *var_out = SCu8(space, size); + } + return(success); +} + +function b32 +config_placed_string_var(Config *config, char *var_name, i32 subscript, String_Const_u8* var_out, u8 *space, umem space_size){ + return(config_placed_string_var(config, SCu8(var_name), subscript, var_out, space, space_size)); +} + +function b32 +config_char_var(Config *config, String_Const_u8 var_name, i32 subscript, char* var_out){ + Config_Get_Result result = config_var(config, var_name, subscript); + b32 success = result.success && result.type == ConfigRValueType_Character; + if (success){ + *var_out = result.character; + } + return(success); +} + +function b32 +config_char_var(Config *config, char *var_name, i32 subscript, char* var_out){ + return(config_char_var(config, SCu8(var_name), subscript, var_out)); +} + +function b32 +config_compound_var(Config *config, String_Const_u8 var_name, i32 subscript, Config_Compound** var_out){ + Config_Get_Result result = config_var(config, var_name, subscript); + b32 success = result.success && result.type == ConfigRValueType_Compound; + if (success){ + *var_out = result.compound; + } + return(success); +} + +function b32 +config_compound_var(Config *config, char *var_name, i32 subscript, Config_Compound** var_out){ + return(config_compound_var(config, SCu8(var_name), subscript, var_out)); +} + +function b32 +config_compound_has_member(Config *config, Config_Compound *compound, + String_Const_u8 var_name, i32 index){ + Config_Get_Result result = config_compound_member(config, compound, var_name, index); + b32 success = result.success && result.type == ConfigRValueType_NoType; + return(success); +} + +function b32 +config_compound_has_member(Config *config, Config_Compound *compound, + char *var_name, i32 index){ + return(config_compound_has_member(config, compound, SCu8(var_name), index)); +} + +function b32 +config_compound_bool_member(Config *config, Config_Compound *compound, + String_Const_u8 var_name, i32 index, b32* var_out){ + Config_Get_Result result = config_compound_member(config, compound, var_name, index); + b32 success = result.success && result.type == ConfigRValueType_Boolean; + if (success){ + *var_out = result.boolean; + } + return(success); +} + +function b32 +config_compound_bool_member(Config *config, Config_Compound *compound, + char *var_name, i32 index, b32* var_out){ + return(config_compound_bool_member(config, compound, SCu8(var_name), index, var_out)); +} + +function b32 +config_compound_int_member(Config *config, Config_Compound *compound, + String_Const_u8 var_name, i32 index, i32* var_out){ + Config_Get_Result result = config_compound_member(config, compound, var_name, index); + b32 success = result.success && result.type == ConfigRValueType_Integer; + if (success){ + *var_out = result.integer; + } + return(success); +} + +function b32 +config_compound_int_member(Config *config, Config_Compound *compound, + char *var_name, i32 index, i32* var_out){ + return(config_compound_int_member(config, compound, SCu8(var_name), index, var_out)); +} + +function b32 +config_compound_uint_member(Config *config, Config_Compound *compound, + String_Const_u8 var_name, i32 index, u32* var_out){ + Config_Get_Result result = config_compound_member(config, compound, var_name, index); + b32 success = result.success && result.type == ConfigRValueType_Integer; + if (success){ + *var_out = result.uinteger; + } + return(success); +} + +function b32 +config_compound_uint_member(Config *config, Config_Compound *compound, + char *var_name, i32 index, u32* var_out){ + return(config_compound_uint_member(config, compound, SCu8(var_name), index, var_out)); +} + +function b32 +config_compound_string_member(Config *config, Config_Compound *compound, + String_Const_u8 var_name, i32 index, String_Const_u8* var_out){ + Config_Get_Result result = config_compound_member(config, compound, var_name, index); + b32 success = (result.success && result.type == ConfigRValueType_String); + if (success){ + *var_out = result.string; + } + return(success); +} + +function b32 +config_compound_string_member(Config *config, Config_Compound *compound, + char *var_name, i32 index, String_Const_u8* var_out){ + return(config_compound_string_member(config, compound, SCu8(var_name), index, var_out)); +} + +function b32 +config_compound_placed_string_member(Config *config, Config_Compound *compound, + String_Const_u8 var_name, i32 index, String_Const_u8* var_out, u8 *space, umem space_size){ + Config_Get_Result result = config_compound_member(config, compound, var_name, index); + b32 success = (result.success && result.type == ConfigRValueType_String); + if (success){ + umem size = result.string.size; + size = clamp_top(size, space_size); + block_copy(space, result.string.str, size); + *var_out = SCu8(space, size); + } + return(success); +} + +function b32 +config_compound_placed_string_member(Config *config, Config_Compound *compound, + char *var_name, i32 index, String_Const_u8* var_out, u8 *space, umem space_size){ + return(config_compound_placed_string_member(config, compound, SCu8(var_name), index, var_out, space, space_size)); +} + +function b32 +config_compound_char_member(Config *config, Config_Compound *compound, + String_Const_u8 var_name, i32 index, char* var_out){ + Config_Get_Result result = config_compound_member(config, compound, var_name, index); + b32 success = result.success && result.type == ConfigRValueType_Character; + if (success){ + *var_out = result.character; + } + return(success); +} + +function b32 +config_compound_char_member(Config *config, Config_Compound *compound, + char *var_name, i32 index, char* var_out){ + return(config_compound_char_member(config, compound, SCu8(var_name), index, var_out)); +} + +function b32 +config_compound_compound_member(Config *config, Config_Compound *compound, + String_Const_u8 var_name, i32 index, Config_Compound** var_out){ + Config_Get_Result result = config_compound_member(config, compound, var_name, index); + b32 success = result.success && result.type == ConfigRValueType_Compound; + if (success){ + *var_out = result.compound; + } + return(success); +} + +function b32 +config_compound_compound_member(Config *config, Config_Compound *compound, + char *var_name, i32 index, Config_Compound** var_out){ + return(config_compound_compound_member(config, compound, SCu8(var_name), index, var_out)); +} + +function Iteration_Step_Result +typed_has_array_iteration_step(Config *config, Config_Compound *compound, i32 index){ + Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_NoType, index); + return(result.step); +} + +function Iteration_Step_Result +typed_bool_array_iteration_step(Config *config, Config_Compound *compound, i32 index, b32* var_out){ + Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Boolean, index); + b32 success = (result.step == Iteration_Good); + if (success){ + *var_out = result.get.boolean; + } + return(result.step); +} + +function Iteration_Step_Result +typed_int_array_iteration_step(Config *config, Config_Compound *compound, i32 index, i32* var_out){ + Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Integer, index); + b32 success = (result.step == Iteration_Good); + if (success){ + *var_out = result.get.integer; + } + return(result.step); +} + +function Iteration_Step_Result +typed_uint_array_iteration_step(Config *config, Config_Compound *compound, i32 index, u32* var_out){ + Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Integer, index); + b32 success = (result.step == Iteration_Good); + if (success){ + *var_out = result.get.uinteger; + } + return(result.step); +} + +function Iteration_Step_Result +typed_string_array_iteration_step(Config *config, Config_Compound *compound, i32 index, String_Const_u8* var_out){ + Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_String, index); + b32 success = (result.step == Iteration_Good); + if (success){ + *var_out = result.get.string; + } + return(result.step); +} + +function Iteration_Step_Result +typed_placed_string_array_iteration_step(Config *config, Config_Compound *compound, i32 index, String_Const_u8* var_out, u8 *space, umem space_size){ + Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_String, index); + b32 success = (result.step == Iteration_Good); + if (success){ + umem size = result.get.string.size; + size = clamp_top(size, space_size); + block_copy(space, result.get.string.str, size); + *var_out = SCu8(space, size); + } + return(result.step); +} + +function Iteration_Step_Result +typed_char_array_iteration_step(Config *config, Config_Compound *compound, i32 index, char* var_out){ + Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Character, index); + b32 success = (result.step == Iteration_Good); + if (success){ + *var_out = result.get.character; + } + return(result.step); +} + +function Iteration_Step_Result +typed_compound_array_iteration_step(Config *config, Config_Compound *compound, i32 index, Config_Compound** var_out){ + Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Compound, index); + b32 success = (result.step == Iteration_Good); + if (success){ + *var_out = result.get.compound; + } + return(result.step); +} + +function i32 +typed_bool_array_get_count(Config *config, Config_Compound *compound){ + i32 count = typed_array_get_count(config, compound, ConfigRValueType_Boolean); + return(count); +} + +function i32 +typed_int_array_get_count(Config *config, Config_Compound *compound){ + i32 count = typed_array_get_count(config, compound, ConfigRValueType_Integer); + return(count); +} + +function i32 +typed_float_array_get_count(Config *config, Config_Compound *compound){ + i32 count = typed_array_get_count(config, compound, ConfigRValueType_Float); + return(count); +} + +function i32 +typed_string_array_get_count(Config *config, Config_Compound *compound){ + i32 count = typed_array_get_count(config, compound, ConfigRValueType_String); + return(count); +} + +function i32 +typed_character_array_get_count(Config *config, Config_Compound *compound){ + i32 count = typed_array_get_count(config, compound, ConfigRValueType_Character); + return(count); +} + +function i32 +typed_compound_array_get_count(Config *config, Config_Compound *compound){ + i32 count = typed_array_get_count(config, compound, ConfigRValueType_Compound); + return(count); +} + +function i32 +typed_no_type_array_get_count(Config *config, Config_Compound *compound){ + i32 count = typed_array_get_count(config, compound, ConfigRValueType_NoType); + return(count); +} + +function Config_Get_Result_List +typed_bool_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ + Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Boolean); + return(list); +} + +function Config_Get_Result_List +typed_int_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ + Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Integer); + return(list); +} + +function Config_Get_Result_List +typed_float_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ + Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Float); + return(list); +} + +function Config_Get_Result_List +typed_string_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ + Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_String); + return(list); +} + +function Config_Get_Result_List +typed_character_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ + Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Character); + return(list); +} + +function Config_Get_Result_List +typed_compound_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ + Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Compound); + return(list); +} + +function Config_Get_Result_List +typed_no_type_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ + Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_NoType); + return(list); +} + +//////////////////////////////// + +function Config_Iteration_Step_Result +typed_array_iteration_step(Config *parsed, Config_Compound *compound, Config_RValue_Type type, i32 index){ + Config_Iteration_Step_Result result = {}; + result.step = Iteration_Quit; + Config_Get_Result get_result = config_compound_member(parsed, compound, string_u8_litexpr("~"), index); + if (get_result.success){ + if (get_result.type == type || type == ConfigRValueType_NoType){ + result.step = Iteration_Good; + result.get = get_result; + } + else{ + result.step = Iteration_Skip; + } + } + return(result); +} + +function i32 +typed_array_get_count(Config *parsed, Config_Compound *compound, Config_RValue_Type type){ + i32 count = 0; + for (i32 i = 0;; ++i){ + Config_Iteration_Step_Result result = typed_array_iteration_step(parsed, compound, type, i); + if (result.step == Iteration_Skip){ + continue; + } + else if (result.step == Iteration_Quit){ + break; + } + count += 1; + } + return(count); +} + +function Config_Get_Result_List +typed_array_reference_list(Arena *arena, Config *parsed, Config_Compound *compound, Config_RValue_Type type){ + Config_Get_Result_List list = {}; + for (i32 i = 0;; ++i){ + Config_Iteration_Step_Result result = typed_array_iteration_step(parsed, compound, type, i); + if (result.step == Iteration_Skip){ + continue; + } + else if (result.step == Iteration_Quit){ + break; + } + Config_Get_Result_Node *node = push_array(arena, Config_Get_Result_Node, 1); + node->result = result.get; + zdll_push_back(list.first, list.last, node); + list.count += 1; + } + return(list); +} + +//////////////////////////////// + +function void +change_mode(Application_Links *app, String_Const_u8 mode){ + fcoder_mode = FCoderMode_Original; + if (string_match(mode, string_u8_litexpr("4coder"))){ + fcoder_mode = FCoderMode_Original; + } + else if (string_match(mode, string_u8_litexpr("notepad-like"))){ + begin_notepad_mode(app); + } + else{ + print_message(app, string_u8_litexpr("Unknown mode.\n")); + } +} + +//////////////////////////////// + +function Token_Array +token_array_from_text(Arena *arena, String_Const_u8 data){ + Token_List list = lex_full_input_cpp(arena, data); + return(token_array_from_list(arena, &list)); +} + +function Config* +text_data_to_parsed_data(Arena *arena, String_Const_u8 file_name, String_Const_u8 data){ + Config *parsed = 0; + Temp_Memory restore_point = begin_temp(arena); + Token_Array array = token_array_from_text(arena, data); + if (array.tokens != 0){ + parsed = text_data_and_token_array_to_parse_data(arena, file_name, data, array); + if (parsed == 0){ + end_temp(restore_point); + } + } + return(parsed); +} + +//////////////////////////////// + +function void +config_init_default(Config_Data *config){ + config->user_name = SCu8(config->user_name_space, (umem)0); + + block_zero_struct(&config->code_exts); + + config->mode = SCu8(config->mode_space, (umem)0); + + config->use_scroll_bars = false; + config->use_file_bars = true; + config->hide_file_bar_in_ui = true; + config->use_error_highlight = true; + config->use_jump_highlight = true; + config->use_scope_highlight = true; + config->use_paren_helper = true; + config->use_comment_keyword = true; + config->lister_whole_word_backspace_when_modified = false; + config->show_line_number_margins = false; + + config->enable_virtual_whitespace = true; + config->enable_code_wrapping = true; + config->automatically_adjust_wrapping = true; + config->automatically_indent_text_on_save = true; + config->automatically_save_changes_on_build = true; + config->automatically_load_project = false; + + config->indent_with_tabs = false; + config->indent_width = 4; + + config->default_wrap_width = 672; + config->default_min_base_width = 550; + + config->default_theme_name = SCu8(config->default_theme_name_space, sizeof("4coder") - 1); + block_copy(config->default_theme_name.str, "4coder", config->default_theme_name.size); + config->highlight_line_at_cursor = true; + + config->default_font_name = SCu8(config->default_font_name_space, (umem)0); + config->default_font_size = 16; + config->default_font_hinting = false; + + config->default_compiler_bat = SCu8(config->default_compiler_bat_space, 2); + block_copy(config->default_compiler_bat.str, "cl", 2); + + config->default_flags_bat = SCu8(config->default_flags_bat_space, (umem)0); + + config->default_compiler_sh = SCu8(config->default_compiler_sh_space, 3); + block_copy(config->default_compiler_sh.str, "g++", 3); + + config->default_flags_sh = SCu8(config->default_flags_sh_space, (umem)0); + + config->lalt_lctrl_is_altgr = false; +} + +function Config* +config_parse__data(Arena *arena, String_Const_u8 file_name, String_Const_u8 data, Config_Data *config){ + config_init_default(config); + + b32 success = false; + + Config *parsed = text_data_to_parsed_data(arena, file_name, data); + if (parsed != 0){ + success = true; + + config_fixed_string_var(parsed, "user_name", 0, + &config->user_name, config->user_name_space); + + String_Const_u8 str = {}; + if (config_string_var(parsed, "treat_as_code", 0, &str)){ + config->code_exts = parse_extension_line_to_extension_list(arena, str); + } + + config_fixed_string_var(parsed, "mode", 0, + &config->mode, config->mode_space); + + config_bool_var(parsed, "use_scroll_bars", 0, &config->use_scroll_bars); + config_bool_var(parsed, "use_file_bars", 0, &config->use_file_bars); + config_bool_var(parsed, "hide_file_bar_in_ui", 0, &config->hide_file_bar_in_ui); + config_bool_var(parsed, "use_error_highlight", 0, &config->use_error_highlight); + config_bool_var(parsed, "use_jump_highlight", 0, &config->use_jump_highlight); + config_bool_var(parsed, "use_scope_highlight", 0, &config->use_scope_highlight); + config_bool_var(parsed, "use_paren_helper", 0, &config->use_paren_helper); + config_bool_var(parsed, "use_comment_keyword", 0, &config->use_comment_keyword); + config_bool_var(parsed, "lister_whole_word_backspace_when_modified", 0, &config->lister_whole_word_backspace_when_modified); + config_bool_var(parsed, "show_line_number_margins", 0, &config->show_line_number_margins); + + + config_bool_var(parsed, "enable_virtual_whitespace", 0, &config->enable_virtual_whitespace); + config_bool_var(parsed, "enable_code_wrapping", 0, &config->enable_code_wrapping); + config_bool_var(parsed, "automatically_adjust_wrapping", 0, &config->automatically_adjust_wrapping); + config_bool_var(parsed, "automatically_indent_text_on_save", 0, &config->automatically_indent_text_on_save); + config_bool_var(parsed, "automatically_save_changes_on_build", 0, &config->automatically_save_changes_on_build); + config_bool_var(parsed, "automatically_load_project", 0, &config->automatically_load_project); + + config_bool_var(parsed, "indent_with_tabs", 0, &config->indent_with_tabs); + config_int_var(parsed, "indent_width", 0, &config->indent_width); + + config_int_var(parsed, "default_wrap_width", 0, &config->default_wrap_width); + config_int_var(parsed, "default_min_base_width", 0, &config->default_min_base_width); + + config_fixed_string_var(parsed, "default_theme_name", 0, + &config->default_theme_name, config->default_theme_name_space); + config_bool_var(parsed, "highlight_line_at_cursor", 0, &config->highlight_line_at_cursor); + + config_fixed_string_var(parsed, "default_font_name", 0, + &config->default_font_name, config->default_font_name_space); + config_int_var(parsed, "default_font_size", 0, &config->default_font_size); + config_bool_var(parsed, "default_font_hinting", 0, &config->default_font_hinting); + + config_fixed_string_var(parsed, "default_compiler_bat", 0, + &config->default_compiler_bat, config->default_compiler_bat_space); + config_fixed_string_var(parsed, "default_flags_bat", 0, + &config->default_flags_bat, config->default_flags_bat_space); + config_fixed_string_var(parsed, "default_compiler_sh", 0, + &config->default_compiler_sh, config->default_compiler_sh_space); + config_fixed_string_var(parsed, "default_flags_sh", 0, + &config->default_flags_sh, config->default_flags_sh_space); + + config_bool_var(parsed, "lalt_lctrl_is_altgr", 0, &config->lalt_lctrl_is_altgr); + } + + if (!success){ + config_init_default(config); + } + + return(parsed); +} + +function Config* +config_parse__file_handle(Arena *arena, String_Const_u8 file_name, FILE *file, Config_Data *config){ + Config *parsed = 0; + Data data = dump_file_handle(arena, file); + if (data.data != 0){ + parsed = config_parse__data(arena, file_name, SCu8(data), config); + } + else{ + config_init_default(config); + } + return(parsed); +} + +function Config* +config_parse__file_name(Application_Links *app, Arena *arena, char *file_name, Config_Data *config){ + Config *parsed = 0; + b32 success = false; + FILE *file = open_file_try_current_path_then_binary_path(app, file_name); + if (file != 0){ + Data data = dump_file_handle(arena, file); + fclose(file); + if (data.data != 0){ + parsed = config_parse__data(arena, SCu8(file_name), SCu8(data), config); + success = true; + } + } + if (!success){ + config_init_default(config); + } + return(parsed); +} + +#if 0 +function void +init_theme_zero(Theme *theme){ + for (i32 i = 0; i < Stag_COUNT; ++i){ + theme->colors[i] = 0; + } +} + +function Config* +theme_parse__data(Partition *arena, String file_name, String data, Theme_Data *theme){ + theme->name = make_fixed_width_string(theme->space); + copy(&theme->name, "unnamed"); + init_theme_zero(&theme->theme); + + Config *parsed = text_data_to_parsed_data(arena, file_name, data); + if (parsed != 0){ + config_fixed_string_var(parsed, "name", 0, &theme->name, theme->space); + + for (i32 i = 0; i < Stag_COUNT; ++i){ + char *name = style_tag_names[i]; + u32 color = 0; + if (!config_uint_var(parsed, name, 0, &color)){ + color = 0xFFFF00FF; + } + theme->theme.colors[i] = color; + } + } + + return(parsed); +} + +function Config* +theme_parse__file_handle(Partition *arena, String file_name, FILE *file, Theme_Data *theme){ + String data = dump_file_handle(arena, file); + Config *parsed = 0; + if (data.str != 0){ + parsed = theme_parse__data(arena, file_name, data, theme); + } + return(parsed); +} + +function Config* +theme_parse__file_name(Application_Links *app, Partition *arena, + char *file_name, Theme_Data *theme){ + Config *parsed = 0; + FILE *file = open_file_try_current_path_then_binary_path(app, file_name); + if (file != 0){ + String data = dump_file_handle(arena, file); + fclose(file); + parsed = theme_parse__data(arena, make_string_slowly(file_name), data, theme); + } + if (parsed == 0){ + char space[256]; + String str = make_fixed_width_string(space); + append(&str, "Did not find "); + append(&str, file_name); + append(&str, ", color scheme not loaded"); + print_message(app, str.str, str.size); + } + return(parsed); +} +#endif + +//////////////////////////////// + +function void +config_feedback_bool(Arena *arena, List_String_Const_u8 *list, char *name, b32 val){ + string_list_pushf(arena, list, "%s = %s;\n", name, (char*)(val?"true":"false")); +} + +function void +config_feedback_string(Arena *arena, List_String_Const_u8 *list, char *name, String_Const_u8 val){ + val.size = clamp_bot(0, val.size); + string_list_pushf(arena, list, "%s = \"%.*s\";\n", name, string_expand(val)); +} + +function void +config_feedback_string(Arena *arena, List_String_Const_u8 *list, char *name, char *val){ + string_list_pushf(arena, list, "%s = \"%s\";\n", name, val); +} + +function void +config_feedback_extension_list(Arena *arena, List_String_Const_u8 *list, char *name, String_Const_u8_Array *extensions){ + string_list_pushf(arena, list, "%s = \"", name); + for (i32 i = 0; i < extensions->count; ++i){ + String_Const_u8 ext = extensions->strings[i]; + string_list_pushf(arena, list, ".%.*s", string_expand(ext)); + } + string_list_push_u8_lit(arena, list, "\";\n"); +} + +function void +config_feedback_int(Arena *arena, List_String_Const_u8 *list, char *name, i32 val){ + string_list_pushf(arena, list, "%s = %d;\n", name, val); +} + +//////////////////////////////// + +function void +load_config_and_apply(Application_Links *app, Arena *out_arena, Config_Data *config, + i32 override_font_size, b32 override_hinting){ + Scratch_Block scratch(app); + + linalloc_clear(out_arena); + Config *parsed = config_parse__file_name(app, out_arena, "config.4coder", config); + + if (parsed != 0){ + // Top + print_message(app, string_u8_litexpr("Loaded config file:\n")); + + // Errors + String_Const_u8 error_text = config_stringize_errors(scratch, parsed); + if (error_text.str != 0){ + print_message(app, error_text); + } + } + else{ + print_message(app, string_u8_litexpr("Using default config:\n")); + Face_Description description = get_face_description(app, 0); + if (description.font.file_name.str != 0){ + umem size = min(description.font.file_name.size, sizeof(config->default_font_name_space)); + block_copy(config->default_font_name_space, description.font.file_name.str, size); + config->default_font_name.size = size; + } + } + + if (config->default_font_name.size == 0){ +#define M "liberation-mono.ttf" + block_copy(config->default_font_name_space, M, sizeof(M) - 1); + config->default_font_name.size = sizeof(M) - 1; +#undef M + } + + { + // Values + Temp_Memory temp2 = begin_temp(scratch); + List_String_Const_u8 list = {}; + + config_feedback_string(scratch, &list, "user_name", config->user_name); + config_feedback_extension_list(scratch, &list, "treat_as_code", &config->code_exts); + + config_feedback_string(scratch, &list, "mode", config->mode); + + config_feedback_bool(scratch, &list, "use_scroll_bars", config->use_scroll_bars); + config_feedback_bool(scratch, &list, "use_file_bars", config->use_file_bars); + config_feedback_bool(scratch, &list, "hide_file_bar_in_ui", config->hide_file_bar_in_ui); + config_feedback_bool(scratch, &list, "use_error_highlight", config->use_error_highlight); + config_feedback_bool(scratch, &list, "use_jump_highlight", config->use_jump_highlight); + config_feedback_bool(scratch, &list, "use_scope_highlight", config->use_scope_highlight); + config_feedback_bool(scratch, &list, "use_paren_helper", config->use_paren_helper); + config_feedback_bool(scratch, &list, "use_comment_keyword", config->use_comment_keyword); + config_feedback_bool(scratch, &list, "lister_whole_word_backspace_when_modified", config->lister_whole_word_backspace_when_modified); + config_feedback_bool(scratch, &list, "show_line_number_margins", config->show_line_number_margins); + + config_feedback_bool(scratch, &list, "enable_virtual_whitespace", config->enable_virtual_whitespace); + config_feedback_bool(scratch, &list, "enable_code_wrapping", config->enable_code_wrapping); + config_feedback_bool(scratch, &list, "automatically_indent_text_on_save", config->automatically_indent_text_on_save); + config_feedback_bool(scratch, &list, "automatically_save_changes_on_build", config->automatically_save_changes_on_build); + config_feedback_bool(scratch, &list, "automatically_adjust_wrapping", config->automatically_adjust_wrapping); + config_feedback_bool(scratch, &list, "automatically_load_project", config->automatically_load_project); + + config_feedback_bool(scratch, &list, "indent_with_tabs", config->indent_with_tabs); + config_feedback_int(scratch, &list, "indent_width", config->indent_width); + + config_feedback_int(scratch, &list, "default_wrap_width", config->default_wrap_width); + config_feedback_int(scratch, &list, "default_min_base_width", config->default_min_base_width); + + config_feedback_string(scratch, &list, "default_theme_name", config->default_theme_name); + config_feedback_bool(scratch, &list, "highlight_line_at_cursor", config->highlight_line_at_cursor); + + config_feedback_string(scratch, &list, "default_font_name", config->default_font_name); + config_feedback_int(scratch, &list, "default_font_size", config->default_font_size); + config_feedback_bool(scratch, &list, "default_font_hinting", config->default_font_hinting); + + config_feedback_string(scratch, &list, "default_compiler_bat", config->default_compiler_bat); + config_feedback_string(scratch, &list, "default_flags_bat", config->default_flags_bat); + config_feedback_string(scratch, &list, "default_compiler_sh", config->default_compiler_sh); + config_feedback_string(scratch, &list, "default_flags_sh", config->default_flags_sh); + + config_feedback_bool(scratch, &list, "lalt_lctrl_is_altgr", config->lalt_lctrl_is_altgr); + + string_list_push_u8_lit(scratch, &list, "\n"); + String_Const_u8 message = string_list_flatten(scratch, list); + print_message(app, message); + end_temp(temp2); + } + + // Apply config + change_mode(app, config->mode); + global_set_setting(app, GlobalSetting_LAltLCtrlIsAltGr, config->lalt_lctrl_is_altgr); + + //change_theme(app, config->default_theme_name.str, config->default_theme_name.size); + + Face_Description description = {}; + description.font.file_name = config->default_font_name; + if (override_font_size != 0){ + description.parameters.pt_size = override_font_size; + } + else{ + description.parameters.pt_size = config->default_font_size; + } + description.parameters.hinting = config->default_font_hinting || override_hinting; + description.font.in_4coder_font_folder = true; + if (!modify_global_face_by_description(app, description)){ + description.font.in_4coder_font_folder = false; + modify_global_face_by_description(app, description); + } +} + +#if 0 +function void +load_theme_file_into_live_set(Application_Links *app, Partition *scratch, char *file_name){ + Temp_Memory temp = begin_temp_memory(scratch); + Theme_Data theme = {}; + Config *config = theme_parse__file_name(app, scratch, file_name, &theme); + String error_text = config_stringize_errors(scratch, config); + print_message(app, error_text.str, error_text.size); + end_temp_memory(temp); + create_theme(app, &theme.theme, theme.name.str, theme.name.size); +} + +function void +load_folder_of_themes_into_live_set(Application_Links *app, Partition *scratch, + char *folder_name){ + char path_space[512]; + String path = make_fixed_width_string(path_space); + path.size = get_4ed_path(app, path_space, sizeof(path_space)); + append(&path, folder_name); + + if (path.size < path.memory_size){ + File_List list = get_file_list(app, path.str, path.size); + for (u32 i = 0; i < list.count; ++i){ + File_Info *info = &list.infos[i]; + if (info->folder){ + continue; + } + String info_file_name = make_string(info->filename, info->filename_len); + char file_name_space[512]; + String file_name = make_fixed_width_string(file_name_space); + copy(&file_name, path); + append(&file_name, "/"); + append(&file_name, info_file_name); + if (terminate_with_null(&file_name)){ + load_theme_file_into_live_set(app, scratch, file_name.str); + } + } + free_file_list(app, list); + } +} +#endif + +// BOTTOM + diff --git a/custom/4coder_default_bindings.cpp b/custom/4coder_default_bindings.cpp index 7619a89b..d636362f 100644 --- a/custom/4coder_default_bindings.cpp +++ b/custom/4coder_default_bindings.cpp @@ -19,6 +19,7 @@ custom_layer_init(Application_Links *app){ mapping_init(tctx, &framework_mapping); setup_default_mapping(&framework_mapping); global_prof_init(); + async_task_handler_init(app); } #endif diff --git a/custom/4coder_default_framework.cpp b/custom/4coder_default_framework.cpp index 708391c5..44c18e5d 100644 --- a/custom/4coder_default_framework.cpp +++ b/custom/4coder_default_framework.cpp @@ -453,6 +453,7 @@ default_4coder_initialize(Application_Links *app, String_Const_u8_Array file_nam buffer_map_id = managed_id_declare(app, SCu8("DEFAULT.buffer_map_id" )); buffer_eol_setting = managed_id_declare(app, SCu8("DEFAULT.buffer_eol_setting")); + buffer_lex_task = managed_id_declare(app, SCu8("DEFAULT.buffer_lex_task")); sticky_jump_marker_handle = managed_id_declare(app, SCu8("DEFAULT.sticky_jump_marker_handle")); attachment_tokens = managed_id_declare(app, SCu8("DEFAULT.tokens")); diff --git a/custom/4coder_default_framework_variables.cpp b/custom/4coder_default_framework_variables.cpp index 455fd789..61f538b5 100644 --- a/custom/4coder_default_framework_variables.cpp +++ b/custom/4coder_default_framework_variables.cpp @@ -44,6 +44,7 @@ global Managed_ID view_call_next = 0; global Managed_ID buffer_map_id = 0; global Managed_ID buffer_eol_setting = 0; +global Managed_ID buffer_lex_task = 0; global Managed_ID sticky_jump_marker_handle = 0; diff --git a/custom/4coder_default_hooks.cpp b/custom/4coder_default_hooks.cpp index 5a4efa5a..bc883130 100644 --- a/custom/4coder_default_hooks.cpp +++ b/custom/4coder_default_hooks.cpp @@ -92,7 +92,7 @@ CUSTOM_DOC("Input consumption loop for default view behavior") Managed_Scope scope = view_get_managed_scope(app, view); Custom_Command_Function** next_call = 0; - + call_again: next_call = scope_attachment(app, scope, view_call_next, Custom_Command_Function*); *next_call = 0; @@ -539,11 +539,17 @@ BUFFER_NAME_RESOLVER_SIG(default_buffer_name_resolution){ } function void -do_full_lex(Application_Links *app, Buffer_ID buffer_id){ - Scratch_Block scratch(app); +do_full_lex_async__inner(Application_Links *app, Buffer_ID buffer_id){ + Thread_Context *tctx = get_thread_context(app); + Scratch_Block scratch(tctx); + + system_acquire_global_frame_mutex(tctx); String_Const_u8 contents = push_whole_buffer(app, scratch, buffer_id); + system_release_global_frame_mutex(tctx); + Token_List list = lex_full_input_cpp(scratch, contents); + system_acquire_global_frame_mutex(tctx); Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); Base_Allocator *allocator = managed_scope_allocator(app, scope); Token_Array tokens = {}; @@ -554,6 +560,15 @@ do_full_lex(Application_Links *app, Buffer_ID buffer_id){ Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, Token_Array); block_copy_struct(tokens_ptr, &tokens); + system_release_global_frame_mutex(tctx); +} + +function void +do_full_lex_async(Application_Links *app, Data data){ + if (data.size == sizeof(Buffer_ID)){ + Buffer_ID buffer = *(Buffer_ID*)data.data; + do_full_lex_async__inner(app, buffer); + } } BUFFER_HOOK_SIG(default_begin_buffer){ @@ -643,6 +658,7 @@ BUFFER_HOOK_SIG(default_begin_buffer){ first_call = false; buffer_map_id = managed_id_declare(app, SCu8("DEFAULT.buffer_map_id")); buffer_eol_setting = managed_id_declare(app, SCu8("DEFAULT.buffer_eol_setting")); + buffer_lex_task = managed_id_declare(app, SCu8("DEFAULT.buffer_lex_task")); } Command_Map_ID map_id = (treat_as_code)?(default_code_map):(mapid_file); @@ -672,10 +688,11 @@ BUFFER_HOOK_SIG(default_begin_buffer){ } if (use_lexer){ - do_full_lex(app, buffer_id); + Async_Task lex_task = async_task_no_dep(do_full_lex_async, make_data_struct(&buffer_id)); + Async_Task *lex_task_ptr = scope_attachment(app, scope, buffer_lex_task, Async_Task); + *lex_task_ptr = lex_task; } - // no meaning for return return(0); } @@ -778,7 +795,9 @@ BUFFER_EDIT_RANGE_SIG(default_buffer_edit_range){ else{ scratch.restore(); base_free(allocator, ptr->tokens); - do_full_lex(app, buffer_id); + Async_Task lex_task = async_task_no_dep(do_full_lex_async, make_data_struct(&buffer_id)); + Async_Task *lex_task_ptr = scope_attachment(app, scope, buffer_lex_task, Async_Task); + *lex_task_ptr = lex_task; } #if 0 diff --git a/custom/4coder_default_include.cpp b/custom/4coder_default_include.cpp index aee98a20..85d89273 100644 --- a/custom/4coder_default_include.cpp +++ b/custom/4coder_default_include.cpp @@ -26,6 +26,7 @@ #include "4coder_system_allocator.cpp" #include "4coder_profile.h" +#include "4coder_async_tasks.h" #include "4coder_token.h" #include "generated/lexer_cpp.h" #include "4coder_string_match.h" @@ -64,6 +65,7 @@ #include "4coder_log.cpp" #include "4coder_hash_functions.cpp" #include "4coder_table.cpp" +#include "4coder_async_tasks.cpp" #include "4coder_string_match.cpp" #include "4coder_buffer_seek_constructors.cpp" diff --git a/custom/4coder_profile_inspect.cpp b/custom/4coder_profile_inspect.cpp index 9b75b925..e64636ee 100644 --- a/custom/4coder_profile_inspect.cpp +++ b/custom/4coder_profile_inspect.cpp @@ -85,8 +85,6 @@ profile_parse_record(Arena *arena, Profile_Inspection *insp, slot = profile_parse_get_slot(arena, insp, location, name); } else if (record->id == id){ - String_Const_u8 close_location = record->location; - String_Const_u8 close_name = record->name; slot = profile_parse_get_slot(arena, insp, location, name); node->time.max = record->time; node->closed = true; diff --git a/custom/4coder_types.h b/custom/4coder_types.h index f16f2c48..07403dae 100644 --- a/custom/4coder_types.h +++ b/custom/4coder_types.h @@ -15,6 +15,7 @@ struct Application_Links{ void *cmd_context; + void *current_thread; void *current_coroutine; i32 type_coroutine; }; @@ -373,14 +374,14 @@ STRUCT Theme_Color{ //int_color colors[Stag_COUNT]; //}; -TYPEDEF u32 Face_ID; +typedef u32 Face_ID; -STRUCT Font_Load_Location{ +struct Font_Load_Location{ String_Const_u8 file_name; b32 in_4coder_font_folder; }; -STRUCT Face_Load_Parameters{ +struct Face_Load_Parameters{ u32 pt_size; b32 bold; b32 italic; @@ -388,7 +389,7 @@ STRUCT Face_Load_Parameters{ b32 hinting; }; -STRUCT Face_Description{ +struct Face_Description{ Font_Load_Location font; Face_Load_Parameters parameters; }; diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index a43cec1c..3772485e 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -233,217 +233,217 @@ i32 source_name_len; i32 line_number; }; static Command_Metadata fcoder_metacmd_table[211] = { -{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "c:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 56 }, -{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "c:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 196 }, -{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "c:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 202 }, -{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "c:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 208 }, -{ PROC_LINKS(seek_beginning_of_textual_line, 0), false, "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "c:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2106 }, -{ PROC_LINKS(seek_end_of_textual_line, 0), false, "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "c:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2112 }, -{ PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "c:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2118 }, -{ PROC_LINKS(seek_end_of_line, 0), false, "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "c:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2124 }, -{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "c:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2130 }, -{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "c:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2138 }, -{ PROC_LINKS(change_active_panel, 0), false, "change_active_panel", 19, "Change the currently active panel, moving to the panel with the next highest view_id.", 85, "c:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 270 }, -{ PROC_LINKS(change_active_panel_backwards, 0), false, "change_active_panel_backwards", 29, "Change the currently active panel, moving to the panel with the next lowest view_id.", 84, "c:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 280 }, -{ PROC_LINKS(open_panel_vsplit, 0), false, "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "c:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 290 }, -{ PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "c:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 300 }, -{ PROC_LINKS(suppress_mouse, 0), false, "suppress_mouse", 14, "Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.", 83, "c:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 365 }, -{ PROC_LINKS(allow_mouse, 0), false, "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "c:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 371 }, -{ PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "c:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 377 }, -{ PROC_LINKS(set_mode_to_original, 0), false, "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "c:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 383 }, -{ PROC_LINKS(set_mode_to_notepad_like, 0), false, "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "c:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 389 }, -{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), false, "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "c:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 395 }, -{ PROC_LINKS(toggle_highlight_enclosing_scopes, 0), false, "toggle_highlight_enclosing_scopes", 33, "In code files scopes surrounding the cursor are highlighted with distinguishing colors.", 87, "c:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 401 }, -{ PROC_LINKS(toggle_paren_matching_helper, 0), false, "toggle_paren_matching_helper", 28, "In code files matching parentheses pairs are colored with distinguishing colors.", 80, "c:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 407 }, -{ PROC_LINKS(toggle_fullscreen, 0), false, "toggle_fullscreen", 17, "Toggle fullscreen mode on or off. The change(s) do not take effect until the next frame.", 89, "c:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 413 }, -{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever character was used to trigger this command.", 60, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 58 }, -{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts an underscore.", 22, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 66 }, -{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 72 }, -{ PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 78 }, -{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 95 }, -{ PROC_LINKS(set_mark, 0), false, "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 114 }, -{ PROC_LINKS(cursor_mark_swap, 0), false, "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 123 }, -{ PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 133 }, -{ PROC_LINKS(backspace_alpha_numeric_boundary, 0), false, "backspace_alpha_numeric_boundary", 32, "Delete characters between the cursor position and the first alphanumeric boundary to the left.", 94, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 153 }, -{ PROC_LINKS(delete_alpha_numeric_boundary, 0), false, "delete_alpha_numeric_boundary", 29, "Delete characters between the cursor position and the first alphanumeric boundary to the right.", 95, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 161 }, -{ PROC_LINKS(snipe_backward_whitespace_or_token_boundary, 0), false, "snipe_backward_whitespace_or_token_boundary", 43, "Delete a single, whole token on or to the left of the cursor and post it to the clipboard.", 90, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 181 }, -{ PROC_LINKS(snipe_forward_whitespace_or_token_boundary, 0), false, "snipe_forward_whitespace_or_token_boundary", 42, "Delete a single, whole token on or to the right of the cursor and post it to the clipboard.", 91, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 189 }, -{ PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 199 }, -{ PROC_LINKS(left_adjust_view, 0), false, "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 213 }, -{ PROC_LINKS(click_set_cursor_and_mark, 0), false, "click_set_cursor_and_mark", 25, "Sets the cursor position and mark to the mouse position.", 56, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 225 }, -{ PROC_LINKS(click_set_cursor, 0), false, "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 235 }, -{ PROC_LINKS(click_set_cursor_if_lbutton, 0), false, "click_set_cursor_if_lbutton", 27, "If the mouse left button is pressed, sets the cursor position to the mouse position.", 84, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 245 }, -{ PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 257 }, -{ PROC_LINKS(mouse_wheel_scroll, 0), false, "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 267 }, -{ PROC_LINKS(move_up, 0), false, "move_up", 7, "Moves the cursor up one line.", 29, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 321 }, -{ PROC_LINKS(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 327 }, -{ PROC_LINKS(move_up_10, 0), false, "move_up_10", 10, "Moves the cursor up ten lines.", 30, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 333 }, -{ PROC_LINKS(move_down_10, 0), false, "move_down_10", 12, "Moves the cursor down ten lines.", 32, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 339 }, -{ PROC_LINKS(move_down_textual, 0), false, "move_down_textual", 17, "Moves down to the next line of actual text, regardless of line wrapping.", 72, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 345 }, -{ PROC_LINKS(page_up, 0), false, "page_up", 7, "Scrolls the view up one view height and moves the cursor up one view height.", 76, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 355 }, -{ PROC_LINKS(page_down, 0), false, "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 363 }, -{ PROC_LINKS(move_up_to_blank_line, 0), false, "move_up_to_blank_line", 21, "Seeks the cursor up to the next blank line.", 43, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 393 }, -{ PROC_LINKS(move_down_to_blank_line, 0), false, "move_down_to_blank_line", 23, "Seeks the cursor down to the next blank line.", 45, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 399 }, -{ PROC_LINKS(move_up_to_blank_line_skip_whitespace, 0), false, "move_up_to_blank_line_skip_whitespace", 37, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 405 }, -{ PROC_LINKS(move_down_to_blank_line_skip_whitespace, 0), false, "move_down_to_blank_line_skip_whitespace", 39, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 411 }, -{ PROC_LINKS(move_up_to_blank_line_end, 0), false, "move_up_to_blank_line_end", 25, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 417 }, -{ PROC_LINKS(move_down_to_blank_line_end, 0), false, "move_down_to_blank_line_end", 27, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 423 }, -{ PROC_LINKS(move_left, 0), false, "move_left", 9, "Moves the cursor one character to the left.", 43, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 429 }, -{ PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 441 }, -{ PROC_LINKS(move_right_whitespace_boundary, 0), false, "move_right_whitespace_boundary", 30, "Seek right for the next boundary between whitespace and non-whitespace.", 71, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 463 }, -{ PROC_LINKS(move_left_whitespace_boundary, 0), false, "move_left_whitespace_boundary", 29, "Seek left for the next boundary between whitespace and non-whitespace.", 70, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 471 }, -{ PROC_LINKS(move_right_token_boundary, 0), false, "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 479 }, -{ PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 487 }, -{ PROC_LINKS(move_right_whitespace_or_token_boundary, 0), false, "move_right_whitespace_or_token_boundary", 39, "Seek right for the next end of a token or boundary between whitespace and non-whitespace.", 89, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 495 }, -{ PROC_LINKS(move_left_whitespace_or_token_boundary, 0), false, "move_left_whitespace_or_token_boundary", 38, "Seek left for the next end of a token or boundary between whitespace and non-whitespace.", 88, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 503 }, -{ PROC_LINKS(move_right_alpha_numeric_boundary, 0), false, "move_right_alpha_numeric_boundary", 33, "Seek right for boundary between alphanumeric characters and non-alphanumeric characters.", 88, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 511 }, -{ PROC_LINKS(move_left_alpha_numeric_boundary, 0), false, "move_left_alpha_numeric_boundary", 32, "Seek left for boundary between alphanumeric characters and non-alphanumeric characters.", 87, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 519 }, -{ PROC_LINKS(move_right_alpha_numeric_or_camel_boundary, 0), false, "move_right_alpha_numeric_or_camel_boundary", 42, "Seek right for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 107, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 527 }, -{ PROC_LINKS(move_left_alpha_numeric_or_camel_boundary, 0), false, "move_left_alpha_numeric_or_camel_boundary", 41, "Seek left for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 106, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 535 }, -{ PROC_LINKS(select_all, 0), false, "select_all", 10, "Puts the cursor at the top of the file, and the mark at the bottom of the file.", 79, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 545 }, -{ PROC_LINKS(to_uppercase, 0), false, "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 558 }, -{ PROC_LINKS(to_lowercase, 0), false, "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 571 }, -{ PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 584 }, -{ PROC_LINKS(basic_change_active_panel, 0), false, "basic_change_active_panel", 25, "Change the currently active panel, moving to the panel with the next highest view_id. Will not skipe the build panel if it is open.", 132, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 618 }, -{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 626 }, -{ PROC_LINKS(show_scrollbar, 0), false, "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 635 }, -{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 642 }, -{ PROC_LINKS(show_filebar, 0), false, "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 649 }, -{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 656 }, -{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 663 }, -{ PROC_LINKS(toggle_fps_meter, 0), false, "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 672 }, -{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 678 }, -{ PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 689 }, -{ PROC_LINKS(mouse_wheel_change_face_size, 0), false, "mouse_wheel_change_face_size", 28, "Reads the state of the mouse wheel and uses it to either increase or decrease the face size.", 92, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 700 }, -{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 717 }, -{ PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 726 }, -{ PROC_LINKS(toggle_line_numbers, 0), false, "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 735 }, -{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 741 }, -{ PROC_LINKS(goto_line, 0), false, "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 749 }, -{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 977 }, -{ PROC_LINKS(reverse_search, 0), false, "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 983 }, -{ PROC_LINKS(search_identifier, 0), false, "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 989 }, -{ PROC_LINKS(reverse_search_identifier, 0), false, "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 995 }, -{ PROC_LINKS(replace_in_range, 0), false, "replace_in_range", 16, "Queries the user for a needle and string. Replaces all occurences of needle with string in the range between cursor and the mark in the active buffer.", 150, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1042 }, -{ PROC_LINKS(replace_in_buffer, 0), false, "replace_in_buffer", 17, "Queries the user for a needle and string. Replaces all occurences of needle with string in the active buffer.", 109, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1051 }, -{ PROC_LINKS(replace_in_all_buffers, 0), false, "replace_in_all_buffers", 22, "Queries the user for a needle and string. Replaces all occurences of needle with string in all editable buffers.", 112, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1060 }, -{ PROC_LINKS(query_replace, 0), false, "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1150 }, -{ PROC_LINKS(query_replace_identifier, 0), false, "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1171 }, -{ PROC_LINKS(query_replace_selection, 0), false, "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1187 }, -{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1222 }, -{ PROC_LINKS(delete_file_query, 0), false, "delete_file_query", 17, "Deletes the file of the current buffer if 4coder has the appropriate access rights. Will ask the user for confirmation first.", 125, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1247 }, -{ PROC_LINKS(save_to_query, 0), false, "save_to_query", 13, "Queries the user for a file name and saves the contents of the current buffer, altering the buffer's name too.", 110, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1291 }, -{ PROC_LINKS(rename_file_query, 0), false, "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1324 }, -{ PROC_LINKS(make_directory_query, 0), false, "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1362 }, -{ PROC_LINKS(move_line_up, 0), false, "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1396 }, -{ PROC_LINKS(move_line_down, 0), false, "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1402 }, -{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1408 }, -{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1422 }, -{ PROC_LINKS(open_file_in_quotes, 0), false, "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1487 }, -{ PROC_LINKS(open_matching_file_cpp, 0), false, "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1519 }, -{ PROC_LINKS(view_buffer_other_panel, 0), false, "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1532 }, -{ PROC_LINKS(swap_buffers_between_panels, 0), false, "swap_buffers_between_panels", 27, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1544 }, -{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1578 }, -{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1586 }, -{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1596 }, -{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1825 }, -{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1838 }, -{ PROC_LINKS(undo_all_buffers, 0), false, "undo_all_buffers", 16, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1852 }, -{ PROC_LINKS(redo_all_buffers, 0), false, "redo_all_buffers", 16, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1923 }, -{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 2024 }, -{ PROC_LINKS(default_file_externally_modified, 0), false, "default_file_externally_modified", 32, "Notes the external modification of attached files by printing a message.", 72, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 2031 }, -{ PROC_LINKS(set_eol_mode_to_crlf, 0), false, "set_eol_mode_to_crlf", 20, "Puts the buffer in crlf line ending mode.", 41, "c:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 80 }, -{ PROC_LINKS(set_eol_mode_to_lf, 0), false, "set_eol_mode_to_lf", 18, "Puts the buffer in lf line ending mode.", 39, "c:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 91 }, -{ PROC_LINKS(set_eol_mode_to_binary, 0), false, "set_eol_mode_to_binary", 22, "Puts the buffer in bin line ending mode.", 40, "c:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 102 }, -{ PROC_LINKS(set_eol_mode_from_contents, 0), false, "set_eol_mode_from_contents", 26, "Sets the buffer's line ending mode to match the contents of the buffer.", 71, "c:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 113 }, -{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "c:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 477 }, -{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "c:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 496 }, -{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "c:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 567 }, -{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "c:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 606 }, -{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "c:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 639 }, -{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "c:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 702 }, -{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "c:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 356 }, -{ PROC_LINKS(auto_indent_line_at_cursor, 0), false, "auto_indent_line_at_cursor", 26, "Auto-indents the line on which the cursor sits.", 47, "c:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 365 }, -{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "c:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 375 }, -{ PROC_LINKS(write_text_and_auto_indent, 0), false, "write_text_and_auto_indent", 26, "Inserts text and auto-indents the line on which the cursor sits if any of the text contains 'layout punctuation' such as ;:{}()[]# and new lines.", 145, "c:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 385 }, -{ PROC_LINKS(list_all_locations, 0), false, "list_all_locations", 18, "Queries the user for a string and lists all exact case-sensitive matches found in all open buffers.", 99, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 166 }, -{ PROC_LINKS(list_all_substring_locations, 0), false, "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 172 }, -{ PROC_LINKS(list_all_locations_case_insensitive, 0), false, "list_all_locations_case_insensitive", 35, "Queries the user for a string and lists all exact case-insensitive matches found in all open buffers.", 101, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 178 }, -{ PROC_LINKS(list_all_substring_locations_case_insensitive, 0), false, "list_all_substring_locations_case_insensitive", 45, "Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.", 105, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 184 }, -{ PROC_LINKS(list_all_locations_of_identifier, 0), false, "list_all_locations_of_identifier", 32, "Reads a token or word under the cursor and lists all exact case-sensitive mathces in all open buffers.", 102, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 190 }, -{ PROC_LINKS(list_all_locations_of_identifier_case_insensitive, 0), false, "list_all_locations_of_identifier_case_insensitive", 49, "Reads a token or word under the cursor and lists all exact case-insensitive mathces in all open buffers.", 104, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 196 }, -{ PROC_LINKS(list_all_locations_of_selection, 0), false, "list_all_locations_of_selection", 31, "Reads the string in the selected range and lists all exact case-sensitive mathces in all open buffers.", 102, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 202 }, -{ PROC_LINKS(list_all_locations_of_selection_case_insensitive, 0), false, "list_all_locations_of_selection_case_insensitive", 48, "Reads the string in the selected range and lists all exact case-insensitive mathces in all open buffers.", 104, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 208 }, -{ PROC_LINKS(list_all_locations_of_type_definition, 0), false, "list_all_locations_of_type_definition", 37, "Queries user for string, lists all locations of strings that appear to define a type whose name matches the input string.", 121, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 214 }, -{ PROC_LINKS(list_all_locations_of_type_definition_of_identifier, 0), false, "list_all_locations_of_type_definition_of_identifier", 51, "Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it.", 125, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 222 }, -{ PROC_LINKS(word_complete, 0), false, "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 391 }, -{ PROC_LINKS(goto_jump_at_cursor, 0), false, "goto_jump_at_cursor", 19, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 346 }, -{ PROC_LINKS(goto_jump_at_cursor_same_panel, 0), false, "goto_jump_at_cursor_same_panel", 30, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.", 167, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 373 }, -{ PROC_LINKS(goto_next_jump, 0), false, "goto_next_jump", 14, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 462 }, -{ PROC_LINKS(goto_prev_jump, 0), false, "goto_prev_jump", 14, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 479 }, -{ PROC_LINKS(goto_next_jump_no_skips, 0), false, "goto_next_jump_no_skips", 23, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 492 }, -{ PROC_LINKS(goto_prev_jump_no_skips, 0), false, "goto_prev_jump_no_skips", 23, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 509 }, -{ PROC_LINKS(goto_first_jump, 0), false, "goto_first_jump", 15, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 523 }, -{ PROC_LINKS(goto_first_jump_same_panel_sticky, 0), false, "goto_first_jump_same_panel_sticky", 33, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer and views the buffer in the panel where the jump list was.", 153, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 540 }, -{ PROC_LINKS(if_read_only_goto_position, 0), false, "if_read_only_goto_position", 26, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 562 }, -{ PROC_LINKS(if_read_only_goto_position_same_panel, 0), false, "if_read_only_goto_position_same_panel", 37, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 579 }, -{ PROC_LINKS(view_jump_list_with_lister, 0), false, "view_jump_list_with_lister", 26, "When executed on a buffer with jumps, creates a persistent lister for all the jumps", 83, "c:\\4ed\\code\\custom\\4coder_jump_lister.cpp", 41, 104 }, -{ PROC_LINKS(show_the_log_graph, 0), true, "show_the_log_graph", 18, "Parses *log* and displays the 'log graph' UI", 44, "c:\\4ed\\code\\custom\\4coder_log_parser.cpp", 40, 990 }, -{ PROC_LINKS(copy, 0), false, "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "c:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 19 }, -{ PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "c:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 28 }, -{ PROC_LINKS(paste, 0), false, "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "c:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 39 }, -{ PROC_LINKS(paste_next, 0), false, "paste_next", 10, "If the previous command was paste or paste_next, replaces the paste range with the next text down on the clipboard, otherwise operates as the paste command.", 156, "c:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 73 }, -{ PROC_LINKS(paste_and_indent, 0), false, "paste_and_indent", 16, "Paste from the top of clipboard and run auto-indent on the newly pasted text.", 77, "c:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 115 }, -{ PROC_LINKS(paste_next_and_indent, 0), false, "paste_next_and_indent", 21, "Paste the next item on the clipboard and run auto-indent on the newly pasted text.", 82, "c:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 122 }, -{ PROC_LINKS(execute_previous_cli, 0), false, "execute_previous_cli", 20, "If the command execute_any_cli has already been used, this will execute a CLI reusing the most recent buffer name and command.", 126, "c:\\4ed\\code\\custom\\4coder_cli_command.cpp", 41, 7 }, -{ PROC_LINKS(execute_any_cli, 0), false, "execute_any_cli", 15, "Queries for an output buffer name and system command, runs the system command as a CLI and prints the output to the specified buffer.", 133, "c:\\4ed\\code\\custom\\4coder_cli_command.cpp", 41, 22 }, -{ PROC_LINKS(build_search, 0), false, "build_search", 12, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*.", 153, "c:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 128 }, -{ PROC_LINKS(build_in_build_panel, 0), false, "build_in_build_panel", 20, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. Puts the *compilation* buffer in a panel at the footer of the current view.", 230, "c:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 163 }, -{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "c:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 178 }, -{ PROC_LINKS(change_to_build_panel, 0), false, "change_to_build_panel", 21, "If the special build panel is open, makes the build panel the active panel.", 75, "c:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 184 }, -{ PROC_LINKS(close_all_code, 0), false, "close_all_code", 14, "Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.", 107, "c:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 917 }, -{ PROC_LINKS(open_all_code, 0), false, "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "c:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 923 }, -{ PROC_LINKS(open_all_code_recursive, 0), false, "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "c:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 929 }, -{ PROC_LINKS(load_project, 0), false, "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "c:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 937 }, -{ PROC_LINKS(project_fkey_command, 0), false, "project_fkey_command", 20, "Run an 'fkey command' configured in a project.4coder file. Determines the index of the 'fkey command' by which function key or numeric key was pressed to trigger the command.", 175, "c:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 944 }, -{ PROC_LINKS(project_go_to_root_directory, 0), false, "project_go_to_root_directory", 28, "Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns.", 125, "c:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 969 }, -{ PROC_LINKS(setup_new_project, 0), false, "setup_new_project", 17, "Queries the user for several configuration options and initializes a new 4coder project with build scripts for every OS.", 120, "c:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1303 }, -{ PROC_LINKS(setup_build_bat, 0), false, "setup_build_bat", 15, "Queries the user for several configuration options and initializes a new build batch script.", 92, "c:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1310 }, -{ PROC_LINKS(setup_build_sh, 0), false, "setup_build_sh", 14, "Queries the user for several configuration options and initializes a new build shell script.", 92, "c:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1316 }, -{ PROC_LINKS(setup_build_bat_and_sh, 0), false, "setup_build_bat_and_sh", 22, "Queries the user for several configuration options and initializes a new build batch script.", 92, "c:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1322 }, -{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "c:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1338 }, -{ PROC_LINKS(list_all_functions_current_buffer, 0), false, "list_all_functions_current_buffer", 33, "Creates a jump list of lines of the current buffer that appear to define or declare functions.", 94, "c:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 267 }, -{ PROC_LINKS(list_all_functions_current_buffer_lister, 0), false, "list_all_functions_current_buffer_lister", 40, "Creates a lister of locations that look like function definitions and declarations in the buffer.", 97, "c:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 277 }, -{ PROC_LINKS(list_all_functions_all_buffers, 0), false, "list_all_functions_all_buffers", 30, "Creates a jump list of lines from all buffers that appear to define or declare functions.", 89, "c:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 289 }, -{ PROC_LINKS(list_all_functions_all_buffers_lister, 0), false, "list_all_functions_all_buffers_lister", 37, "Creates a lister of locations that look like function definitions and declarations all buffers.", 95, "c:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 295 }, -{ PROC_LINKS(select_surrounding_scope, 0), false, "select_surrounding_scope", 24, "Finds the scope enclosed by '{' '}' surrounding the cursor and puts the cursor and mark on the '{' and '}'.", 107, "c:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 7 }, -{ PROC_LINKS(select_next_scope_absolute, 0), false, "select_next_scope_absolute", 26, "Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.", 102, "c:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 32 }, -{ PROC_LINKS(select_next_scope_after_current, 0), false, "select_next_scope_after_current", 31, "Finds the first scope started by '{' after the mark and puts the cursor and mark on the '{' and '}'. This command is meant to be used after a scope is already selected so that it will have the effect of selecting the next scope after the current scope.", 253, "c:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 41 }, -{ PROC_LINKS(select_prev_scope_absolute, 0), false, "select_prev_scope_absolute", 26, "Finds the first scope started by '{' before the cursor and puts the cursor and mark on the '{' and '}'.", 103, "c:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 50 }, -{ PROC_LINKS(place_in_scope, 0), false, "place_in_scope", 14, "Wraps the code contained in the range between cursor and mark with a new curly brace scope.", 91, "c:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 67 }, -{ PROC_LINKS(delete_current_scope, 0), false, "delete_current_scope", 20, "Deletes the braces surrounding the currently selected scope. Leaves the contents within the scope.", 99, "c:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 73 }, -{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "c:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 46 }, -{ PROC_LINKS(open_long_braces_semicolon, 0), false, "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "c:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 54 }, -{ PROC_LINKS(open_long_braces_break, 0), false, "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "c:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 62 }, -{ PROC_LINKS(if0_off, 0), false, "if0_off", 7, "Surround the range between the cursor and mark with an '#if 0' and an '#endif'", 78, "c:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 70 }, -{ PROC_LINKS(write_todo, 0), false, "write_todo", 10, "At the cursor, insert a '// TODO' comment, includes user name if it was specified in config.4coder.", 99, "c:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 76 }, -{ PROC_LINKS(write_hack, 0), false, "write_hack", 10, "At the cursor, insert a '// HACK' comment, includes user name if it was specified in config.4coder.", 99, "c:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 82 }, -{ PROC_LINKS(write_note, 0), false, "write_note", 10, "At the cursor, insert a '// NOTE' comment, includes user name if it was specified in config.4coder.", 99, "c:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 88 }, -{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "c:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 94 }, -{ PROC_LINKS(write_zero_struct, 0), false, "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "c:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 100 }, -{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "c:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 125 }, -{ PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "c:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 137 }, -{ PROC_LINKS(comment_line_toggle, 0), false, "comment_line_toggle", 19, "Turns uncommented lines into commented lines and vice versa for comments starting with '//'.", 92, "c:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 149 }, -{ PROC_LINKS(snippet_lister, 0), false, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "c:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 231 }, -{ PROC_LINKS(miblo_increment_basic, 0), false, "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "c:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 29 }, -{ PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "c:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 44 }, -{ PROC_LINKS(miblo_increment_time_stamp, 0), false, "miblo_increment_time_stamp", 26, "Increment a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "c:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 231 }, -{ PROC_LINKS(miblo_decrement_time_stamp, 0), false, "miblo_decrement_time_stamp", 26, "Decrement a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "c:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 237 }, -{ PROC_LINKS(miblo_increment_time_stamp_minute, 0), false, "miblo_increment_time_stamp_minute", 33, "Increment a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "c:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 243 }, -{ PROC_LINKS(miblo_decrement_time_stamp_minute, 0), false, "miblo_decrement_time_stamp_minute", 33, "Decrement a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "c:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 249 }, -{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "c:\\4ed\\code\\custom\\4coder_profile_inspect.cpp", 45, 377 }, -{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "c:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 7 }, -{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "c:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 21 }, +{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 56 }, +{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 196 }, +{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 202 }, +{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 208 }, +{ PROC_LINKS(seek_beginning_of_textual_line, 0), false, "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2106 }, +{ PROC_LINKS(seek_end_of_textual_line, 0), false, "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2112 }, +{ PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2118 }, +{ PROC_LINKS(seek_end_of_line, 0), false, "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2124 }, +{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2130 }, +{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2138 }, +{ PROC_LINKS(change_active_panel, 0), false, "change_active_panel", 19, "Change the currently active panel, moving to the panel with the next highest view_id.", 85, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 270 }, +{ PROC_LINKS(change_active_panel_backwards, 0), false, "change_active_panel_backwards", 29, "Change the currently active panel, moving to the panel with the next lowest view_id.", 84, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 280 }, +{ PROC_LINKS(open_panel_vsplit, 0), false, "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 290 }, +{ PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 300 }, +{ PROC_LINKS(suppress_mouse, 0), false, "suppress_mouse", 14, "Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.", 83, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 365 }, +{ PROC_LINKS(allow_mouse, 0), false, "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 371 }, +{ PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 377 }, +{ PROC_LINKS(set_mode_to_original, 0), false, "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 383 }, +{ PROC_LINKS(set_mode_to_notepad_like, 0), false, "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 389 }, +{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), false, "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 395 }, +{ PROC_LINKS(toggle_highlight_enclosing_scopes, 0), false, "toggle_highlight_enclosing_scopes", 33, "In code files scopes surrounding the cursor are highlighted with distinguishing colors.", 87, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 401 }, +{ PROC_LINKS(toggle_paren_matching_helper, 0), false, "toggle_paren_matching_helper", 28, "In code files matching parentheses pairs are colored with distinguishing colors.", 80, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 407 }, +{ PROC_LINKS(toggle_fullscreen, 0), false, "toggle_fullscreen", 17, "Toggle fullscreen mode on or off. The change(s) do not take effect until the next frame.", 89, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 413 }, +{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever character was used to trigger this command.", 60, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 58 }, +{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts an underscore.", 22, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 66 }, +{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 72 }, +{ PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 78 }, +{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 95 }, +{ PROC_LINKS(set_mark, 0), false, "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 114 }, +{ PROC_LINKS(cursor_mark_swap, 0), false, "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 123 }, +{ PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 133 }, +{ PROC_LINKS(backspace_alpha_numeric_boundary, 0), false, "backspace_alpha_numeric_boundary", 32, "Delete characters between the cursor position and the first alphanumeric boundary to the left.", 94, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 153 }, +{ PROC_LINKS(delete_alpha_numeric_boundary, 0), false, "delete_alpha_numeric_boundary", 29, "Delete characters between the cursor position and the first alphanumeric boundary to the right.", 95, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 161 }, +{ PROC_LINKS(snipe_backward_whitespace_or_token_boundary, 0), false, "snipe_backward_whitespace_or_token_boundary", 43, "Delete a single, whole token on or to the left of the cursor and post it to the clipboard.", 90, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 181 }, +{ PROC_LINKS(snipe_forward_whitespace_or_token_boundary, 0), false, "snipe_forward_whitespace_or_token_boundary", 42, "Delete a single, whole token on or to the right of the cursor and post it to the clipboard.", 91, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 189 }, +{ PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 199 }, +{ PROC_LINKS(left_adjust_view, 0), false, "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 213 }, +{ PROC_LINKS(click_set_cursor_and_mark, 0), false, "click_set_cursor_and_mark", 25, "Sets the cursor position and mark to the mouse position.", 56, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 225 }, +{ PROC_LINKS(click_set_cursor, 0), false, "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 235 }, +{ PROC_LINKS(click_set_cursor_if_lbutton, 0), false, "click_set_cursor_if_lbutton", 27, "If the mouse left button is pressed, sets the cursor position to the mouse position.", 84, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 245 }, +{ PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 257 }, +{ PROC_LINKS(mouse_wheel_scroll, 0), false, "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 267 }, +{ PROC_LINKS(move_up, 0), false, "move_up", 7, "Moves the cursor up one line.", 29, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 321 }, +{ PROC_LINKS(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 327 }, +{ PROC_LINKS(move_up_10, 0), false, "move_up_10", 10, "Moves the cursor up ten lines.", 30, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 333 }, +{ PROC_LINKS(move_down_10, 0), false, "move_down_10", 12, "Moves the cursor down ten lines.", 32, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 339 }, +{ PROC_LINKS(move_down_textual, 0), false, "move_down_textual", 17, "Moves down to the next line of actual text, regardless of line wrapping.", 72, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 345 }, +{ PROC_LINKS(page_up, 0), false, "page_up", 7, "Scrolls the view up one view height and moves the cursor up one view height.", 76, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 355 }, +{ PROC_LINKS(page_down, 0), false, "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 363 }, +{ PROC_LINKS(move_up_to_blank_line, 0), false, "move_up_to_blank_line", 21, "Seeks the cursor up to the next blank line.", 43, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 393 }, +{ PROC_LINKS(move_down_to_blank_line, 0), false, "move_down_to_blank_line", 23, "Seeks the cursor down to the next blank line.", 45, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 399 }, +{ PROC_LINKS(move_up_to_blank_line_skip_whitespace, 0), false, "move_up_to_blank_line_skip_whitespace", 37, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 405 }, +{ PROC_LINKS(move_down_to_blank_line_skip_whitespace, 0), false, "move_down_to_blank_line_skip_whitespace", 39, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 411 }, +{ PROC_LINKS(move_up_to_blank_line_end, 0), false, "move_up_to_blank_line_end", 25, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 417 }, +{ PROC_LINKS(move_down_to_blank_line_end, 0), false, "move_down_to_blank_line_end", 27, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 423 }, +{ PROC_LINKS(move_left, 0), false, "move_left", 9, "Moves the cursor one character to the left.", 43, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 429 }, +{ PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 441 }, +{ PROC_LINKS(move_right_whitespace_boundary, 0), false, "move_right_whitespace_boundary", 30, "Seek right for the next boundary between whitespace and non-whitespace.", 71, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 463 }, +{ PROC_LINKS(move_left_whitespace_boundary, 0), false, "move_left_whitespace_boundary", 29, "Seek left for the next boundary between whitespace and non-whitespace.", 70, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 471 }, +{ PROC_LINKS(move_right_token_boundary, 0), false, "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 479 }, +{ PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 487 }, +{ PROC_LINKS(move_right_whitespace_or_token_boundary, 0), false, "move_right_whitespace_or_token_boundary", 39, "Seek right for the next end of a token or boundary between whitespace and non-whitespace.", 89, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 495 }, +{ PROC_LINKS(move_left_whitespace_or_token_boundary, 0), false, "move_left_whitespace_or_token_boundary", 38, "Seek left for the next end of a token or boundary between whitespace and non-whitespace.", 88, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 503 }, +{ PROC_LINKS(move_right_alpha_numeric_boundary, 0), false, "move_right_alpha_numeric_boundary", 33, "Seek right for boundary between alphanumeric characters and non-alphanumeric characters.", 88, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 511 }, +{ PROC_LINKS(move_left_alpha_numeric_boundary, 0), false, "move_left_alpha_numeric_boundary", 32, "Seek left for boundary between alphanumeric characters and non-alphanumeric characters.", 87, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 519 }, +{ PROC_LINKS(move_right_alpha_numeric_or_camel_boundary, 0), false, "move_right_alpha_numeric_or_camel_boundary", 42, "Seek right for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 107, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 527 }, +{ PROC_LINKS(move_left_alpha_numeric_or_camel_boundary, 0), false, "move_left_alpha_numeric_or_camel_boundary", 41, "Seek left for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 106, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 535 }, +{ PROC_LINKS(select_all, 0), false, "select_all", 10, "Puts the cursor at the top of the file, and the mark at the bottom of the file.", 79, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 545 }, +{ PROC_LINKS(to_uppercase, 0), false, "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 558 }, +{ PROC_LINKS(to_lowercase, 0), false, "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 571 }, +{ PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 584 }, +{ PROC_LINKS(basic_change_active_panel, 0), false, "basic_change_active_panel", 25, "Change the currently active panel, moving to the panel with the next highest view_id. Will not skipe the build panel if it is open.", 132, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 618 }, +{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 626 }, +{ PROC_LINKS(show_scrollbar, 0), false, "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 635 }, +{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 642 }, +{ PROC_LINKS(show_filebar, 0), false, "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 649 }, +{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 656 }, +{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 663 }, +{ PROC_LINKS(toggle_fps_meter, 0), false, "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 672 }, +{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 678 }, +{ PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 689 }, +{ PROC_LINKS(mouse_wheel_change_face_size, 0), false, "mouse_wheel_change_face_size", 28, "Reads the state of the mouse wheel and uses it to either increase or decrease the face size.", 92, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 700 }, +{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 717 }, +{ PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 726 }, +{ PROC_LINKS(toggle_line_numbers, 0), false, "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 735 }, +{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 741 }, +{ PROC_LINKS(goto_line, 0), false, "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 749 }, +{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 977 }, +{ PROC_LINKS(reverse_search, 0), false, "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 983 }, +{ PROC_LINKS(search_identifier, 0), false, "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 989 }, +{ PROC_LINKS(reverse_search_identifier, 0), false, "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 995 }, +{ PROC_LINKS(replace_in_range, 0), false, "replace_in_range", 16, "Queries the user for a needle and string. Replaces all occurences of needle with string in the range between cursor and the mark in the active buffer.", 150, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1042 }, +{ PROC_LINKS(replace_in_buffer, 0), false, "replace_in_buffer", 17, "Queries the user for a needle and string. Replaces all occurences of needle with string in the active buffer.", 109, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1051 }, +{ PROC_LINKS(replace_in_all_buffers, 0), false, "replace_in_all_buffers", 22, "Queries the user for a needle and string. Replaces all occurences of needle with string in all editable buffers.", 112, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1060 }, +{ PROC_LINKS(query_replace, 0), false, "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1150 }, +{ PROC_LINKS(query_replace_identifier, 0), false, "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1171 }, +{ PROC_LINKS(query_replace_selection, 0), false, "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1187 }, +{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1222 }, +{ PROC_LINKS(delete_file_query, 0), false, "delete_file_query", 17, "Deletes the file of the current buffer if 4coder has the appropriate access rights. Will ask the user for confirmation first.", 125, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1247 }, +{ PROC_LINKS(save_to_query, 0), false, "save_to_query", 13, "Queries the user for a file name and saves the contents of the current buffer, altering the buffer's name too.", 110, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1291 }, +{ PROC_LINKS(rename_file_query, 0), false, "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1324 }, +{ PROC_LINKS(make_directory_query, 0), false, "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1362 }, +{ PROC_LINKS(move_line_up, 0), false, "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1396 }, +{ PROC_LINKS(move_line_down, 0), false, "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1402 }, +{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1408 }, +{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1422 }, +{ PROC_LINKS(open_file_in_quotes, 0), false, "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1487 }, +{ PROC_LINKS(open_matching_file_cpp, 0), false, "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1519 }, +{ PROC_LINKS(view_buffer_other_panel, 0), false, "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1532 }, +{ PROC_LINKS(swap_buffers_between_panels, 0), false, "swap_buffers_between_panels", 27, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1544 }, +{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1578 }, +{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1586 }, +{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1596 }, +{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1825 }, +{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1838 }, +{ PROC_LINKS(undo_all_buffers, 0), false, "undo_all_buffers", 16, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1852 }, +{ PROC_LINKS(redo_all_buffers, 0), false, "redo_all_buffers", 16, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1923 }, +{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 2024 }, +{ PROC_LINKS(default_file_externally_modified, 0), false, "default_file_externally_modified", 32, "Notes the external modification of attached files by printing a message.", 72, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 2031 }, +{ PROC_LINKS(set_eol_mode_to_crlf, 0), false, "set_eol_mode_to_crlf", 20, "Puts the buffer in crlf line ending mode.", 41, "w:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 80 }, +{ PROC_LINKS(set_eol_mode_to_lf, 0), false, "set_eol_mode_to_lf", 18, "Puts the buffer in lf line ending mode.", 39, "w:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 91 }, +{ PROC_LINKS(set_eol_mode_to_binary, 0), false, "set_eol_mode_to_binary", 22, "Puts the buffer in bin line ending mode.", 40, "w:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 102 }, +{ PROC_LINKS(set_eol_mode_from_contents, 0), false, "set_eol_mode_from_contents", 26, "Sets the buffer's line ending mode to match the contents of the buffer.", 71, "w:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 113 }, +{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 477 }, +{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 496 }, +{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 567 }, +{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 606 }, +{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 639 }, +{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 702 }, +{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 356 }, +{ PROC_LINKS(auto_indent_line_at_cursor, 0), false, "auto_indent_line_at_cursor", 26, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 365 }, +{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 375 }, +{ PROC_LINKS(write_text_and_auto_indent, 0), false, "write_text_and_auto_indent", 26, "Inserts text and auto-indents the line on which the cursor sits if any of the text contains 'layout punctuation' such as ;:{}()[]# and new lines.", 145, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 385 }, +{ PROC_LINKS(list_all_locations, 0), false, "list_all_locations", 18, "Queries the user for a string and lists all exact case-sensitive matches found in all open buffers.", 99, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 166 }, +{ PROC_LINKS(list_all_substring_locations, 0), false, "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 172 }, +{ PROC_LINKS(list_all_locations_case_insensitive, 0), false, "list_all_locations_case_insensitive", 35, "Queries the user for a string and lists all exact case-insensitive matches found in all open buffers.", 101, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 178 }, +{ PROC_LINKS(list_all_substring_locations_case_insensitive, 0), false, "list_all_substring_locations_case_insensitive", 45, "Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.", 105, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 184 }, +{ PROC_LINKS(list_all_locations_of_identifier, 0), false, "list_all_locations_of_identifier", 32, "Reads a token or word under the cursor and lists all exact case-sensitive mathces in all open buffers.", 102, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 190 }, +{ PROC_LINKS(list_all_locations_of_identifier_case_insensitive, 0), false, "list_all_locations_of_identifier_case_insensitive", 49, "Reads a token or word under the cursor and lists all exact case-insensitive mathces in all open buffers.", 104, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 196 }, +{ PROC_LINKS(list_all_locations_of_selection, 0), false, "list_all_locations_of_selection", 31, "Reads the string in the selected range and lists all exact case-sensitive mathces in all open buffers.", 102, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 202 }, +{ PROC_LINKS(list_all_locations_of_selection_case_insensitive, 0), false, "list_all_locations_of_selection_case_insensitive", 48, "Reads the string in the selected range and lists all exact case-insensitive mathces in all open buffers.", 104, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 208 }, +{ PROC_LINKS(list_all_locations_of_type_definition, 0), false, "list_all_locations_of_type_definition", 37, "Queries user for string, lists all locations of strings that appear to define a type whose name matches the input string.", 121, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 214 }, +{ PROC_LINKS(list_all_locations_of_type_definition_of_identifier, 0), false, "list_all_locations_of_type_definition_of_identifier", 51, "Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it.", 125, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 222 }, +{ PROC_LINKS(word_complete, 0), false, "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 391 }, +{ PROC_LINKS(goto_jump_at_cursor, 0), false, "goto_jump_at_cursor", 19, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 346 }, +{ PROC_LINKS(goto_jump_at_cursor_same_panel, 0), false, "goto_jump_at_cursor_same_panel", 30, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.", 167, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 373 }, +{ PROC_LINKS(goto_next_jump, 0), false, "goto_next_jump", 14, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 462 }, +{ PROC_LINKS(goto_prev_jump, 0), false, "goto_prev_jump", 14, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 479 }, +{ PROC_LINKS(goto_next_jump_no_skips, 0), false, "goto_next_jump_no_skips", 23, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 492 }, +{ PROC_LINKS(goto_prev_jump_no_skips, 0), false, "goto_prev_jump_no_skips", 23, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 509 }, +{ PROC_LINKS(goto_first_jump, 0), false, "goto_first_jump", 15, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 523 }, +{ PROC_LINKS(goto_first_jump_same_panel_sticky, 0), false, "goto_first_jump_same_panel_sticky", 33, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer and views the buffer in the panel where the jump list was.", 153, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 540 }, +{ PROC_LINKS(if_read_only_goto_position, 0), false, "if_read_only_goto_position", 26, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 562 }, +{ PROC_LINKS(if_read_only_goto_position_same_panel, 0), false, "if_read_only_goto_position_same_panel", 37, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 579 }, +{ PROC_LINKS(view_jump_list_with_lister, 0), false, "view_jump_list_with_lister", 26, "When executed on a buffer with jumps, creates a persistent lister for all the jumps", 83, "w:\\4ed\\code\\custom\\4coder_jump_lister.cpp", 41, 104 }, +{ PROC_LINKS(show_the_log_graph, 0), true, "show_the_log_graph", 18, "Parses *log* and displays the 'log graph' UI", 44, "w:\\4ed\\code\\custom\\4coder_log_parser.cpp", 40, 990 }, +{ PROC_LINKS(copy, 0), false, "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 19 }, +{ PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 28 }, +{ PROC_LINKS(paste, 0), false, "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 39 }, +{ PROC_LINKS(paste_next, 0), false, "paste_next", 10, "If the previous command was paste or paste_next, replaces the paste range with the next text down on the clipboard, otherwise operates as the paste command.", 156, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 73 }, +{ PROC_LINKS(paste_and_indent, 0), false, "paste_and_indent", 16, "Paste from the top of clipboard and run auto-indent on the newly pasted text.", 77, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 115 }, +{ PROC_LINKS(paste_next_and_indent, 0), false, "paste_next_and_indent", 21, "Paste the next item on the clipboard and run auto-indent on the newly pasted text.", 82, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 122 }, +{ PROC_LINKS(execute_previous_cli, 0), false, "execute_previous_cli", 20, "If the command execute_any_cli has already been used, this will execute a CLI reusing the most recent buffer name and command.", 126, "w:\\4ed\\code\\custom\\4coder_cli_command.cpp", 41, 7 }, +{ PROC_LINKS(execute_any_cli, 0), false, "execute_any_cli", 15, "Queries for an output buffer name and system command, runs the system command as a CLI and prints the output to the specified buffer.", 133, "w:\\4ed\\code\\custom\\4coder_cli_command.cpp", 41, 22 }, +{ PROC_LINKS(build_search, 0), false, "build_search", 12, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*.", 153, "w:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 128 }, +{ PROC_LINKS(build_in_build_panel, 0), false, "build_in_build_panel", 20, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. Puts the *compilation* buffer in a panel at the footer of the current view.", 230, "w:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 163 }, +{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "w:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 178 }, +{ PROC_LINKS(change_to_build_panel, 0), false, "change_to_build_panel", 21, "If the special build panel is open, makes the build panel the active panel.", 75, "w:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 184 }, +{ PROC_LINKS(close_all_code, 0), false, "close_all_code", 14, "Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.", 107, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 917 }, +{ PROC_LINKS(open_all_code, 0), false, "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 923 }, +{ PROC_LINKS(open_all_code_recursive, 0), false, "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 929 }, +{ PROC_LINKS(load_project, 0), false, "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 937 }, +{ PROC_LINKS(project_fkey_command, 0), false, "project_fkey_command", 20, "Run an 'fkey command' configured in a project.4coder file. Determines the index of the 'fkey command' by which function key or numeric key was pressed to trigger the command.", 175, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 944 }, +{ PROC_LINKS(project_go_to_root_directory, 0), false, "project_go_to_root_directory", 28, "Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns.", 125, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 969 }, +{ PROC_LINKS(setup_new_project, 0), false, "setup_new_project", 17, "Queries the user for several configuration options and initializes a new 4coder project with build scripts for every OS.", 120, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1303 }, +{ PROC_LINKS(setup_build_bat, 0), false, "setup_build_bat", 15, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1310 }, +{ PROC_LINKS(setup_build_sh, 0), false, "setup_build_sh", 14, "Queries the user for several configuration options and initializes a new build shell script.", 92, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1316 }, +{ PROC_LINKS(setup_build_bat_and_sh, 0), false, "setup_build_bat_and_sh", 22, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1322 }, +{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1338 }, +{ PROC_LINKS(list_all_functions_current_buffer, 0), false, "list_all_functions_current_buffer", 33, "Creates a jump list of lines of the current buffer that appear to define or declare functions.", 94, "w:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 267 }, +{ PROC_LINKS(list_all_functions_current_buffer_lister, 0), false, "list_all_functions_current_buffer_lister", 40, "Creates a lister of locations that look like function definitions and declarations in the buffer.", 97, "w:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 277 }, +{ PROC_LINKS(list_all_functions_all_buffers, 0), false, "list_all_functions_all_buffers", 30, "Creates a jump list of lines from all buffers that appear to define or declare functions.", 89, "w:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 289 }, +{ PROC_LINKS(list_all_functions_all_buffers_lister, 0), false, "list_all_functions_all_buffers_lister", 37, "Creates a lister of locations that look like function definitions and declarations all buffers.", 95, "w:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 295 }, +{ PROC_LINKS(select_surrounding_scope, 0), false, "select_surrounding_scope", 24, "Finds the scope enclosed by '{' '}' surrounding the cursor and puts the cursor and mark on the '{' and '}'.", 107, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 7 }, +{ PROC_LINKS(select_next_scope_absolute, 0), false, "select_next_scope_absolute", 26, "Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.", 102, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 32 }, +{ PROC_LINKS(select_next_scope_after_current, 0), false, "select_next_scope_after_current", 31, "Finds the first scope started by '{' after the mark and puts the cursor and mark on the '{' and '}'. This command is meant to be used after a scope is already selected so that it will have the effect of selecting the next scope after the current scope.", 253, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 41 }, +{ PROC_LINKS(select_prev_scope_absolute, 0), false, "select_prev_scope_absolute", 26, "Finds the first scope started by '{' before the cursor and puts the cursor and mark on the '{' and '}'.", 103, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 50 }, +{ PROC_LINKS(place_in_scope, 0), false, "place_in_scope", 14, "Wraps the code contained in the range between cursor and mark with a new curly brace scope.", 91, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 67 }, +{ PROC_LINKS(delete_current_scope, 0), false, "delete_current_scope", 20, "Deletes the braces surrounding the currently selected scope. Leaves the contents within the scope.", 99, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 73 }, +{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 46 }, +{ PROC_LINKS(open_long_braces_semicolon, 0), false, "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 54 }, +{ PROC_LINKS(open_long_braces_break, 0), false, "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 62 }, +{ PROC_LINKS(if0_off, 0), false, "if0_off", 7, "Surround the range between the cursor and mark with an '#if 0' and an '#endif'", 78, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 70 }, +{ PROC_LINKS(write_todo, 0), false, "write_todo", 10, "At the cursor, insert a '// TODO' comment, includes user name if it was specified in config.4coder.", 99, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 76 }, +{ PROC_LINKS(write_hack, 0), false, "write_hack", 10, "At the cursor, insert a '// HACK' comment, includes user name if it was specified in config.4coder.", 99, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 82 }, +{ PROC_LINKS(write_note, 0), false, "write_note", 10, "At the cursor, insert a '// NOTE' comment, includes user name if it was specified in config.4coder.", 99, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 88 }, +{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 94 }, +{ PROC_LINKS(write_zero_struct, 0), false, "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 100 }, +{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 125 }, +{ PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 137 }, +{ PROC_LINKS(comment_line_toggle, 0), false, "comment_line_toggle", 19, "Turns uncommented lines into commented lines and vice versa for comments starting with '//'.", 92, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 149 }, +{ PROC_LINKS(snippet_lister, 0), false, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 231 }, +{ PROC_LINKS(miblo_increment_basic, 0), false, "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 29 }, +{ PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 44 }, +{ PROC_LINKS(miblo_increment_time_stamp, 0), false, "miblo_increment_time_stamp", 26, "Increment a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 231 }, +{ PROC_LINKS(miblo_decrement_time_stamp, 0), false, "miblo_decrement_time_stamp", 26, "Decrement a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 237 }, +{ PROC_LINKS(miblo_increment_time_stamp_minute, 0), false, "miblo_increment_time_stamp_minute", 33, "Increment a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 243 }, +{ PROC_LINKS(miblo_decrement_time_stamp_minute, 0), false, "miblo_decrement_time_stamp_minute", 33, "Decrement a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 249 }, +{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "w:\\4ed\\code\\custom\\4coder_profile_inspect.cpp", 45, 375 }, +{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 7 }, +{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 21 }, }; static i32 fcoder_metacmd_ID_default_view_input_handler = 0; static i32 fcoder_metacmd_ID_profile_enable = 1; diff --git a/custom/generated/system_api.cpp b/custom/generated/system_api.cpp index ed253290..5b190f6b 100644 --- a/custom/generated/system_api.cpp +++ b/custom/generated/system_api.cpp @@ -29,6 +29,8 @@ vtable->thread_launch = system_thread_launch; vtable->thread_join = system_thread_join; vtable->thread_free = system_thread_free; vtable->thread_get_id = system_thread_get_id; +vtable->acquire_global_frame_mutex = system_acquire_global_frame_mutex; +vtable->release_global_frame_mutex = system_release_global_frame_mutex; vtable->mutex_make = system_mutex_make; vtable->mutex_acquire = system_mutex_acquire; vtable->mutex_release = system_mutex_release; @@ -77,6 +79,8 @@ system_thread_launch = vtable->thread_launch; system_thread_join = vtable->thread_join; system_thread_free = vtable->thread_free; system_thread_get_id = vtable->thread_get_id; +system_acquire_global_frame_mutex = vtable->acquire_global_frame_mutex; +system_release_global_frame_mutex = vtable->release_global_frame_mutex; system_mutex_make = vtable->mutex_make; system_mutex_acquire = vtable->mutex_acquire; system_mutex_release = vtable->mutex_release; diff --git a/custom/generated/system_api.h b/custom/generated/system_api.h index a54e36fc..5b72162d 100644 --- a/custom/generated/system_api.h +++ b/custom/generated/system_api.h @@ -27,6 +27,8 @@ #define system_thread_join_sig() void system_thread_join(System_Thread thread) #define system_thread_free_sig() void system_thread_free(System_Thread thread) #define system_thread_get_id_sig() i32 system_thread_get_id(void) +#define system_acquire_global_frame_mutex_sig() void system_acquire_global_frame_mutex(Thread_Context* tctx) +#define system_release_global_frame_mutex_sig() void system_release_global_frame_mutex(Thread_Context* tctx) #define system_mutex_make_sig() System_Mutex system_mutex_make(void) #define system_mutex_acquire_sig() void system_mutex_acquire(System_Mutex mutex) #define system_mutex_release_sig() void system_mutex_release(System_Mutex mutex) @@ -71,6 +73,8 @@ typedef System_Thread system_thread_launch_type(Thread_Function* proc, void* ptr typedef void system_thread_join_type(System_Thread thread); typedef void system_thread_free_type(System_Thread thread); typedef i32 system_thread_get_id_type(void); +typedef void system_acquire_global_frame_mutex_type(Thread_Context* tctx); +typedef void system_release_global_frame_mutex_type(Thread_Context* tctx); typedef System_Mutex system_mutex_make_type(void); typedef void system_mutex_acquire_type(System_Mutex mutex); typedef void system_mutex_release_type(System_Mutex mutex); @@ -116,6 +120,8 @@ system_thread_launch_type *thread_launch; system_thread_join_type *thread_join; system_thread_free_type *thread_free; system_thread_get_id_type *thread_get_id; +system_acquire_global_frame_mutex_type *acquire_global_frame_mutex; +system_release_global_frame_mutex_type *release_global_frame_mutex; system_mutex_make_type *mutex_make; system_mutex_acquire_type *mutex_acquire; system_mutex_release_type *mutex_release; @@ -162,6 +168,8 @@ internal System_Thread system_thread_launch(Thread_Function* proc, void* ptr); internal void system_thread_join(System_Thread thread); internal void system_thread_free(System_Thread thread); internal i32 system_thread_get_id(void); +internal void system_acquire_global_frame_mutex(Thread_Context* tctx); +internal void system_release_global_frame_mutex(Thread_Context* tctx); internal System_Mutex system_mutex_make(void); internal void system_mutex_acquire(System_Mutex mutex); internal void system_mutex_release(System_Mutex mutex); @@ -208,6 +216,8 @@ global system_thread_launch_type *system_thread_launch = 0; global system_thread_join_type *system_thread_join = 0; global system_thread_free_type *system_thread_free = 0; global system_thread_get_id_type *system_thread_get_id = 0; +global system_acquire_global_frame_mutex_type *system_acquire_global_frame_mutex = 0; +global system_release_global_frame_mutex_type *system_release_global_frame_mutex = 0; global system_mutex_make_type *system_mutex_make = 0; global system_mutex_acquire_type *system_mutex_acquire = 0; global system_mutex_release_type *system_mutex_release = 0; diff --git a/custom/generated/system_api_master_list.h b/custom/generated/system_api_master_list.h index 94dd6d49..57cef0fe 100644 --- a/custom/generated/system_api_master_list.h +++ b/custom/generated/system_api_master_list.h @@ -27,6 +27,8 @@ api(system) function System_Thread thread_launch(Thread_Function* proc, void* pt api(system) function void thread_join(System_Thread thread); api(system) function void thread_free(System_Thread thread); api(system) function i32 thread_get_id(void); +api(system) function void acquire_global_frame_mutex(Thread_Context* tctx); +api(system) function void release_global_frame_mutex(Thread_Context* tctx); api(system) function System_Mutex mutex_make(void); api(system) function void mutex_acquire(System_Mutex mutex); api(system) function void mutex_release(System_Mutex mutex); diff --git a/platform_win32/win32_4ed.cpp b/platform_win32/win32_4ed.cpp index 83d461d1..803ecf07 100644 --- a/platform_win32/win32_4ed.cpp +++ b/platform_win32/win32_4ed.cpp @@ -188,6 +188,8 @@ struct Win32_Vars{ CONDITION_VARIABLE thread_launch_cv; b32 waiting_for_launch; + System_Mutex global_frame_mutex; + Log_Function *log_string; }; @@ -887,6 +889,20 @@ system_mutex_release_sig(){ } } +internal +system_acquire_global_frame_mutex_sig(){ + if (tctx->kind == ThreadKind_AsyncTasks){ + system_mutex_acquire(win32vars.global_frame_mutex); + } +} + +internal +system_release_global_frame_mutex_sig(){ + if (tctx->kind == ThreadKind_AsyncTasks){ + system_mutex_release(win32vars.global_frame_mutex); + } +} + internal system_mutex_free_sig(){ Win32_Object *object = (Win32_Object*)handle_type_ptr(mutex); @@ -1440,7 +1456,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS // NOTE(allen): context setup Thread_Context _tctx = {}; - thread_ctx_init(&_tctx, get_base_allocator_system(), get_base_allocator_system()); + thread_ctx_init(&_tctx, ThreadKind_Main, get_base_allocator_system(), get_base_allocator_system()); block_zero_struct(&win32vars); win32vars.tctx = &_tctx; @@ -1684,6 +1700,9 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS SetActiveWindow(win32vars.window_handle); ShowWindow(win32vars.window_handle, SW_SHOW); + win32vars.global_frame_mutex = system_mutex_make(); + system_mutex_acquire(win32vars.global_frame_mutex); + u64 timer_start = system_now_time(); MSG msg; for (;keep_running;){ @@ -1921,6 +1940,8 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS } // NOTE(allen): sleep a bit to cool off :) + system_mutex_release(win32vars.global_frame_mutex); + u64 timer_end = system_now_time(); u64 end_target = timer_start + frame_useconds; @@ -1933,6 +1954,8 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS } timer_start = system_now_time(); + system_mutex_acquire(win32vars.global_frame_mutex); + win32vars.first = false; } diff --git a/ship_files/release-config.4coder b/ship_files/release-config.4coder index c6e7c8f0..bfe0fc32 100644 --- a/ship_files/release-config.4coder +++ b/ship_files/release-config.4coder @@ -14,10 +14,13 @@ mode = "4coder"; // UI use_scroll_bars = false; use_file_bars = true; -use_line_highlight = true; +use_error_highlight = true; +use_jump_highlight = true; use_scope_highlight = true; use_paren_helper = true; use_comment_keywords = true; +lister_whole_word_backspace_when_modified = false; +show_line_number_margins = false; // Code Wrapping treat_as_code = ".cpp.c.hpp.h.cc.cs.java.rs.glsl.m";