Wrote a new config parser

This commit is contained in:
Allen Webster 2018-05-11 17:53:02 -07:00
parent 7759f7e8ef
commit 537f83ab69
15 changed files with 1421 additions and 942 deletions

View File

@ -40,7 +40,8 @@ get_build_directory(Application_Links *app, Buffer_Summary *buffer, String *dir_
// TODO(allen): Better names for the "standard build search" family.
static int32_t
standard_build_search(Application_Links *app, View_Summary *view, Buffer_Summary *active_buffer, String *dir, String *command, int32_t perform_backup, int32_t use_path_in_command, String filename, String commandname){
standard_build_search(Application_Links *app, View_Summary *view, Buffer_Summary *active_buffer,
String *dir, String *command, bool32 perform_backup, bool32 use_path_in_command, String filename, String command_name){
int32_t result = false;
for(;;){
@ -51,13 +52,13 @@ standard_build_search(Application_Links *app, View_Summary *view, Buffer_Summary
dir->size = old_size;
if (use_path_in_command){
append_s_char(command, '"');
append_ss(command, *dir);
append_ss(command, commandname);
append_s_char(command, '"');
append(command, '"');
append(command, *dir);
append(command, command_name);
append(command, '"');
}
else{
append_ss(command, commandname);
append_ss(command, command_name);
}
char space[512];
@ -67,7 +68,7 @@ standard_build_search(Application_Links *app, View_Summary *view, Buffer_Summary
append_s_char(&message, '\n');
print_message(app, message.str, message.size);
if (automatically_save_changes_on_build){
if (global_config.automatically_save_changes_on_build){
save_all_dirty_buffers(app);
}

View File

@ -24,15 +24,14 @@ write_named_comment_string(Application_Links *app, char *type_string){
char space[512];
String str = make_fixed_width_string(space);
char *name = 0;
int32_t name_len = 0;
if (get_current_name(&name, &name_len)){
append(&str, "// ");
append(&str, type_string);
append(&str, "(");
append(&str, make_string(name, name_len));
append(&str, "): ");
}
String name = global_config.user_name;
if (name.size > 0){
append(&str, "// ");
append(&str, type_string);
append(&str, "(");
append(&str, name);
append(&str, "): ");
}
else{
append(&str, "// ");
append(&str, type_string);

943
4coder_config.cpp Normal file
View File

@ -0,0 +1,943 @@
/*
4coder_config.cpp - Parsing *.4coder files.
*/
// TOP
// TODO(allen): Stop handling files this way! My own API should be able to do this!!?!?!?!!?!?!!!!?
// NOTE(allen): Actually need binary buffers for some stuff to work, but not this parsing thing here.
#include <stdio.h>
////////////////////////////////
static CString_Array
get_code_extensions(Extension_List *list){
CString_Array array = {0};
array.strings = default_extensions;
array.count = ArrayCount(default_extensions);
if (list->count != 0){
array.strings = list->exts;
array.count = list->count;
}
return(array);
}
static void
parse_extension_line_to_extension_list(String str, Extension_List *list){
int32_t mode = 0;
int32_t j = 0, k = 0;
for (int32_t i = 0; i < str.size; ++i){
switch (mode){
case 0:
{
if (str.str[i] == '.'){
mode = 1;
list->exts[k++] = &list->space[j];
}
}break;
case 1:
{
if (str.str[i] == '.'){
list->space[j++] = 0;
list->exts[k++] = &list->space[j];
}
else{
list->space[j++] = str.str[i];
}
}break;
}
}
list->space[j++] = 0;
list->count = k;
}
////////////////////////////////
static void
config_parser__advance_to_next(Config_Parser *ctx){
Cpp_Token *t = ctx->token;
Cpp_Token *e = ctx->end;
for (t += 1; t < e && t->type == CPP_TOKEN_COMMENT; t += 1);
ctx->token = t;
}
static Config_Parser
make_config_parser(Partition *arena, char *file_name, String data, Cpp_Token_Array array){
Config_Parser ctx = {0};
ctx.start = array.tokens;
ctx.token = ctx.start;
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);
}
static bool32
config_parser__recognize_token(Config_Parser *ctx, Cpp_Token_Type type){
bool32 result = false;
if (ctx->start <= ctx->token && ctx->token < ctx->end){
result = (ctx->token->type == type);
}
else if (type == CPP_TOKEN_EOF){
result = true;
}
return(result);
}
static String
config_parser__get_lexeme(Config_Parser *ctx){
String lexeme = {0};
if (ctx->start <= ctx->token && ctx->token < ctx->end){
lexeme = make_string(ctx->data.str + ctx->token->start, ctx->token->size);
}
return(lexeme);
}
static int32_t
config_parser__get_integer(Config_Parser *ctx){
String str = config_parser__get_lexeme(ctx);
return(str_to_int(str));
}
static bool32
config_parser__get_boolean(Config_Parser *ctx){
String str = config_parser__get_lexeme(ctx);
return(match(str, "true"));
}
static bool32
config_parser__recognize_text(Config_Parser *ctx, String text){
bool32 result = false;
String lexeme = config_parser__get_lexeme(ctx);
if (lexeme.str != 0 && match(lexeme, text)){
result = true;
}
return(result);
}
static bool32
config_parser__match_token(Config_Parser *ctx, Cpp_Token_Type type){
bool32 result = config_parser__recognize_token(ctx, type);
if (result){
config_parser__advance_to_next(ctx);
}
return(result);
}
static bool32
config_parser__match_text(Config_Parser *ctx, String text){
bool32 result = config_parser__recognize_text(ctx, text);
if (result){
config_parser__advance_to_next(ctx);
}
return(result);
}
static Config *config_parser__config(Config_Parser *ctx);
static int32_t *config_parser__version(Config_Parser *ctx);
static Config_Assignment *config_parser__assignment(Config_Parser *ctx);
static Config_LValue *config_parser__lvalue(Config_Parser *ctx);
static Config_RValue *config_parser__rvalue(Config_Parser *ctx);
static Config_Compound *config_parser__compound(Config_Parser *ctx);
static Config_Compound_Element *config_parser__element(Config_Parser *ctx);
static Config*
config_parser__config(Config_Parser *ctx){
int32_t *version = config_parser__version(ctx);
Config_Assignment *first = 0;
Config_Assignment *last = 0;
int32_t count = 0;
for (;!config_parser__recognize_token(ctx, CPP_TOKEN_EOF);){
Config_Assignment *assignment = config_parser__assignment(ctx);
require(assignment != 0);
zdll_push_back(first, last, assignment);
count += 1;
}
Config *config = push_array(ctx->arena, Config, 1);
config->version = version;
config->first = first;
config->last = last;
config->count = count;
return(config);
}
static int32_t*
config_parser__version(Config_Parser *ctx){
require(config_parser__match_text(ctx, make_lit_string("version")));
require(config_parser__match_token(ctx, CPP_TOKEN_PARENTHESE_OPEN));
require(config_parser__recognize_token(ctx, CPP_TOKEN_INTEGER_CONSTANT));
int32_t value = config_parser__get_integer(ctx);
config_parser__advance_to_next(ctx);
require(config_parser__match_token(ctx, CPP_TOKEN_PARENTHESE_CLOSE));
int32_t *ptr = push_array(ctx->arena, int32_t, 1);
*ptr = value;
return(ptr);
}
static Config_Assignment*
config_parser__assignment(Config_Parser *ctx){
Config_LValue *l = config_parser__lvalue(ctx);
require(l != 0);
Config_RValue *r = config_parser__rvalue(ctx);
require(r != 0);
Config_Assignment *assignment = push_array(ctx->arena, Config_Assignment, 1);
assignment->l = l;
assignment->r = r;
return(assignment);
}
static Config_LValue*
config_parser__lvalue(Config_Parser *ctx){
require(config_parser__recognize_token(ctx, CPP_TOKEN_IDENTIFIER));
String identifier = config_parser__get_lexeme(ctx);
config_parser__advance_to_next(ctx);
int32_t index = 0;
if (config_parser__match_token(ctx, CPP_TOKEN_BRACKET_OPEN)){
require(config_parser__recognize_token(ctx, CPP_TOKEN_INTEGER_CONSTANT));
index = config_parser__get_integer(ctx);
config_parser__advance_to_next(ctx);
require(config_parser__match_token(ctx, CPP_TOKEN_BRACKET_CLOSE));
}
Config_LValue *lvalue = push_array(ctx->arena, Config_LValue, 1);
lvalue->identifier = identifier;
lvalue->index = index;
return(lvalue);
}
static Config_RValue*
config_parser__rvalue(Config_Parser *ctx){
if (config_parser__recognize_token(ctx, CPP_TOKEN_IDENTIFIER)){
Config_LValue *l = config_parser__lvalue(ctx);
require(l != 0);
Config_RValue *rvalue = push_array(ctx->arena, Config_RValue, 1);
rvalue->type = ConfigRValueType_LValue;
rvalue->lvalue = l;
return(rvalue);
}
else if (config_parser__recognize_token(ctx, CPP_TOKEN_BRACE_OPEN)){
config_parser__advance_to_next(ctx);
Config_Compound *compound = config_parser__compound(ctx);
require(compound != 0);
Config_RValue *rvalue = push_array(ctx->arena, Config_RValue, 1);
rvalue->type = ConfigRValueType_Compound;
rvalue->compound = compound;
return(rvalue);
}
else if (config_parser__recognize_token(ctx, CPP_TOKEN_BOOLEAN_CONSTANT)){
bool32 b = config_parser__get_boolean(ctx);
config_parser__advance_to_next(ctx);
Config_RValue *rvalue = push_array(ctx->arena, Config_RValue, 1);
rvalue->type = ConfigRValueType_Boolean;
rvalue->boolean = b;
return(rvalue);
}
else if (config_parser__recognize_token(ctx, CPP_TOKEN_INTEGER_CONSTANT)){
int32_t v = config_parser__get_integer(ctx);
config_parser__advance_to_next(ctx);
Config_RValue *rvalue = push_array(ctx->arena, Config_RValue, 1);
rvalue->type = ConfigRValueType_Integer;
rvalue->integer = v;
return(rvalue);
}
else if (config_parser__recognize_token(ctx, CPP_TOKEN_STRING_CONSTANT)){
String s = config_parser__get_lexeme(ctx);
config_parser__advance_to_next(ctx);
char *space = push_array(ctx->arena, char, s.size + 1);
push_align(ctx->arena, 8);
s = substr(s, 1, s.size - 2);
string_interpret_escapes(s, space);
Config_RValue *rvalue = push_array(ctx->arena, Config_RValue, 1);
rvalue->type = ConfigRValueType_String;
rvalue->string = make_string_slowly(space);
return(rvalue);
}
else if (config_parser__recognize_token(ctx, CPP_TOKEN_CHARACTER_CONSTANT)){
String s = config_parser__get_lexeme(ctx);
config_parser__advance_to_next(ctx);
char *space = push_array(ctx->arena, char, s.size + 1);
push_align(ctx->arena, 8);
s = substr(s, 1, s.size - 2);
string_interpret_escapes(s, space);
Config_RValue *rvalue = push_array(ctx->arena, Config_RValue, 1);
rvalue->type = ConfigRValueType_Character;
rvalue->character = space[0];
return(rvalue);
}
return(0);
}
static Config_Compound*
config_parser__compound(Config_Parser *ctx){
Config_Compound_Element *first = 0;
Config_Compound_Element *last = 0;
int32_t 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, CPP_TOKEN_COMMA);){
if (config_parser__recognize_token(ctx, CPP_TOKEN_BRACE_CLOSE)){
break;
}
element = config_parser__element(ctx);
require(element != 0);
zdll_push_back(first, last, element);
count += 1;
}
require(config_parser__match_token(ctx, CPP_TOKEN_BRACE_CLOSE));
Config_Compound *compound = push_array(ctx->arena, Config_Compound, 1);
compound->first = first;
compound->last = last;
compound->count = count;
return(compound);
}
static Config_Compound_Element*
config_parser__element(Config_Parser *ctx){
Config_Layout layout = {0};
if (config_parser__match_token(ctx, CPP_TOKEN_DOT)){
if (config_parser__recognize_token(ctx, CPP_TOKEN_INTEGER_CONSTANT)){
layout.type = ConfigLayoutType_Identifier;
layout.identifier = config_parser__get_lexeme(ctx);
config_parser__advance_to_next(ctx);
}
else if (config_parser__recognize_token(ctx, CPP_TOKEN_IDENTIFIER)){
layout.type = ConfigLayoutType_Integer;
layout.integer = config_parser__get_integer(ctx);
config_parser__advance_to_next(ctx);
}
else{
return(0);
}
require(config_parser__match_token(ctx, CPP_TOKEN_EQ));
}
Config_RValue *rvalue = config_parser__rvalue(ctx);
require(rvalue);
Config_Compound_Element *element = push_array(ctx->arena, Config_Compound_Element, 1);
element->l = layout;
element->r = rvalue;
return(element);
}
////////////////////////////////
static Cpp_Token
read_config_token(Cpp_Token_Array array, int32_t *i_ptr){
Cpp_Token token = {0};
int32_t i = *i_ptr;
for (; i < array.count; ++i){
Cpp_Token comment_token = array.tokens[i];
if (comment_token.type != CPP_TOKEN_COMMENT){
break;
}
}
if (i < array.count){
token = array.tokens[i];
}
*i_ptr = i;
return(token);
}
static Config_Line
read_config_line(Cpp_Token_Array array, int32_t *i_ptr, char *text){
Config_Line config_line = {0};
int32_t i = *i_ptr;
config_line.id_token = read_config_token(array, &i);
int32_t text_index_start = config_line.id_token.start;
if (config_line.id_token.type == CPP_TOKEN_IDENTIFIER){
++i;
if (i < array.count){
Cpp_Token token = read_config_token(array, &i);
bool32 lvalue_success = true;
if (token.type == CPP_TOKEN_BRACKET_OPEN){
lvalue_success = false;
++i;
if (i < array.count){
config_line.subscript_token = read_config_token(array, &i);
if (config_line.subscript_token.type == CPP_TOKEN_INTEGER_CONSTANT){
++i;
if (i < array.count){
token = read_config_token(array, &i);
if (token.type == CPP_TOKEN_BRACKET_CLOSE){
++i;
if (i < array.count){
token = read_config_token(array, &i);
lvalue_success = true;
}
}
}
}
}
}
if (lvalue_success){
if (token.type == CPP_TOKEN_EQ){
config_line.eq_token = read_config_token(array, &i);
++i;
if (i < array.count){
Cpp_Token val_token = read_config_token(array, &i);
bool32 rvalue_success = true;
if (val_token.type == CPP_TOKEN_BRACE_OPEN){
rvalue_success = false;
++i;
if (i < array.count){
config_line.val_array_start = i;
bool32 expecting_array_item = 1;
for (; i < array.count; ++i){
Cpp_Token array_token = read_config_token(array, &i);
if (array_token.size == 0){
break;
}
if (array_token.type == CPP_TOKEN_BRACE_CLOSE){
config_line.val_array_end = i;
rvalue_success = true;
break;
}
else{
if (array_token.type == CPP_TOKEN_COMMA){
if (!expecting_array_item){
expecting_array_item = true;
}
else{
break;
}
}
else{
if (expecting_array_item){
expecting_array_item = false;
++config_line.val_array_count;
}
}
}
}
}
}
if (rvalue_success){
config_line.val_token = val_token;
++i;
if (i < array.count){
Cpp_Token semicolon_token = read_config_token(array, &i);
if (semicolon_token.type == CPP_TOKEN_SEMICOLON){
config_line.read_success = true;
}
}
}
}
}
}
}
}
if (!config_line.read_success){
Cpp_Token token = {0};
if (i < array.count){
token = array.tokens[i];
}
int32_t text_index_current = token.start + token.size;
if (text_index_current <= text_index_start){
if (array.count > 0){
token = array.tokens[array.count - 1];
text_index_current = token.start + token.size;
}
}
if (text_index_current > text_index_start){
config_line.error_str = make_string(text + text_index_start, text_index_current - text_index_start);
}
for (; i < array.count; ++i){
Cpp_Token skip_token = read_config_token(array, &i);
if (skip_token.type == CPP_TOKEN_SEMICOLON){
break;
}
}
}
*i_ptr = i;
return(config_line);
}
static Config_Item
get_config_item(Config_Line line, char *mem, Cpp_Token_Array array){
Config_Item item = {0};
item.line = line;
item.array = array;
item.mem = mem;
if (line.id_token.size != 0){
item.id = make_string(mem + line.id_token.start, line.id_token.size);
}
if (line.subscript_token.size != 0){
String subscript_str = make_string(mem + line.subscript_token.start,line.subscript_token.size);
item.subscript_index = str_to_int_s(subscript_str);
item.has_subscript = 1;
}
return(item);
}
static bool32
config_var(Config_Item item, char *var_name, int32_t *subscript, uint32_t token_type, void *var_out){
bool32 result = false;
bool32 subscript_success = true;
if (item.line.val_token.type == token_type){
if ((var_name == 0 && item.id.size == 0) || match(item.id, var_name)){
if (subscript){
if (item.has_subscript){
*subscript = item.subscript_index;
}
else{
subscript_success = false;
}
}
if (subscript_success){
if (var_out){
switch (token_type){
case CPP_TOKEN_BOOLEAN_CONSTANT:
{
*(bool32*)var_out = (item.mem[item.line.val_token.start] == 't');
}break;
case CPP_TOKEN_INTEGER_CONSTANT:
{
if (match(make_string(item.mem + item.line.val_token.start, 2), "0x")){
// Hex Integer
String val = make_string(item.mem + item.line.val_token.start + 2, item.line.val_token.size - 2);
*(uint32_t*)var_out = hexstr_to_int(val);
}
else{
// Integer
String val = make_string(item.mem + item.line.val_token.start, item.line.val_token.size);
*(int32_t*)var_out = str_to_int(val);
}
}break;
case CPP_TOKEN_STRING_CONSTANT:
{
String str = make_string(item.mem + item.line.val_token.start + 1,item.line.val_token.size - 2);
copy((String*)var_out, str);
}break;
case CPP_TOKEN_IDENTIFIER:
{
String str = make_string(item.mem + item.line.val_token.start,item.line.val_token.size);
copy((String*)var_out, str);
}break;
case CPP_TOKEN_BRACE_OPEN:
{
Config_Array_Reader *array_reader = (Config_Array_Reader*)var_out;
array_reader->array = item.array;
array_reader->mem = item.mem;
array_reader->i = item.line.val_array_start;
array_reader->val_array_end = item.line.val_array_end;
array_reader->good = 1;
}break;
}
}
result = true;
}
}
}
return(result);
}
static bool32
config_bool_var(Config_Item item, char *var_name, int32_t *subscript, bool32 *var_out){
return(config_var(item, var_name, subscript, CPP_TOKEN_BOOLEAN_CONSTANT, var_out));
}
static bool32
config_int_var(Config_Item item, char *var_name, int32_t *subscript, int32_t *var_out){
return(config_var(item, var_name, subscript, CPP_TOKEN_INTEGER_CONSTANT, var_out));
}
static bool32
config_uint_var(Config_Item item, char *var_name, int32_t *subscript, uint32_t *var_out){
return(config_var(item, var_name, subscript, CPP_TOKEN_INTEGER_CONSTANT, var_out));
}
static bool32
config_string_var(Config_Item item, char *var_name, int32_t *subscript, String *var_out){
return(config_var(item, var_name, subscript, CPP_TOKEN_STRING_CONSTANT, var_out));
}
static bool32
config_identifier_var(Config_Item item, char *var_name, int32_t *subscript, String *var_out){
return(config_var(item, var_name, subscript, CPP_TOKEN_IDENTIFIER, var_out));
}
static bool32
config_array_var(Config_Item item, char *var_name, int32_t *subscript, Config_Array_Reader *array_reader){
return(config_var(item, var_name, subscript, CPP_TOKEN_BRACE_OPEN, array_reader));
}
static bool32
config_array_next_item(Config_Array_Reader *array_reader, Config_Item *item){
bool32 result = false;
for (;array_reader->i < array_reader->val_array_end;
++array_reader->i){
Cpp_Token array_token = read_config_token(array_reader->array, &array_reader->i);
if (array_token.size == 0 || array_reader->i >= array_reader->val_array_end){
break;
}
if (array_token.type == CPP_TOKEN_BRACE_CLOSE){
break;
}
switch (array_token.type){
case CPP_TOKEN_BOOLEAN_CONSTANT:
case CPP_TOKEN_INTEGER_CONSTANT:
case CPP_TOKEN_STRING_CONSTANT:
{
Config_Line line = {0};
line.val_token = array_token;
line.read_success = 1;
*item = get_config_item(line, array_reader->mem, array_reader->array);
result = true;
++array_reader->i;
goto doublebreak;
}break;
}
}
doublebreak:;
array_reader->good = result;
return(result);
}
static bool32
config_array_good(Config_Array_Reader *array_reader){
return(array_reader->good);
}
////////////////////////////////
static void
change_mapping(Application_Links *app, String mapping){
bool32 did_remap = false;
for (int32_t i = 0; i < named_map_count; ++i){
if (match(mapping, named_maps[i].name)){
did_remap = true;
exec_command(app, named_maps[i].remap_command);
break;
}
}
if (!did_remap){
print_message(app, literal("Leaving bindings unaltered.\n"));
}
}
////////////////////////////////
static void
config_init_default(Config_Data *config){
config->default_wrap_width = 672;
config->default_min_base_width = 550;
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->lalt_lctrl_is_altgr = false;
config->default_theme_name = make_fixed_width_string(config->default_theme_name_space);
copy(&config->default_theme_name, "4coder");
config->default_font_name = make_fixed_width_string(config->default_font_name_space);
copy(&config->default_font_name, "");
config->user_name = make_fixed_width_string(config->user_name_space);
copy(&config->user_name, "");
config->default_compiler_bat = make_fixed_width_string(config->default_compiler_bat_space);
copy(&config->default_compiler_bat, "cl");
config->default_flags_bat = make_fixed_width_string(config->default_flags_bat_space);
copy(&config->default_flags_bat, "");
config->default_compiler_sh = make_fixed_width_string(config->default_compiler_sh_space);
copy(&config->default_compiler_sh, "g++");
config->default_flags_sh = make_fixed_width_string(config->default_flags_sh_space);
copy(&config->default_flags_sh, "");
config->current_mapping = make_fixed_width_string(config->current_mapping_space);
copy(&config->current_mapping, "");
memset(&config->code_exts, 0, sizeof(config->code_exts));
}
static void
config_parse__data(Partition *scratch,
String data, Config_Data *config){
config_init_default(config);
bool32 success = false;
Temp_Memory temp = begin_temp_memory(scratch);
Cpp_Token_Array array = {0};
array.count = 0;
array.max_count = (1 << 20)/sizeof(Cpp_Token);
array.tokens = push_array(scratch, Cpp_Token, array.max_count);
if (array.tokens != 0){
Cpp_Keyword_Table kw_table = {0};
Cpp_Keyword_Table pp_table = {0};
lexer_keywords_default_init(scratch, &kw_table, &pp_table);
Cpp_Lex_Data S = cpp_lex_data_init(false, kw_table, pp_table);
Cpp_Lex_Result result = cpp_lex_step(&S, data.str, data.size + 1, HAS_NULL_TERM, &array, NO_OUT_LIMIT);
if (result == LexResult_Finished){
success = true;
for (int32_t i = 0; i < array.count; ++i){
Config_Line config_line = read_config_line(array, &i, data.str);
if (config_line.read_success){
Config_Item item = get_config_item(config_line, data.str, array);
config_bool_var(item, "enable_code_wrapping", 0,
&config->enable_code_wrapping);
config_bool_var(item, "automatically_adjust_wrapping", 0,
&config->automatically_adjust_wrapping);
config_bool_var(item, "automatically_indent_text_on_save", 0,
&config->automatically_indent_text_on_save);
config_bool_var(item, "automatically_save_changes_on_build", 0,
&config->automatically_save_changes_on_build);
config_int_var(item, "default_wrap_width", 0,
&config->default_wrap_width);
config_int_var(item, "default_min_base_width", 0,
&config->default_min_base_width);
config_string_var(item, "default_theme_name", 0,
&config->default_theme_name);
config_string_var(item, "default_font_name", 0,
&config->default_font_name);
config_string_var(item, "user_name", 0,
&config->user_name);
config_string_var(item, "default_compiler_bat", 0,
&config->default_compiler_bat);
config_string_var(item, "default_flags_bat", 0,
&config->default_flags_bat);
config_string_var(item, "default_compiler_sh", 0,
&config->default_compiler_sh);
config_string_var(item, "default_flags_sh", 0,
&config->default_flags_sh);
config_string_var(item, "mapping", 0,
&config->current_mapping);
char space[512];
String str = make_fixed_width_string(space);
if (config_string_var(item, "treat_as_code", 0, &str)){
parse_extension_line_to_extension_list(str, &config->code_exts);
}
config_bool_var(item, "automatically_load_project", 0,
&config->automatically_load_project);
config_bool_var(item, "lalt_lctrl_is_altgr", 0,
&config->lalt_lctrl_is_altgr);
}
}
}
}
end_temp_memory(temp);
if (!success){
config_init_default(config);
}
}
static void
config_parse__file_handle(Partition *scratch,
FILE *file, Config_Data *config){
Temp_Memory temp = begin_temp_memory(scratch);
String data = dump_file_handle(scratch, file);
if (data.str != 0){
config_parse__data(scratch, data, config);
}
else{
config_init_default(config);
}
end_temp_memory(temp);
}
static void
config_parse__file_name(Application_Links *app, Partition *scratch,
char *file_name, Config_Data *config){
FILE *file = open_file_try_current_path_then_binary_path(app, file_name);
if (file != 0){
config_parse__file_handle(scratch, file, config);
fclose(file);
}
else{
print_message(app, literal("Did not find config file, using default settings\n"));
config_init_default(config);
}
}
static bool32
theme_parse__data(Partition *scratch, String data, Theme_Data *theme){
bool32 success = false;
Cpp_Token_Array array;
array.count = 0;
array.max_count = (1 << 20)/sizeof(Cpp_Token);
array.tokens = push_array(scratch, Cpp_Token, array.max_count);
Cpp_Keyword_Table kw_table = {0};
Cpp_Keyword_Table pp_table = {0};
lexer_keywords_default_init(scratch, &kw_table, &pp_table);
Cpp_Lex_Data S = cpp_lex_data_init(false, kw_table, pp_table);
Cpp_Lex_Result result = cpp_lex_step(&S, data.str, data.size + 1, HAS_NULL_TERM, &array, NO_OUT_LIMIT);
if (result == LexResult_Finished){
success = true;
theme->name = make_fixed_width_string(theme->space);
copy(&theme->name, "unnamed");
init_theme_zero(&theme->theme);
for (int32_t i = 0; i < array.count; ++i){
Config_Line config_line = read_config_line(array, &i, data.str);
if (config_line.read_success){
Config_Item item = get_config_item(config_line, data.str, array);
config_string_var(item, "name", 0, &theme->name);
for (int32_t tag = 0; tag < ArrayCount(style_tag_names); ++tag){
char *name = style_tag_names[tag];
int_color color = 0;
if (config_uint_var(item, name, 0, &color)){
int_color *color_slot = &theme->theme.colors[tag];
*color_slot = color;
}
else{
char var_space[512];
String var_str = make_fixed_width_string(var_space);
if (config_identifier_var(item, name, 0, &var_str)){
for (int32_t eq_tag = 0; eq_tag < ArrayCount(style_tag_names); ++eq_tag){
if (match(var_str, style_tag_names[eq_tag])){
int_color *color_slot = &theme->theme.colors[tag];
*color_slot = theme->theme.colors[eq_tag];
break;
}
}
}
}
}
}
}
}
return(success);
}
static bool32
theme_parse__file_handle(Partition *scratch, FILE *file, Theme_Data *theme){
Temp_Memory temp = begin_temp_memory(scratch);
String data = dump_file_handle(scratch, file);
bool32 success = false;
if (data.str != 0){
success = theme_parse__data(scratch, data, theme);
}
end_temp_memory(temp);
return(success);
}
static bool32
theme_parse__file_name(Application_Links *app, Partition *scratch,
char *file_name, Theme_Data *theme){
bool32 success = false;
FILE *file = open_file_try_current_path_then_binary_path(app, file_name);
if (file != 0){
success = theme_parse__file_handle(scratch, file, theme);
fclose(file);
}
else{
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(success);
}
////////////////////////////////
static void
load_config_and_apply(Application_Links *app, Partition *scratch, Config_Data *config){
config_parse__file_name(app, scratch, "config.4coder", config);
change_mapping(app, config->current_mapping);
adjust_all_buffer_wrap_widths(app, config->default_wrap_width, config->default_min_base_width);
global_set_setting(app, GlobalSetting_LAltLCtrlIsAltGr, config->lalt_lctrl_is_altgr);
}
static void
load_theme_file_into_live_set(Application_Links *app, Partition *scratch, char *file_name){
Theme_Data theme = {0};
theme_parse__file_name(app, scratch, file_name, &theme);
create_theme(app, &theme.theme, theme.name.str, theme.name.size);
}
static 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 (uint32_t 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);
if (!match(file_extension(info_file_name), "4coder")) continue;
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);
}
}
// BOTTOM

154
4coder_config.h Normal file
View File

@ -0,0 +1,154 @@
/*
4coder_config.h - Configuration structs.
*/
// TOP
#if !defined(FCODER_CONFIG_H)
#define FCODER_CONFIG_H
struct Config_Parser{
Cpp_Token *start;
Cpp_Token *token;
Cpp_Token *end;
char *file_name;
String data;
Partition *arena;
};
struct Config_LValue{
String identifier;
int32_t index;
};
typedef int32_t Config_RValue_Type;
enum{
ConfigRValueType_LValue = 0,
ConfigRValueType_Boolean = 1,
ConfigRValueType_Integer = 2,
ConfigRValueType_Float = 3,
ConfigRValueType_String = 4,
ConfigRValueType_Character = 5,
ConfigRValueType_Compound = 6,
ConfigRValueType_COUNT = 7,
};
struct Config_Compound{
struct Config_Compound_Element *first;
struct Config_Compound_Element *last;
int32_t count;
};
struct Config_RValue{
Config_RValue_Type type;
union{
Config_LValue *lvalue;
bool32 boolean;
int32_t integer;
String string;
char character;
Config_Compound *compound;
};
};
typedef int32_t Config_Layout_Type;
enum{
ConfigLayoutType_Unset = 0,
ConfigLayoutType_Identifier = 1,
ConfigLayoutType_Integer = 2,
ConfigLayoutType_COUNT = 3,
};
struct Config_Layout{
Config_Layout_Type type;
union{
String identifier;
int32_t integer;
};
};
struct Config_Compound_Element{
Config_Compound_Element *next;
Config_Compound_Element *prev;
Config_Layout l;
Config_RValue *r;
};
struct Config_Assignment{
Config_Assignment *next;
Config_Assignment *prev;
Config_LValue *l;
Config_RValue *r;
};
struct Config{
int32_t *version;
Config_Assignment *first;
Config_Assignment *last;
int32_t count;
};
////////////////////////////////
struct Extension_List{
char space[256];
char *exts[94];
int32_t count;
};
struct CString_Array{
char **strings;
int32_t count;
};
struct Config_Data{
int32_t default_wrap_width;
int32_t default_min_base_width;
bool32 enable_code_wrapping;
bool32 automatically_adjust_wrapping;
bool32 automatically_indent_text_on_save;
bool32 automatically_save_changes_on_build;
bool32 automatically_load_project;
bool32 lalt_lctrl_is_altgr;
char default_theme_name_space[256];
String default_theme_name;
char default_font_name_space[256];
String default_font_name;
char user_name_space[256];
String user_name;
char default_compiler_bat_space[256];
String default_compiler_bat;
char default_flags_bat_space[1024];
String default_flags_bat;
char default_compiler_sh_space[256];
String default_compiler_sh;
char default_flags_sh_space[1024];
String default_flags_sh;
char current_mapping_space[256];
String current_mapping;
Extension_List code_exts;
};
struct Theme_Data{
char space[128];
String name;
Theme theme;
};
#endif
// BOTTOM

View File

@ -0,0 +1,9 @@
config := [version] {assignment}
version := "version" "(" INTEGER ")"
assignment := lvalue "=" rvalue ";"
lvalue := IDENTIFIER [ "[" INTEGER "]" ]
rvalue := lvalue | BOOLEAN | INTEGER | STRING | CHARACTER | "{" compound_body
compound_body := compound_element {"," compound_element} [","] "}"
compound_element := ["." (IDENTIFIER | INTEGER) "="] rvalue

View File

@ -1,5 +1,6 @@
/*
4coder_default_framework.cpp - Sets up the basics of the framework that is used for default 4coder behaviour.
4coder_default_framework.cpp - Sets up the basics of the framework that is used for default
4coder behaviour.
*/
// TOP
@ -38,42 +39,7 @@ static bool32 suppressing_mouse = false;
static ID_Based_Jump_Location prev_location = {0};
static Named_Mapping *named_maps = 0;
static int32_t named_map_count = 0;
static bool32 enable_code_wrapping = true;
static bool32 automatically_adjust_wrapping = true;
static bool32 automatically_indent_text_on_save = true;
static bool32 automatically_save_changes_on_build = true;
static int32_t default_wrap_width = 672;
static int32_t default_min_base_width = 550;
static char default_theme_name_space[256] = {0};
static String default_theme_name = make_fixed_width_string(default_theme_name_space);
static char default_font_name_space[256] = {0};
static String default_font_name = make_fixed_width_string(default_font_name_space);
static char user_name_space[256] = {0};
static String user_name = make_fixed_width_string(user_name_space);
static bool32 automatically_load_project = false;
static char default_compiler_bat_space[256];
static String default_compiler_bat = make_fixed_width_string(default_compiler_bat_space);
static char default_flags_bat_space[1024];
static String default_flags_bat = make_fixed_width_string(default_flags_bat_space);
static char default_compiler_sh_space[256];
static String default_compiler_sh = make_fixed_width_string(default_compiler_sh_space);
static char default_flags_sh_space[1024];
static String default_flags_sh = make_fixed_width_string(default_flags_sh_space);
static char *default_extensions[] = {
"cpp",
"hpp",
"c",
"h",
"cc",
"cs",
};
static Extension_List treat_as_code_exts = {0};
static Config_Data global_config = {0};
////////////////////////////////
@ -254,343 +220,6 @@ CUSTOM_DOC("Toggle fullscreen mode on or off. The change(s) do not take effect
////////////////////////////////
static Cpp_Token
read_config_token(Cpp_Token_Array array, int32_t *i_ptr){
Cpp_Token token = {0};
int32_t i = *i_ptr;
for (; i < array.count; ++i){
Cpp_Token comment_token = array.tokens[i];
if (comment_token.type != CPP_TOKEN_COMMENT){
break;
}
}
if (i < array.count){
token = array.tokens[i];
}
*i_ptr = i;
return(token);
}
static Config_Line
read_config_line(Cpp_Token_Array array, int32_t *i_ptr, char *text){
Config_Line config_line = {0};
int32_t i = *i_ptr;
config_line.id_token = read_config_token(array, &i);
int32_t text_index_start = config_line.id_token.start;
if (config_line.id_token.type == CPP_TOKEN_IDENTIFIER){
++i;
if (i < array.count){
Cpp_Token token = read_config_token(array, &i);
bool32 lvalue_success = true;
if (token.type == CPP_TOKEN_BRACKET_OPEN){
lvalue_success = false;
++i;
if (i < array.count){
config_line.subscript_token = read_config_token(array, &i);
if (config_line.subscript_token.type == CPP_TOKEN_INTEGER_CONSTANT){
++i;
if (i < array.count){
token = read_config_token(array, &i);
if (token.type == CPP_TOKEN_BRACKET_CLOSE){
++i;
if (i < array.count){
token = read_config_token(array, &i);
lvalue_success = true;
}
}
}
}
}
}
if (lvalue_success){
if (token.type == CPP_TOKEN_EQ){
config_line.eq_token = read_config_token(array, &i);
++i;
if (i < array.count){
Cpp_Token val_token = read_config_token(array, &i);
bool32 rvalue_success = true;
if (val_token.type == CPP_TOKEN_BRACE_OPEN){
rvalue_success = false;
++i;
if (i < array.count){
config_line.val_array_start = i;
bool32 expecting_array_item = 1;
for (; i < array.count; ++i){
Cpp_Token array_token = read_config_token(array, &i);
if (array_token.size == 0){
break;
}
if (array_token.type == CPP_TOKEN_BRACE_CLOSE){
config_line.val_array_end = i;
rvalue_success = true;
break;
}
else{
if (array_token.type == CPP_TOKEN_COMMA){
if (!expecting_array_item){
expecting_array_item = true;
}
else{
break;
}
}
else{
if (expecting_array_item){
expecting_array_item = false;
++config_line.val_array_count;
}
}
}
}
}
}
if (rvalue_success){
config_line.val_token = val_token;
++i;
if (i < array.count){
Cpp_Token semicolon_token = read_config_token(array, &i);
if (semicolon_token.type == CPP_TOKEN_SEMICOLON){
config_line.read_success = true;
}
}
}
}
}
}
}
}
if (!config_line.read_success){
Cpp_Token token = {0};
if (i < array.count){
token = array.tokens[i];
}
int32_t text_index_current = token.start + token.size;
if (text_index_current <= text_index_start){
if (array.count > 0){
token = array.tokens[array.count - 1];
text_index_current = token.start + token.size;
}
}
if (text_index_current > text_index_start){
config_line.error_str = make_string(text + text_index_start, text_index_current - text_index_start);
}
for (; i < array.count; ++i){
Cpp_Token skip_token = read_config_token(array, &i);
if (skip_token.type == CPP_TOKEN_SEMICOLON){
break;
}
}
}
*i_ptr = i;
return(config_line);
}
static Config_Item
get_config_item(Config_Line line, char *mem, Cpp_Token_Array array){
Config_Item item = {0};
item.line = line;
item.array = array;
item.mem = mem;
if (line.id_token.size != 0){
item.id = make_string(mem + line.id_token.start, line.id_token.size);
}
if (line.subscript_token.size != 0){
String subscript_str = make_string(mem + line.subscript_token.start,line.subscript_token.size);
item.subscript_index = str_to_int_s(subscript_str);
item.has_subscript = 1;
}
return(item);
}
static bool32
config_var(Config_Item item, char *var_name, int32_t *subscript, uint32_t token_type, void *var_out){
bool32 result = false;
bool32 subscript_success = true;
if (item.line.val_token.type == token_type){
if ((var_name == 0 && item.id.size == 0) || match(item.id, var_name)){
if (subscript){
if (item.has_subscript){
*subscript = item.subscript_index;
}
else{
subscript_success = false;
}
}
if (subscript_success){
if (var_out){
switch (token_type){
case CPP_TOKEN_BOOLEAN_CONSTANT:
{
*(bool32*)var_out = (item.mem[item.line.val_token.start] == 't');
}break;
case CPP_TOKEN_INTEGER_CONSTANT:
{
if (match(make_string(item.mem + item.line.val_token.start, 2), "0x")){
// Hex Integer
String val = make_string(item.mem + item.line.val_token.start + 2, item.line.val_token.size - 2);
*(uint32_t*)var_out = hexstr_to_int(val);
}
else{
// Integer
String val = make_string(item.mem + item.line.val_token.start, item.line.val_token.size);
*(int32_t*)var_out = str_to_int(val);
}
}break;
case CPP_TOKEN_STRING_CONSTANT:
{
String str = make_string(item.mem + item.line.val_token.start + 1,item.line.val_token.size - 2);
copy((String*)var_out, str);
}break;
case CPP_TOKEN_IDENTIFIER:
{
String str = make_string(item.mem + item.line.val_token.start,item.line.val_token.size);
copy((String*)var_out, str);
}break;
case CPP_TOKEN_BRACE_OPEN:
{
Config_Array_Reader *array_reader = (Config_Array_Reader*)var_out;
array_reader->array = item.array;
array_reader->mem = item.mem;
array_reader->i = item.line.val_array_start;
array_reader->val_array_end = item.line.val_array_end;
array_reader->good = 1;
}break;
}
}
result = true;
}
}
}
return(result);
}
static bool32
config_bool_var(Config_Item item, char *var_name, int32_t *subscript, bool32 *var_out){
bool32 result = config_var(item, var_name, subscript, CPP_TOKEN_BOOLEAN_CONSTANT, var_out);
return(result);
}
static bool32
config_int_var(Config_Item item, char *var_name, int32_t *subscript, int32_t *var_out){
bool32 result = config_var(item, var_name, subscript, CPP_TOKEN_INTEGER_CONSTANT, var_out);
return(result);
}
static bool32
config_uint_var(Config_Item item, char *var_name, int32_t *subscript, uint32_t *var_out){
bool32 result = config_var(item, var_name, subscript, CPP_TOKEN_INTEGER_CONSTANT, var_out);
return(result);
}
static bool32
config_string_var(Config_Item item, char *var_name, int32_t *subscript, String *var_out){
bool32 result = config_var(item, var_name, subscript, CPP_TOKEN_STRING_CONSTANT, var_out);
return(result);
}
static bool32
config_identifier_var(Config_Item item, char *var_name, int32_t *subscript, String *var_out){
bool32 result = config_var(item, var_name, subscript, CPP_TOKEN_IDENTIFIER, var_out);
return(result);
}
static bool32
config_array_var(Config_Item item, char *var_name, int32_t *subscript, Config_Array_Reader *array_reader){
bool32 result = config_var(item, var_name, subscript, CPP_TOKEN_BRACE_OPEN, array_reader);
return(result);
}
static bool32
config_array_next_item(Config_Array_Reader *array_reader, Config_Item *item){
bool32 result = false;
for (;array_reader->i < array_reader->val_array_end;
++array_reader->i){
Cpp_Token array_token = read_config_token(array_reader->array, &array_reader->i);
if (array_token.size == 0 || array_reader->i >= array_reader->val_array_end){
break;
}
if (array_token.type == CPP_TOKEN_BRACE_CLOSE){
break;
}
switch (array_token.type){
case CPP_TOKEN_BOOLEAN_CONSTANT:
case CPP_TOKEN_INTEGER_CONSTANT:
case CPP_TOKEN_STRING_CONSTANT:
{
Config_Line line = {0};
line.val_token = array_token;
line.read_success = 1;
*item = get_config_item(line, array_reader->mem, array_reader->array);
result = true;
++array_reader->i;
goto doublebreak;
}break;
}
}
doublebreak:;
array_reader->good = result;
return(result);
}
static bool32
config_array_good(Config_Array_Reader *array_reader){
bool32 result = (array_reader->good);
return(result);
}
////////////////////////////////
static void
lexer_keywords_default_init(Partition *part, Cpp_Keyword_Table *kw_out, Cpp_Keyword_Table *pp_out){
umem_4tech kw_size = cpp_get_table_memory_size_default(CPP_TABLE_KEYWORDS);
umem_4tech pp_size = cpp_get_table_memory_size_default(CPP_TABLE_PREPROCESSOR_DIRECTIVES);
void *kw_mem = push_block(part, (i32_4tech)kw_size);
void *pp_mem = push_block(part, (i32_4tech)pp_size);
*kw_out = cpp_make_table_default(CPP_TABLE_KEYWORDS, kw_mem, kw_size);
*pp_out = cpp_make_table_default(CPP_TABLE_PREPROCESSOR_DIRECTIVES, pp_mem, pp_size);
}
////////////////////////////////
static void
change_mapping(Application_Links *app, String mapping){
bool32 did_remap = false;
for (int32_t i = 0; i < named_map_count; ++i){
if (match(mapping, named_maps[i].name)){
did_remap = true;
exec_command(app, named_maps[i].remap_command);
break;
}
}
if (!did_remap){
print_message(app, literal("Leaving bindings unaltered.\n"));
}
}
CUSTOM_COMMAND_SIG(remap_interactive)
CUSTOM_DOC("Switch to a named key binding map.")
{
@ -604,6 +233,7 @@ CUSTOM_DOC("Switch to a named key binding map.")
////////////////////////////////
#if 0
static bool32
get_current_name(char **name_out, int32_t *len_out){
bool32 result = false;
@ -633,422 +263,7 @@ get_default_font_name(void){
}
return(str);
}
////////////////////////////////
static CString_Array
get_code_extensions(Extension_List *list){
CString_Array array = {0};
array.strings = default_extensions;
array.count = ArrayCount(default_extensions);
if (list->count != 0){
array.strings = list->exts;
array.count = list->count;
}
return(array);
}
static void
parse_extension_line_to_extension_list(String str, Extension_List *list){
int32_t mode = 0;
int32_t j = 0, k = 0;
for (int32_t i = 0; i < str.size; ++i){
switch (mode){
case 0:
{
if (str.str[i] == '.'){
mode = 1;
list->exts[k++] = &list->space[j];
}
}break;
case 1:
{
if (str.str[i] == '.'){
list->space[j++] = 0;
list->exts[k++] = &list->space[j];
}
else{
list->space[j++] = str.str[i];
}
}break;
}
}
list->space[j++] = 0;
list->count = k;
}
////////////////////////////////
// TODO(allen): Stop handling files this way! My own API should be able to do this!!?!?!?!!?!?!!!!?
// NOTE(allen): Actually need binary buffers for some stuff to work, but not this parsing thing here.
#include <stdio.h>
static String
dump_file_handle(Partition *arena, FILE *file){
String str = {0};
if (file != 0){
fseek(file, 0, SEEK_END);
int32_t size = ftell(file);
char *mem = push_array(arena, char, size + 1);
push_align(arena, 8);
if (mem != 0){
fseek(file, 0, SEEK_SET);
fread(mem, 1, size, file);
mem[size] = 0;
str = make_string_cap(mem, size, size + 1);
}
}
return(str);
}
static FILE*
open_file_search_up_path(Partition *scratch, String path, String file_name){
Temp_Memory temp = begin_temp_memory(scratch);
int32_t cap = path.size + file_name.size + 2;
char *space = push_array(scratch, char, cap);
String name_str = make_string_cap(space, 0, cap);
append(&name_str, path);
if (name_str.size == 0 || !char_is_slash(name_str.str[name_str.size - 1])){
append(&name_str, "/");
}
FILE *file = 0;
for (;;){
int32_t base_size = name_str.size;
append(&name_str, file_name);
terminate_with_null(&name_str);
file = fopen(name_str.str, "rb");
if (file != 0){
break;
}
name_str.size = base_size;
remove_last_folder(&name_str);
if (name_str.size >= base_size){
break;
}
}
end_temp_memory(temp);
return(file);
}
static char*
get_null_terminated(Partition *scratch, String name){
char *name_terminated = 0;
if (name.size < name.memory_size){
terminate_with_null(&name);
name_terminated = name.str;
}
else{
name_terminated = push_array(scratch, char, name.size + 1);
if (name_terminated != 0){
memcpy(name_terminated, name.str, name.size);
name_terminated[name.size] = 0;
}
}
return(name_terminated);
}
static FILE*
open_file(Partition *scratch, String name){
FILE *file = 0;
Temp_Memory temp = begin_temp_memory(scratch);
char *name_terminated = get_null_terminated(scratch, name);
if (name_terminated != 0){
file = fopen(name_terminated, "rb");
}
end_temp_memory(temp);
return(file);
}
static String
dump_file(Partition *arena, String name){
String result = {0};
FILE *file = open_file(arena, name);
if (file != 0){
result = dump_file_handle(arena, file);
fclose(file);
}
return(result);
}
static String
dump_file_search_up_path(Partition *arena, String path, String file_name){
String result = {0};
FILE *file = open_file_search_up_path(arena, path, file_name);
if (file != 0){
result = dump_file_handle(arena, file);
fclose(file);
}
return(result);
}
///////////////////////////////
static void
process_config_data(Application_Links *app, Partition *scratch, String data){
Cpp_Token_Array array = {0};
array.count = 0;
array.max_count = (1 << 20)/sizeof(Cpp_Token);
array.tokens = push_array(scratch, Cpp_Token, array.max_count);
if (array.tokens != 0){
Cpp_Keyword_Table kw_table = {0};
Cpp_Keyword_Table pp_table = {0};
lexer_keywords_default_init(scratch, &kw_table, &pp_table);
Cpp_Lex_Data S = cpp_lex_data_init(false, kw_table, pp_table);
Cpp_Lex_Result result = cpp_lex_step(&S, data.str, data.size + 1, HAS_NULL_TERM, &array, NO_OUT_LIMIT);
if (result == LexResult_Finished){
int32_t new_wrap_width = default_wrap_width;
int32_t new_min_base_width = default_min_base_width;
bool32 lalt_lctrl_is_altgr = false;
for (int32_t i = 0; i < array.count; ++i){
Config_Line config_line = read_config_line(array, &i, data.str);
if (config_line.read_success){
Config_Item item = get_config_item(config_line, data.str, array);
config_bool_var(item, "enable_code_wrapping", 0, &enable_code_wrapping);
config_bool_var(item, "automatically_adjust_wrapping", 0, &automatically_adjust_wrapping);
config_bool_var(item, "automatically_indent_text_on_save", 0, &automatically_indent_text_on_save);
config_bool_var(item, "automatically_save_changes_on_build", 0, &automatically_save_changes_on_build);
config_int_var(item, "default_wrap_width", 0, &new_wrap_width);
config_int_var(item, "default_min_base_width", 0, &new_min_base_width);
config_string_var(item, "default_theme_name", 0, &default_theme_name);
config_string_var(item, "default_font_name", 0, &default_font_name);
config_string_var(item, "user_name", 0, &user_name);
config_string_var(item, "default_compiler_bat", 0, &default_compiler_bat);
config_string_var(item, "default_flags_bat", 0, &default_flags_bat);
config_string_var(item, "default_compiler_sh", 0, &default_compiler_sh);
config_string_var(item, "default_flags_sh", 0, &default_flags_sh);
char str_space[512];
String str = make_fixed_width_string(str_space);
if (config_string_var(item, "mapping", 0, &str)){
change_mapping(app, str);
}
if (config_string_var(item, "treat_as_code", 0, &str)){
parse_extension_line_to_extension_list(str, &treat_as_code_exts);
}
config_bool_var(item, "automatically_load_project", 0, &automatically_load_project);
config_bool_var(item, "lalt_lctrl_is_altgr", 0, &lalt_lctrl_is_altgr);
}
else if (config_line.error_str.str != 0){
char space[2048];
String str = make_fixed_width_string(space);
copy(&str, "WARNING: bad syntax in 4coder.config at ");
append(&str, config_line.error_str);
append(&str, "\n");
print_message(app, str.str, str.size);
}
}
adjust_all_buffer_wrap_widths(app, new_wrap_width, new_min_base_width);
default_wrap_width = new_wrap_width;
default_min_base_width = new_min_base_width;
global_set_setting(app, GlobalSetting_LAltLCtrlIsAltGr, lalt_lctrl_is_altgr);
}
}
else{
print_message(app, literal("Ran out of memory processing config.4coder\n"));
}
}
static void
process_config_file(Application_Links *app){
static bool32 has_initialized = false;
if (!has_initialized){
has_initialized = true;
copy(&default_compiler_bat, "cl");
copy(&default_flags_bat, "");
copy(&default_compiler_sh, "g++");
copy(&default_flags_bat, "");
}
Partition *part = &global_part;
FILE *file = fopen("config.4coder", "rb");
if (file == 0){
char space[256];
int32_t size = get_4ed_path(app, space, sizeof(space));
print_message(app, space, size);
String str = make_string_cap(space, size, sizeof(space));
append_sc(&str, "/config.4coder");
terminate_with_null(&str);
file = fopen(str.str, "rb");
}
if (file != 0){
Temp_Memory temp = begin_temp_memory(part);
String data = dump_file_handle(part, file);
if (data.str != 0){
process_config_data(app, part, data);
}
end_temp_memory(temp);
fclose(file);
}
else{
print_message(app, literal("Did not find config.4coder, using default settings\n"));
}
}
////////////////////////////////
static bool32
load_color_theme_data(Application_Links *app, Partition *scratch,
char *file_name, String data){
bool32 success = false;
Cpp_Token_Array array;
array.count = 0;
array.max_count = (1 << 20)/sizeof(Cpp_Token);
array.tokens = push_array(scratch, Cpp_Token, array.max_count);
Cpp_Keyword_Table kw_table = {0};
Cpp_Keyword_Table pp_table = {0};
lexer_keywords_default_init(scratch, &kw_table, &pp_table);
Cpp_Lex_Data S = cpp_lex_data_init(false, kw_table, pp_table);
Cpp_Lex_Result result = cpp_lex_step(&S, data.str, data.size + 1, HAS_NULL_TERM, &array, NO_OUT_LIMIT);
if (result == LexResult_Finished){
success = true;
char name_space[512];
String name_str = make_fixed_width_string(name_space);
Theme theme;
init_theme_zero(&theme);
for (int32_t i = 0; i < array.count; ++i){
Config_Line config_line = read_config_line(array, &i, data.str);
if (config_line.read_success){
Config_Item item = get_config_item(config_line, data.str, array);
config_string_var(item, "name", 0, &name_str);
for (int32_t tag = 0; tag < ArrayCount(style_tag_names); ++tag){
char *name = style_tag_names[tag];
int_color color = 0;
if (config_uint_var(item, name, 0, &color)){
int_color *color_slot = &theme.colors[tag];
*color_slot = color;
}
else{
char var_space[512];
String var_str = make_fixed_width_string(var_space);
if (config_identifier_var(item, name, 0, &var_str)){
for (int32_t eq_tag = 0; eq_tag < ArrayCount(style_tag_names); ++eq_tag){
if (match(var_str, style_tag_names[eq_tag])){
int_color *color_slot = &theme.colors[tag];
*color_slot = theme.colors[eq_tag];
break;
}
}
}
}
}
}
else if (config_line.error_str.str != 0){
char space[2048];
String str = make_fixed_width_string(space);
copy(&str, "WARNING: bad syntax in 4coder.config at ");
append(&str, config_line.error_str);
append(&str, "\n");
print_message(app, str.str, str.size);
}
}
if (name_str.size == 0){
copy(&name_str, file_name);
}
create_theme(app, &theme, name_str.str, name_str.size);
}
return(success);
}
static void
load_color_theme_file(Application_Links *app, char *file_name){
Partition *part = &global_part;
FILE *file = fopen(file_name, "rb");
if (file == 0){
char space[256];
int32_t size = get_4ed_path(app, space, sizeof(space));
String str = make_string_cap(space, size, sizeof(space));
append_sc(&str, "/");
append_sc(&str, file_name);
terminate_with_null(&str);
file = fopen(str.str, "rb");
}
if (file != 0){
Temp_Memory temp = begin_temp_memory(part);
String data = dump_file_handle(part, file);
bool32 success = false;
if (data.str != 0){
success = load_color_theme_data(app, part, file_name, data);
}
end_temp_memory(temp);
fclose(file);
if (!success){
char space[256];
String str = make_fixed_width_string(space);
append_sc(&str, "Could not parse ");
append_sc(&str, file_name);
append_sc(&str, ", color scheme not loaded");
print_message(app, str.str, str.size);
}
}
else{
char space[256];
String str = make_fixed_width_string(space);
append_sc(&str, "Did not find ");
append_sc(&str, file_name);
append_sc(&str, ", color scheme not loaded");
print_message(app, str.str, str.size);
}
}
static void
load_themes_folder(Application_Links *app){
char folder_name_space[512];
String folder_name = make_fixed_width_string(folder_name_space);
folder_name.size = get_4ed_path(app, folder_name_space, sizeof(folder_name_space));
append(&folder_name, "themes");
if (folder_name.size < folder_name.memory_size){
File_List list = get_file_list(app, folder_name.str, folder_name.size);
for (uint32_t i = 0; i < list.count; ++i){
File_Info *info = &list.infos[i];
if (!info->folder){
char file_name_space[512];
String file_name = make_fixed_width_string(file_name_space);
copy(&file_name, folder_name);
append(&file_name, "/");
append(&file_name, make_string(info->filename, info->filename_len));
if (file_name.size < file_name.memory_size){
terminate_with_null(&file_name);
load_color_theme_file(app, file_name.str);
}
}
}
free_file_list(app, list);
}
}
#endif
////////////////////////////////
@ -1208,11 +423,11 @@ init_memory(Application_Links *app){
static void
default_4coder_initialize(Application_Links *app, bool32 use_scrollbars, bool32 use_file_bars){
init_memory(app);
process_config_file(app);
load_themes_folder(app);
load_config_and_apply(app, &global_part, &global_config);
load_folder_of_themes_into_live_set(app, &global_part, "themes");
String theme = get_default_theme_name();
String font = get_default_font_name();
String theme = global_config.default_theme_name;
String font = global_config.default_font_name;
change_theme(app, theme.str, theme.size);
change_font(app, font.str, font.size, true);

View File

@ -72,19 +72,6 @@ struct Named_Mapping{
Custom_Command_Function *remap_command;
};
////////////////////////////////
struct Extension_List{
char space[256];
char *exts[94];
int32_t count;
};
struct CString_Array{
char **strings;
int32_t count;
};
#endif
// BOTTOM

View File

@ -0,0 +1,21 @@
/*
4coder_default_framework_variables.cpp - Declares the global variables used by the framework for
the default 4coder behavior.
*/
// TOP
static Named_Mapping *named_maps = 0;
static int32_t named_map_count = 0;
static char *default_extensions[] = {
"cpp",
"hpp",
"c",
"h",
"cc",
"cs",
};
// BOTTOM

View File

@ -26,7 +26,7 @@ START_HOOK_SIG(default_start){
default_4coder_initialize(app);
default_4coder_side_by_side_panels(app, files, file_count);
if (automatically_load_project){
if (global_config.automatically_load_project){
load_project(app);
}
@ -69,10 +69,10 @@ HOOK_SIG(default_view_adjust){
new_wrap_width = (int32_t)(new_wrap_width * .9f);
int32_t new_min_base_width = (int32_t)(new_wrap_width * .77f);
if (automatically_adjust_wrapping){
if (global_config.automatically_adjust_wrapping){
adjust_all_buffer_wrap_widths(app, new_wrap_width, new_min_base_width);
default_wrap_width = new_wrap_width;
default_min_base_width = new_min_base_width;
global_config.default_wrap_width = new_wrap_width;
global_config.default_min_base_width = new_min_base_width;
}
// no meaning for return
@ -196,7 +196,7 @@ OPEN_FILE_HOOK_SIG(default_file_settings){
bool32 wrap_lines = true;
bool32 lex_without_strings = false;
CString_Array extensions = get_code_extensions(&treat_as_code_exts);
CString_Array extensions = get_code_extensions(&global_config.code_exts);
Parse_Context_ID parse_context_id = 0;
@ -273,8 +273,10 @@ OPEN_FILE_HOOK_SIG(default_file_settings){
int32_t map_id = (treat_as_code)?((int32_t)default_code_map):((int32_t)mapid_file);
buffer_set_setting(app, &buffer, BufferSetting_WrapPosition, default_wrap_width);
buffer_set_setting(app, &buffer, BufferSetting_MinimumBaseWrapPosition, default_min_base_width);
buffer_set_setting(app, &buffer, BufferSetting_WrapPosition,
global_config.default_wrap_width);
buffer_set_setting(app, &buffer, BufferSetting_MinimumBaseWrapPosition,
global_config.default_min_base_width);
buffer_set_setting(app, &buffer, BufferSetting_MapID, map_id);
buffer_set_setting(app, &buffer, BufferSetting_ParserContext, parse_context_id);
@ -283,7 +285,7 @@ OPEN_FILE_HOOK_SIG(default_file_settings){
buffer_set_setting(app, &buffer, BufferSetting_LexWithoutStrings, true);
buffer_set_setting(app, &buffer, BufferSetting_VirtualWhitespace, true);
}
else if (treat_as_code && enable_code_wrapping && buffer.size < (128 << 10)){
else if (treat_as_code && global_config.enable_code_wrapping && buffer.size < (128 << 10)){
// NOTE(allen|a4.0.12): There is a little bit of grossness going on here.
// If we set BufferSetting_Lex to true, it will launch a lexing job.
// If a lexing job is active when we set BufferSetting_VirtualWhitespace, the call can fail.

View File

@ -22,6 +22,7 @@
#include "4coder_helper.h"
#include "4coder_default_framework.h"
#include "4coder_config.h"
#include "4coder_seek.h"
#include "4coder_auto_indent.h"
#include "4coder_search.h"
@ -32,8 +33,10 @@
#include "4coder_function_list.h"
#include "4coder_scope_commands.h"
#include "4coder_default_framework_variables.cpp"
#include "4coder_buffer_seek_constructors.cpp"
#include "4coder_helper.cpp"
#include "4coder_config.cpp"
#include "4coder_default_framework.cpp"
#include "4coder_seek.cpp"
#include "4coder_base_commands.cpp"

View File

@ -214,43 +214,43 @@ int32_t source_name_len;
int32_t line_number;
};
static Command_Metadata fcoder_metacmd_table[194] = {
{ PROC_LINKS(allow_mouse, 0), "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 237 },
{ PROC_LINKS(allow_mouse, 0), "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 203 },
{ PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 722 },
{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 733 },
{ PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 712 },
{ PROC_LINKS(backspace_char, 0), "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 74 },
{ PROC_LINKS(backspace_char, 0), "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 67 },
{ PROC_LINKS(backspace_word, 0), "backspace_word", 14, "Delete characters between the cursor position and the first alphanumeric boundary to the left.", 94, "C:\\work\\4ed\\code\\4coder_seek.cpp", 36, 1247 },
{ PROC_LINKS(basic_change_active_panel, 0), "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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 440 },
{ PROC_LINKS(build_in_build_panel, 0), "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:\\work\\4ed\\code\\4coder_build_commands.cpp", 46, 188 },
{ PROC_LINKS(build_search, 0), "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:\\work\\4ed\\code\\4coder_build_commands.cpp", 46, 154 },
{ PROC_LINKS(center_view, 0), "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 127 },
{ PROC_LINKS(change_active_panel, 0), "change_active_panel", 19, "Change the currently active panel, moving to the panel with the next highest view_id.", 85, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 179 },
{ PROC_LINKS(change_active_panel_backwards, 0), "change_active_panel_backwards", 29, "Change the currently active panel, moving to the panel with the next lowest view_id.", 84, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 189 },
{ PROC_LINKS(change_to_build_panel, 0), "change_to_build_panel", 21, "If the special build panel is open, makes the build panel the active panel.", 75, "C:\\work\\4ed\\code\\4coder_build_commands.cpp", 46, 210 },
{ PROC_LINKS(clean_all_lines, 0), "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 375 },
{ PROC_LINKS(click_set_cursor, 0), "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 181 },
{ PROC_LINKS(click_set_mark, 0), "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 194 },
{ PROC_LINKS(basic_change_active_panel, 0), "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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 433 },
{ PROC_LINKS(build_in_build_panel, 0), "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:\\work\\4ed\\code\\4coder_build_commands.cpp", 46, 189 },
{ PROC_LINKS(build_search, 0), "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:\\work\\4ed\\code\\4coder_build_commands.cpp", 46, 155 },
{ PROC_LINKS(center_view, 0), "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 120 },
{ PROC_LINKS(change_active_panel, 0), "change_active_panel", 19, "Change the currently active panel, moving to the panel with the next highest view_id.", 85, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 145 },
{ PROC_LINKS(change_active_panel_backwards, 0), "change_active_panel_backwards", 29, "Change the currently active panel, moving to the panel with the next lowest view_id.", 84, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 155 },
{ PROC_LINKS(change_to_build_panel, 0), "change_to_build_panel", 21, "If the special build panel is open, makes the build panel the active panel.", 75, "C:\\work\\4ed\\code\\4coder_build_commands.cpp", 46, 211 },
{ PROC_LINKS(clean_all_lines, 0), "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 368 },
{ PROC_LINKS(click_set_cursor, 0), "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 174 },
{ PROC_LINKS(click_set_mark, 0), "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 187 },
{ PROC_LINKS(close_all_code, 0), "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:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 403 },
{ PROC_LINKS(close_build_panel, 0), "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "C:\\work\\4ed\\code\\4coder_build_commands.cpp", 46, 204 },
{ PROC_LINKS(close_panel, 0), "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 448 },
{ PROC_LINKS(close_build_panel, 0), "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "C:\\work\\4ed\\code\\4coder_build_commands.cpp", 46, 205 },
{ PROC_LINKS(close_panel, 0), "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 441 },
{ PROC_LINKS(copy, 0), "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "C:\\work\\4ed\\code\\4coder_clipboard.cpp", 41, 26 },
{ PROC_LINKS(cursor_mark_swap, 0), "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 102 },
{ PROC_LINKS(cursor_mark_swap, 0), "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 95 },
{ PROC_LINKS(cut, 0), "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "C:\\work\\4ed\\code\\4coder_clipboard.cpp", 41, 35 },
{ PROC_LINKS(decrease_face_size, 0), "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 538 },
{ PROC_LINKS(decrease_line_wrap, 0), "decrease_line_wrap", 18, "Decrases the current buffer's width for line wrapping.", 54, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 515 },
{ PROC_LINKS(delete_char, 0), "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 56 },
{ PROC_LINKS(decrease_face_size, 0), "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 531 },
{ PROC_LINKS(decrease_line_wrap, 0), "decrease_line_wrap", 18, "Decrases the current buffer's width for line wrapping.", 54, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 508 },
{ PROC_LINKS(delete_char, 0), "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 49 },
{ PROC_LINKS(delete_current_scope, 0), "delete_current_scope", 20, "Deletes the braces surrounding the currently selected scope. Leaves the contents within the scope.", 99, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 487 },
{ PROC_LINKS(delete_file_query, 0), "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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1000 },
{ PROC_LINKS(delete_line, 0), "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1250 },
{ PROC_LINKS(delete_range, 0), "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 114 },
{ PROC_LINKS(delete_file_query, 0), "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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 993 },
{ PROC_LINKS(delete_line, 0), "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1243 },
{ PROC_LINKS(delete_range, 0), "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 107 },
{ PROC_LINKS(delete_word, 0), "delete_word", 11, "Delete characters between the cursor position and the first alphanumeric boundary to the right.", 95, "C:\\work\\4ed\\code\\4coder_seek.cpp", 36, 1253 },
{ PROC_LINKS(duplicate_line, 0), "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1228 },
{ PROC_LINKS(eol_dosify, 0), "eol_dosify", 10, "Puts the buffer in DOS line ending mode.", 40, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 568 },
{ PROC_LINKS(eol_nixify, 0), "eol_nixify", 10, "Puts the buffer in NIX line ending mode.", 40, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 576 },
{ PROC_LINKS(duplicate_line, 0), "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1221 },
{ PROC_LINKS(eol_dosify, 0), "eol_dosify", 10, "Puts the buffer in DOS line ending mode.", 40, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 561 },
{ PROC_LINKS(eol_nixify, 0), "eol_nixify", 10, "Puts the buffer in NIX line ending mode.", 40, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 569 },
{ PROC_LINKS(execute_any_cli, 0), "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:\\work\\4ed\\code\\4coder_system_command.cpp", 46, 23 },
{ PROC_LINKS(execute_arbitrary_command, 0), "execute_arbitrary_command", 25, "Execute a 'long form' command.", 30, "C:\\work\\4ed\\code\\4coder_long_command_switch.cpp", 51, 8 },
{ PROC_LINKS(execute_previous_cli, 0), "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:\\work\\4ed\\code\\4coder_system_command.cpp", 46, 7 },
{ PROC_LINKS(exit_4coder, 0), "exit_4coder", 11, "Attempts to close 4coder.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 584 },
{ PROC_LINKS(exit_4coder, 0), "exit_4coder", 11, "Attempts to close 4coder.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 577 },
{ PROC_LINKS(goto_beginning_of_file, 0), "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "C:\\work\\4ed\\code\\4coder_seek.cpp", 36, 1168 },
{ PROC_LINKS(goto_end_of_file, 0), "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "C:\\work\\4ed\\code\\4coder_seek.cpp", 36, 1175 },
{ PROC_LINKS(goto_first_jump_direct, 0), "goto_first_jump_direct", 22, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "C:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 84 },
@ -260,7 +260,7 @@ static Command_Metadata fcoder_metacmd_table[194] = {
{ PROC_LINKS(goto_jump_at_cursor_same_panel_direct, 0), "goto_jump_at_cursor_same_panel_direct", 37, "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..", 168, "C:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 29 },
{ PROC_LINKS(goto_jump_at_cursor_same_panel_sticky, 0), "goto_jump_at_cursor_same_panel_sticky", 37, "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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 365 },
{ PROC_LINKS(goto_jump_at_cursor_sticky, 0), "goto_jump_at_cursor_sticky", 26, "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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 337 },
{ PROC_LINKS(goto_line, 0), "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 592 },
{ PROC_LINKS(goto_line, 0), "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 585 },
{ PROC_LINKS(goto_next_jump_direct, 0), "goto_next_jump_direct", 21, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "C:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 48 },
{ PROC_LINKS(goto_next_jump_no_skips_direct, 0), "goto_next_jump_no_skips_direct", 30, "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:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 66 },
{ PROC_LINKS(goto_next_jump_no_skips_sticky, 0), "goto_next_jump_no_skips_sticky", 30, "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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 484 },
@ -269,22 +269,22 @@ static Command_Metadata fcoder_metacmd_table[194] = {
{ PROC_LINKS(goto_prev_jump_no_skips_direct, 0), "goto_prev_jump_no_skips_direct", 30, "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:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 75 },
{ PROC_LINKS(goto_prev_jump_no_skips_sticky, 0), "goto_prev_jump_no_skips_sticky", 30, "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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 500 },
{ PROC_LINKS(goto_prev_jump_sticky, 0), "goto_prev_jump_sticky", 21, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "C:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 470 },
{ PROC_LINKS(hide_filebar, 0), "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 478 },
{ PROC_LINKS(hide_scrollbar, 0), "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 464 },
{ PROC_LINKS(hide_filebar, 0), "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 471 },
{ PROC_LINKS(hide_scrollbar, 0), "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 457 },
{ PROC_LINKS(highlight_next_scope_absolute, 0), "highlight_next_scope_absolute", 29, "Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.", 102, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 363 },
{ PROC_LINKS(highlight_prev_scope_absolute, 0), "highlight_prev_scope_absolute", 29, "Finds the first scope started by '{' before the cursor and puts the cursor and mark on the '{' and '}'.", 103, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 382 },
{ PROC_LINKS(highlight_surrounding_scope, 0), "highlight_surrounding_scope", 27, "Finds the scope enclosed by '{' '}' surrounding the cursor and puts the cursor and mark on the '{' and '}'.", 107, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 341 },
{ PROC_LINKS(if0_off, 0), "if0_off", 7, "Surround the range between the cursor and mark with an '#if 0' and an '#endif'", 78, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 83 },
{ PROC_LINKS(increase_face_size, 0), "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 526 },
{ PROC_LINKS(increase_line_wrap, 0), "increase_line_wrap", 18, "Increases the current buffer's width for line wrapping.", 55, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 504 },
{ PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1440 },
{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1416 },
{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1422 },
{ PROC_LINKS(interactive_open_or_new, 0), "interactive_open_or_new", 23, "Interactively opens or creates a new file.", 42, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1428 },
{ PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1434 },
{ PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1458 },
{ PROC_LINKS(if0_off, 0), "if0_off", 7, "Surround the range between the cursor and mark with an '#if 0' and an '#endif'", 78, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 82 },
{ PROC_LINKS(increase_face_size, 0), "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 519 },
{ PROC_LINKS(increase_line_wrap, 0), "increase_line_wrap", 18, "Increases the current buffer's width for line wrapping.", 55, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 497 },
{ PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1433 },
{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1409 },
{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1415 },
{ PROC_LINKS(interactive_open_or_new, 0), "interactive_open_or_new", 23, "Interactively opens or creates a new file.", 42, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1421 },
{ PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1427 },
{ PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1451 },
{ PROC_LINKS(kill_rect, 0), "kill_rect", 9, "Delete characters in a rectangular region. Range testing is done by unwrapped-xy coordinates.", 93, "C:\\work\\4ed\\code\\4coder_experiments.cpp", 43, 29 },
{ PROC_LINKS(left_adjust_view, 0), "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 142 },
{ PROC_LINKS(left_adjust_view, 0), "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 135 },
{ PROC_LINKS(list_all_functions_current_buffer, 0), "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:\\work\\4ed\\code\\4coder_function_list.cpp", 45, 318 },
{ PROC_LINKS(list_all_locations, 0), "list_all_locations", 18, "Queries the user for a string and lists all exact case-sensitive matches found in all open buffers.", 99, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 741 },
{ PROC_LINKS(list_all_locations_case_insensitive, 0), "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:\\work\\4ed\\code\\4coder_search.cpp", 38, 753 },
@ -297,22 +297,22 @@ static Command_Metadata fcoder_metacmd_table[194] = {
{ PROC_LINKS(list_all_substring_locations, 0), "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:\\work\\4ed\\code\\4coder_search.cpp", 38, 747 },
{ PROC_LINKS(list_all_substring_locations_case_insensitive, 0), "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:\\work\\4ed\\code\\4coder_search.cpp", 38, 759 },
{ PROC_LINKS(load_project, 0), "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:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 426 },
{ PROC_LINKS(make_directory_query, 0), "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1108 },
{ PROC_LINKS(make_directory_query, 0), "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1101 },
{ PROC_LINKS(miblo_decrement_basic, 0), "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "C:\\work\\4ed\\code\\4coder_miblo_numbers.cpp", 45, 110 },
{ PROC_LINKS(miblo_decrement_time_stamp, 0), "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:\\work\\4ed\\code\\4coder_miblo_numbers.cpp", 45, 383 },
{ PROC_LINKS(miblo_decrement_time_stamp_minute, 0), "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:\\work\\4ed\\code\\4coder_miblo_numbers.cpp", 45, 395 },
{ PROC_LINKS(miblo_increment_basic, 0), "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "C:\\work\\4ed\\code\\4coder_miblo_numbers.cpp", 45, 94 },
{ PROC_LINKS(miblo_increment_time_stamp, 0), "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:\\work\\4ed\\code\\4coder_miblo_numbers.cpp", 45, 377 },
{ PROC_LINKS(miblo_increment_time_stamp_minute, 0), "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:\\work\\4ed\\code\\4coder_miblo_numbers.cpp", 45, 389 },
{ PROC_LINKS(move_down, 0), "move_down", 9, "Moves the cursor down one line.", 31, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 257 },
{ PROC_LINKS(move_down_10, 0), "move_down_10", 12, "Moves the cursor down ten lines.", 32, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 269 },
{ PROC_LINKS(move_down_textual, 0), "move_down_textual", 17, "Moves down to the next line of actual text, regardless of line wrapping.", 72, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 275 },
{ PROC_LINKS(move_left, 0), "move_left", 9, "Moves the cursor one character to the left.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 306 },
{ PROC_LINKS(move_line_down, 0), "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1205 },
{ PROC_LINKS(move_line_up, 0), "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1141 },
{ PROC_LINKS(move_right, 0), "move_right", 10, "Moves the cursor one character to the right.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 315 },
{ PROC_LINKS(move_up, 0), "move_up", 7, "Moves the cursor up one line.", 29, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 251 },
{ PROC_LINKS(move_up_10, 0), "move_up_10", 10, "Moves the cursor up ten lines.", 30, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 263 },
{ PROC_LINKS(move_down, 0), "move_down", 9, "Moves the cursor down one line.", 31, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 250 },
{ PROC_LINKS(move_down_10, 0), "move_down_10", 12, "Moves the cursor down ten lines.", 32, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 262 },
{ PROC_LINKS(move_down_textual, 0), "move_down_textual", 17, "Moves down to the next line of actual text, regardless of line wrapping.", 72, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 268 },
{ PROC_LINKS(move_left, 0), "move_left", 9, "Moves the cursor one character to the left.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 299 },
{ PROC_LINKS(move_line_down, 0), "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1198 },
{ PROC_LINKS(move_line_up, 0), "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1134 },
{ PROC_LINKS(move_right, 0), "move_right", 10, "Moves the cursor one character to the right.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 308 },
{ PROC_LINKS(move_up, 0), "move_up", 7, "Moves the cursor up one line.", 29, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 244 },
{ PROC_LINKS(move_up_10, 0), "move_up_10", 10, "Moves the cursor up ten lines.", 30, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 256 },
{ PROC_LINKS(multi_line_edit, 0), "multi_line_edit", 15, "Begin multi-line mode. In multi-line mode characters are inserted at every line between the mark and cursor. All characters are inserted at the same character offset into the line. This mode uses line_char coordinates.", 221, "C:\\work\\4ed\\code\\4coder_experiments.cpp", 43, 120 },
{ PROC_LINKS(newline_or_goto_position_direct, 0), "newline_or_goto_position_direct", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "C:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 101 },
{ PROC_LINKS(newline_or_goto_position_same_panel_direct, 0), "newline_or_goto_position_same_panel_direct", 42, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "C:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 116 },
@ -320,17 +320,17 @@ static Command_Metadata fcoder_metacmd_table[194] = {
{ PROC_LINKS(newline_or_goto_position_sticky, 0), "newline_or_goto_position_sticky", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "C:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 556 },
{ PROC_LINKS(open_all_code, 0), "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:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 410 },
{ PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 417 },
{ PROC_LINKS(open_color_tweaker, 0), "open_color_tweaker", 18, "Opens the 4coder colors and fonts selector menu.", 48, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1464 },
{ PROC_LINKS(open_file_in_quotes, 0), "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1327 },
{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Switches to the next active panel and begins an open file dialogue.", 67, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1472 },
{ PROC_LINKS(open_long_braces, 0), "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 59 },
{ PROC_LINKS(open_long_braces_break, 0), "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 75 },
{ PROC_LINKS(open_long_braces_semicolon, 0), "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 67 },
{ PROC_LINKS(open_matching_file_cpp, 0), "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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1363 },
{ PROC_LINKS(open_panel_hsplit, 0), "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 208 },
{ PROC_LINKS(open_panel_vsplit, 0), "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 199 },
{ PROC_LINKS(page_down, 0), "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 295 },
{ PROC_LINKS(page_up, 0), "page_up", 7, "Scrolls the view up one view height and moves the cursor up one view height.", 76, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 286 },
{ PROC_LINKS(open_color_tweaker, 0), "open_color_tweaker", 18, "Opens the 4coder colors and fonts selector menu.", 48, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1457 },
{ PROC_LINKS(open_file_in_quotes, 0), "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1320 },
{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Switches to the next active panel and begins an open file dialogue.", 67, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1465 },
{ PROC_LINKS(open_long_braces, 0), "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 58 },
{ PROC_LINKS(open_long_braces_break, 0), "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 74 },
{ PROC_LINKS(open_long_braces_semicolon, 0), "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 66 },
{ PROC_LINKS(open_matching_file_cpp, 0), "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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1356 },
{ PROC_LINKS(open_panel_hsplit, 0), "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 174 },
{ PROC_LINKS(open_panel_vsplit, 0), "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 165 },
{ PROC_LINKS(page_down, 0), "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 288 },
{ PROC_LINKS(page_up, 0), "page_up", 7, "Scrolls the view up one view height and moves the cursor up one view height.", 76, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 279 },
{ PROC_LINKS(paste, 0), "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "C:\\work\\4ed\\code\\4coder_clipboard.cpp", 41, 46 },
{ PROC_LINKS(paste_and_indent, 0), "paste_and_indent", 16, "Paste from the top of clipboard and run auto-indent on the newly pasted text.", 77, "C:\\work\\4ed\\code\\4coder_clipboard.cpp", 41, 128 },
{ PROC_LINKS(paste_next, 0), "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:\\work\\4ed\\code\\4coder_clipboard.cpp", 41, 84 },
@ -338,25 +338,25 @@ static Command_Metadata fcoder_metacmd_table[194] = {
{ PROC_LINKS(place_in_scope, 0), "place_in_scope", 14, "Wraps the code contained in the range between cursor and mark with a new curly brace scope.", 91, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 481 },
{ PROC_LINKS(project_fkey_command, 0), "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:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 497 },
{ PROC_LINKS(project_go_to_root_directory, 0), "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:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 522 },
{ PROC_LINKS(query_replace, 0), "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 900 },
{ PROC_LINKS(query_replace_identifier, 0), "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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 920 },
{ PROC_LINKS(query_replace_selection, 0), "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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 938 },
{ PROC_LINKS(redo, 0), "redo", 4, "Advances forewards through the undo history.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1410 },
{ PROC_LINKS(query_replace, 0), "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 893 },
{ PROC_LINKS(query_replace_identifier, 0), "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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 913 },
{ PROC_LINKS(query_replace_selection, 0), "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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 931 },
{ PROC_LINKS(redo, 0), "redo", 4, "Advances forewards through the undo history.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1403 },
{ PROC_LINKS(reload_current_project, 0), "reload_current_project", 22, "If a project file has already been loaded, reloads the same file. Useful for when the project configuration is changed.", 120, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 465 },
{ PROC_LINKS(remap_interactive, 0), "remap_interactive", 17, "Switch to a named key binding map.", 34, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 594 },
{ PROC_LINKS(rename_file_query, 0), "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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1066 },
{ PROC_LINKS(remap_interactive, 0), "remap_interactive", 17, "Switch to a named key binding map.", 34, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 223 },
{ PROC_LINKS(rename_file_query, 0), "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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1059 },
{ PROC_LINKS(rename_parameter, 0), "rename_parameter", 16, "If the cursor is found to be on the name of a function parameter in the signature of a function definition, all occurences within the scope of the function will be replaced with a new provided string.", 200, "C:\\work\\4ed\\code\\4coder_experiments.cpp", 43, 385 },
{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1446 },
{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1439 },
{ PROC_LINKS(replace_all_occurrences, 0), "replace_all_occurrences", 23, "Queries the user for two strings, and replaces all occurrences of the first string with the second string in all open buffers.", 126, "C:\\work\\4ed\\code\\4coder_experiments.cpp", 43, 771 },
{ PROC_LINKS(replace_in_range, 0), "replace_in_range", 16, "Queries the user for two strings, and replaces all occurences of the first string in the range between the cursor and the mark with the second string.", 150, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 798 },
{ PROC_LINKS(reverse_search, 0), "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 769 },
{ PROC_LINKS(reverse_search_identifier, 0), "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 787 },
{ PROC_LINKS(save, 0), "save", 4, "Saves the current buffer.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1452 },
{ PROC_LINKS(save_all_dirty_buffers, 0), "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 965 },
{ PROC_LINKS(save_to_query, 0), "save_to_query", 13, "Queries the user for a name and saves the contents of the current buffer, altering the buffer's name too.", 105, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1026 },
{ PROC_LINKS(replace_in_range, 0), "replace_in_range", 16, "Queries the user for two strings, and replaces all occurences of the first string in the range between the cursor and the mark with the second string.", 150, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 791 },
{ PROC_LINKS(reverse_search, 0), "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 762 },
{ PROC_LINKS(reverse_search_identifier, 0), "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 780 },
{ PROC_LINKS(save, 0), "save", 4, "Saves the current buffer.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1445 },
{ PROC_LINKS(save_all_dirty_buffers, 0), "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 958 },
{ PROC_LINKS(save_to_query, 0), "save_to_query", 13, "Queries the user for a name and saves the contents of the current buffer, altering the buffer's name too.", 105, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1019 },
{ PROC_LINKS(scope_absorb_down, 0), "scope_absorb_down", 17, "If a scope is currently selected, and a statement or block statement is present below the current scope, the statement is moved into the scope.", 143, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 738 },
{ PROC_LINKS(search, 0), "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 762 },
{ PROC_LINKS(search_identifier, 0), "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 776 },
{ PROC_LINKS(search, 0), "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 755 },
{ PROC_LINKS(search_identifier, 0), "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 769 },
{ PROC_LINKS(seek_alphanumeric_left, 0), "seek_alphanumeric_left", 22, "Seek left for boundary between alphanumeric characters and non-alphanumeric characters.", 87, "C:\\work\\4ed\\code\\4coder_seek.cpp", 36, 1227 },
{ PROC_LINKS(seek_alphanumeric_or_camel_left, 0), "seek_alphanumeric_or_camel_left", 31, "Seek left for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 106, "C:\\work\\4ed\\code\\4coder_seek.cpp", 36, 1239 },
{ PROC_LINKS(seek_alphanumeric_or_camel_right, 0), "seek_alphanumeric_or_camel_right", 32, "Seek right for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 107, "C:\\work\\4ed\\code\\4coder_seek.cpp", 36, 1233 },
@ -375,39 +375,39 @@ static Command_Metadata fcoder_metacmd_table[194] = {
{ PROC_LINKS(seek_whitespace_right, 0), "seek_whitespace_right", 21, "Seek right for the next boundary between whitespace and non-whitespace.", 71, "C:\\work\\4ed\\code\\4coder_seek.cpp", 36, 1185 },
{ PROC_LINKS(seek_whitespace_up, 0), "seek_whitespace_up", 18, "Seeks the cursor up to the next blank line.", 43, "C:\\work\\4ed\\code\\4coder_seek.cpp", 36, 1090 },
{ PROC_LINKS(seek_whitespace_up_end_line, 0), "seek_whitespace_up_end_line", 27, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "C:\\work\\4ed\\code\\4coder_seek.cpp", 36, 1148 },
{ PROC_LINKS(select_all, 0), "select_all", 10, "Puts the cursor at the top of the file, and the mark at the bottom of the file.", 79, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 324 },
{ PROC_LINKS(select_all, 0), "select_all", 10, "Puts the cursor at the top of the file, and the mark at the bottom of the file.", 79, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 317 },
{ PROC_LINKS(set_bindings_choose, 0), "set_bindings_choose", 19, "Remap keybindings using the 'choose' mapping rule.", 50, "C:\\work\\4ed\\code\\4coder_remapping_commands.cpp", 50, 47 },
{ PROC_LINKS(set_bindings_default, 0), "set_bindings_default", 20, "Remap keybindings using the 'default' mapping rule.", 51, "C:\\work\\4ed\\code\\4coder_remapping_commands.cpp", 50, 61 },
{ PROC_LINKS(set_bindings_mac_default, 0), "set_bindings_mac_default", 24, "Remap keybindings using the 'mac-default' mapping rule.", 55, "C:\\work\\4ed\\code\\4coder_remapping_commands.cpp", 50, 75 },
{ PROC_LINKS(set_mark, 0), "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 93 },
{ PROC_LINKS(set_mark, 0), "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 86 },
{ PROC_LINKS(setup_new_project, 0), "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:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 569 },
{ PROC_LINKS(show_filebar, 0), "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 471 },
{ PROC_LINKS(show_scrollbar, 0), "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 457 },
{ PROC_LINKS(show_filebar, 0), "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 464 },
{ PROC_LINKS(show_scrollbar, 0), "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 450 },
{ PROC_LINKS(snipe_token_or_word, 0), "snipe_token_or_word", 19, "Delete a single, whole token on or to the left of the cursor and post it to the clipboard.", 90, "C:\\work\\4ed\\code\\4coder_seek.cpp", 36, 1259 },
{ PROC_LINKS(snipe_token_or_word_right, 0), "snipe_token_or_word_right", 25, "Delete a single, whole token on or to the right of the cursor and post it to the clipboard.", 91, "C:\\work\\4ed\\code\\4coder_seek.cpp", 36, 1265 },
{ PROC_LINKS(suppress_mouse, 0), "suppress_mouse", 14, "Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.", 83, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 231 },
{ PROC_LINKS(swap_buffers_between_panels, 0), "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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1387 },
{ PROC_LINKS(to_lowercase, 0), "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 355 },
{ PROC_LINKS(to_uppercase, 0), "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 335 },
{ PROC_LINKS(toggle_filebar, 0), "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 485 },
{ PROC_LINKS(toggle_fullscreen, 0), "toggle_fullscreen", 17, "Toggle fullscreen mode on or off. The change(s) do not take effect until the next frame.", 89, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 249 },
{ PROC_LINKS(toggle_line_wrap, 0), "toggle_line_wrap", 16, "Toggles the current buffer's line wrapping status.", 50, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 494 },
{ PROC_LINKS(toggle_mouse, 0), "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 243 },
{ PROC_LINKS(toggle_show_whitespace, 0), "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 561 },
{ PROC_LINKS(toggle_virtual_whitespace, 0), "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 550 },
{ PROC_LINKS(undo, 0), "undo", 4, "Advances backwards through the undo history.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1404 },
{ PROC_LINKS(view_buffer_other_panel, 0), "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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1377 },
{ PROC_LINKS(suppress_mouse, 0), "suppress_mouse", 14, "Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.", 83, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 197 },
{ PROC_LINKS(swap_buffers_between_panels, 0), "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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1380 },
{ PROC_LINKS(to_lowercase, 0), "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 348 },
{ PROC_LINKS(to_uppercase, 0), "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 328 },
{ PROC_LINKS(toggle_filebar, 0), "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 478 },
{ PROC_LINKS(toggle_fullscreen, 0), "toggle_fullscreen", 17, "Toggle fullscreen mode on or off. The change(s) do not take effect until the next frame.", 89, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 215 },
{ PROC_LINKS(toggle_line_wrap, 0), "toggle_line_wrap", 16, "Toggles the current buffer's line wrapping status.", 50, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 487 },
{ PROC_LINKS(toggle_mouse, 0), "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "C:\\work\\4ed\\code\\4coder_default_framework.cpp", 49, 209 },
{ PROC_LINKS(toggle_show_whitespace, 0), "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 554 },
{ PROC_LINKS(toggle_virtual_whitespace, 0), "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 543 },
{ PROC_LINKS(undo, 0), "undo", 4, "Advances backwards through the undo history.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1397 },
{ PROC_LINKS(view_buffer_other_panel, 0), "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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1370 },
{ PROC_LINKS(word_complete, 0), "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:\\work\\4ed\\code\\4coder_search.cpp", 38, 820 },
{ PROC_LINKS(write_and_auto_tab, 0), "write_and_auto_tab", 18, "Inserts a character and auto-indents the line on which the cursor sits.", 71, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 745 },
{ PROC_LINKS(write_block, 0), "write_block", 11, "At the cursor, insert a block comment.", 38, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 107 },
{ PROC_LINKS(write_block, 0), "write_block", 11, "At the cursor, insert a block comment.", 38, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 106 },
{ PROC_LINKS(write_character, 0), "write_character", 15, "Inserts whatever character was used to trigger this command.", 60, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 33 },
{ PROC_LINKS(write_explicit_enum_flags, 0), "write_explicit_enum_flags", 25, "If the cursor is found to be on the '{' of an enum definition, the values of the enum will be filled in to give each a unique power of 2 value, starting from 1. Existing values are overwritten.", 194, "C:\\work\\4ed\\code\\4coder_experiments.cpp", 43, 707 },
{ PROC_LINKS(write_explicit_enum_values, 0), "write_explicit_enum_values", 26, "If the cursor is found to be on the '{' of an enum definition, the values of the enum will be filled in sequentially starting from zero. Existing values are overwritten.", 170, "C:\\work\\4ed\\code\\4coder_experiments.cpp", 43, 701 },
{ PROC_LINKS(write_hack, 0), "write_hack", 10, "At the cursor, insert a '// HACK' comment, includes user name if it was specified in config.4coder.", 99, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 95 },
{ PROC_LINKS(write_note, 0), "write_note", 10, "At the cursor, insert a '// NOTE' comment, includes user name if it was specified in config.4coder.", 99, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 101 },
{ PROC_LINKS(write_todo, 0), "write_todo", 10, "At the cursor, insert a '// TODO' comment, includes user name if it was specified in config.4coder.", 99, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 89 },
{ PROC_LINKS(write_underscore, 0), "write_underscore", 16, "Inserts an underscore.", 22, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 49 },
{ PROC_LINKS(write_zero_struct, 0), "write_zero_struct", 17, "At the cursor, insert a ' = {0};'.", 34, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 113 },
{ PROC_LINKS(write_hack, 0), "write_hack", 10, "At the cursor, insert a '// HACK' comment, includes user name if it was specified in config.4coder.", 99, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 94 },
{ PROC_LINKS(write_note, 0), "write_note", 10, "At the cursor, insert a '// NOTE' comment, includes user name if it was specified in config.4coder.", 99, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 100 },
{ PROC_LINKS(write_todo, 0), "write_todo", 10, "At the cursor, insert a '// TODO' comment, includes user name if it was specified in config.4coder.", 99, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 88 },
{ PROC_LINKS(write_underscore, 0), "write_underscore", 16, "Inserts an underscore.", 22, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 42 },
{ PROC_LINKS(write_zero_struct, 0), "write_zero_struct", 17, "At the cursor, insert a ' = {0};'.", 34, "C:\\work\\4ed\\code\\4coder_combined_write_commands.cpp", 55, 112 },
};
static int32_t fcoder_metacmd_ID_allow_mouse = 0;
static int32_t fcoder_metacmd_ID_auto_tab_line_at_cursor = 1;

View File

@ -1120,5 +1120,139 @@ build_string(Partition *part, String s0, String s1, String s2){
return(sr);
}
static void
lexer_keywords_default_init(Partition *part, Cpp_Keyword_Table *kw_out, Cpp_Keyword_Table *pp_out){
umem_4tech kw_size = cpp_get_table_memory_size_default(CPP_TABLE_KEYWORDS);
umem_4tech pp_size = cpp_get_table_memory_size_default(CPP_TABLE_PREPROCESSOR_DIRECTIVES);
void *kw_mem = push_array(part, char, (i32_4tech)kw_size);
void *pp_mem = push_array(part, char, (i32_4tech)pp_size);
*kw_out = cpp_make_table_default(CPP_TABLE_KEYWORDS, kw_mem, kw_size);
*pp_out = cpp_make_table_default(CPP_TABLE_PREPROCESSOR_DIRECTIVES, pp_mem, pp_size);
}
////////////////////////////////
// TODO(allen): Stop handling files this way! My own API should be able to do this!!?!?!?!!?!?!!!!?
// NOTE(allen): Actually need binary buffers for some stuff to work, but not this parsing thing here.
#include <stdio.h>
static String
dump_file_handle(Partition *arena, FILE *file){
String str = {0};
if (file != 0){
fseek(file, 0, SEEK_END);
int32_t size = ftell(file);
char *mem = push_array(arena, char, size + 1);
push_align(arena, 8);
if (mem != 0){
fseek(file, 0, SEEK_SET);
fread(mem, 1, size, file);
mem[size] = 0;
str = make_string_cap(mem, size, size + 1);
}
}
return(str);
}
static FILE*
open_file_search_up_path(Partition *scratch, String path, String file_name){
Temp_Memory temp = begin_temp_memory(scratch);
int32_t cap = path.size + file_name.size + 2;
char *space = push_array(scratch, char, cap);
String name_str = make_string_cap(space, 0, cap);
append(&name_str, path);
if (name_str.size == 0 || !char_is_slash(name_str.str[name_str.size - 1])){
append(&name_str, "/");
}
FILE *file = 0;
for (;;){
int32_t base_size = name_str.size;
append(&name_str, file_name);
terminate_with_null(&name_str);
file = fopen(name_str.str, "rb");
if (file != 0){
break;
}
name_str.size = base_size;
remove_last_folder(&name_str);
if (name_str.size >= base_size){
break;
}
}
end_temp_memory(temp);
return(file);
}
static FILE*
open_file_try_current_path_then_binary_path(Application_Links *app, char *file_name){
FILE *file = fopen(file_name, "rb");
if (file == 0){
char space[256];
int32_t size = get_4ed_path(app, space, sizeof(space));
String str = make_string_cap(space, size, sizeof(space));
append(&str, "/");
append(&str, file_name);
if (terminate_with_null(&str)){
file = fopen(str.str, "rb");
}
}
return(file);
}
static char*
get_null_terminated(Partition *scratch, String name){
char *name_terminated = 0;
if (name.size < name.memory_size){
terminate_with_null(&name);
name_terminated = name.str;
}
else{
name_terminated = push_array(scratch, char, name.size + 1);
if (name_terminated != 0){
memcpy(name_terminated, name.str, name.size);
name_terminated[name.size] = 0;
}
}
return(name_terminated);
}
static FILE*
open_file(Partition *scratch, String name){
FILE *file = 0;
Temp_Memory temp = begin_temp_memory(scratch);
char *name_terminated = get_null_terminated(scratch, name);
if (name_terminated != 0){
file = fopen(name_terminated, "rb");
}
end_temp_memory(temp);
return(file);
}
static String
dump_file(Partition *arena, String name){
String result = {0};
FILE *file = open_file(arena, name);
if (file != 0){
result = dump_file_handle(arena, file);
fclose(file);
}
return(result);
}
static String
dump_file_search_up_path(Partition *arena, String path, String file_name){
String result = {0};
FILE *file = open_file_search_up_path(arena, path, file_name);
if (file != 0){
result = dump_file_handle(arena, file);
fclose(file);
}
return(result);
}
// BOTTOM

View File

@ -65,10 +65,16 @@ max_f32_proc(void){
# define Swap(T,a,b) do{ T t = a; a = b; b = t; } while(0)
#endif
#define require(c) if (!(c)){ return(0); }
////////////////////////////////
struct Buffer_Rect{
int32_t char0, line0;
int32_t char1, line1;
};
int32_t char0;
int32_t line0;
int32_t char1;
int32_t line1;
};
////////////////////////////////

View File

@ -1499,6 +1499,7 @@ string_interpret_escapes(String src, char *dst){
case 'n': {dst[j++] = '\n'; mode = 0;}break;
case 't': {dst[j++] = '\t'; mode = 0;}break;
case '"': {dst[j++] = '"'; mode = 0;}break;
case '\'':{dst[j++] = '\''; mode = 0;}break;
case '0': {dst[j++] = '\0'; mode = 0;}break;
}
}break;

View File

@ -624,14 +624,16 @@ CUSTOM_DOC("Queries the user for several configuration options and initializes a
FILE *bat_script = fopen(str.str, "wb");
if (bat_script != 0){
fprintf(bat_script, "@echo off\n\n");
fprintf(bat_script, "SET OPTS=%.*s\n",
default_flags_bat.size, default_flags_bat.str);
fprintf(bat_script, "SET CODE_HOME=%%cd%%\n");
fprintf(bat_script, "set opts=%.*s\n",
global_config.default_flags_bat.size,
global_config.default_flags_bat.str);
fprintf(bat_script, "set code=%%cd%%\n");
fprintf(bat_script, "pushd %.*s\n",
output_dir.size, output_dir.str);
fprintf(bat_script, "%.*s %%OPTS%% %%CODE_HOME%%\\%.*s -Fe%.*s\n",
default_compiler_bat.size, default_compiler_bat.str,
fprintf(bat_script, "%.*s %%opts%% %%code%%\\%.*s -Fe%.*s\n",
global_config.default_compiler_bat.size,
global_config.default_compiler_bat.str,
code_file.size, code_file.str,
binary_file.size, binary_file.str);
fprintf(bat_script, "popd\n");
@ -658,18 +660,20 @@ CUSTOM_DOC("Queries the user for several configuration options and initializes a
if (sh_script != 0){
fprintf(sh_script, "#!/bin/bash\n\n");
fprintf(sh_script, "CODE_HOME=\"$PWD\"\n");
fprintf(sh_script, "code=\"$PWD\"\n");
fprintf(sh_script, "OPTS=%.*s\n",
default_flags_sh.size, default_flags_sh.str);
fprintf(sh_script, "opts=%.*s\n",
global_config.default_flags_sh.size,
global_config.default_flags_sh.str);
fprintf(sh_script, "cd %.*s > /dev/null\n",
output_dir.size, output_dir.str);
fprintf(sh_script, "%.*s $OPTS $CODE_HOME/%.*s -o %.*s\n",
default_compiler_sh.size, default_compiler_sh.str,
fprintf(sh_script, "%.*s $opts $code/%.*s -o %.*s\n",
global_config.default_compiler_sh.size,
global_config.default_compiler_sh.str,
code_file.size, code_file.str,
binary_file.size, binary_file.str);
fprintf(sh_script, "cd $CODE_HOME > /dev/null\n");
fprintf(sh_script, "cd $code > /dev/null\n");
fclose(sh_script);
}