setup the remapping commands, restructured the 4coder mapping internals, started working on global_set_mapping

master
Allen Webster 2017-11-08 13:24:30 -05:00
parent 7aa46e8c48
commit dca823fe4f
20 changed files with 822 additions and 626 deletions

View File

@ -1,5 +1,6 @@
struct Application_Links;
#define GLOBAL_SET_SETTING_SIG(n) bool32 n(Application_Links *app, Global_Setting_ID setting, int32_t value)
#define GLOBAL_SET_MAPPING_SIG(n) bool32 n(Application_Links *app, void *data, int32_t size)
#define EXEC_COMMAND_SIG(n) bool32 n(Application_Links *app, Command_ID command_id)
#define EXEC_SYSTEM_COMMAND_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Identifier buffer_id, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags)
#define CLIPBOARD_POST_SIG(n) void n(Application_Links *app, int32_t clipboard_id, char *str, int32_t len)
@ -76,6 +77,7 @@ struct Application_Links;
#define IS_FULLSCREEN_SIG(n) bool32 n(Application_Links *app)
#define SEND_EXIT_SIGNAL_SIG(n) void n(Application_Links *app)
typedef GLOBAL_SET_SETTING_SIG(Global_Set_Setting_Function);
typedef GLOBAL_SET_MAPPING_SIG(Global_Set_Mapping_Function);
typedef EXEC_COMMAND_SIG(Exec_Command_Function);
typedef EXEC_SYSTEM_COMMAND_SIG(Exec_System_Command_Function);
typedef CLIPBOARD_POST_SIG(Clipboard_Post_Function);
@ -154,6 +156,7 @@ typedef SEND_EXIT_SIGNAL_SIG(Send_Exit_Signal_Function);
struct Application_Links{
#if defined(ALLOW_DEP_4CODER)
Global_Set_Setting_Function *global_set_setting;
Global_Set_Mapping_Function *global_set_mapping;
Exec_Command_Function *exec_command;
Exec_System_Command_Function *exec_system_command;
Clipboard_Post_Function *clipboard_post;
@ -231,6 +234,7 @@ Is_Fullscreen_Function *is_fullscreen;
Send_Exit_Signal_Function *send_exit_signal;
#else
Global_Set_Setting_Function *global_set_setting_;
Global_Set_Mapping_Function *global_set_mapping_;
Exec_Command_Function *exec_command_;
Exec_System_Command_Function *exec_system_command_;
Clipboard_Post_Function *clipboard_post_;
@ -316,6 +320,7 @@ int32_t type_coroutine;
};
#define FillAppLinksAPI(app_links) do{\
app_links->global_set_setting_ = Global_Set_Setting;\
app_links->global_set_mapping_ = Global_Set_Mapping;\
app_links->exec_command_ = Exec_Command;\
app_links->exec_system_command_ = Exec_System_Command;\
app_links->clipboard_post_ = Clipboard_Post;\
@ -393,6 +398,7 @@ app_links->is_fullscreen_ = Is_Fullscreen;\
app_links->send_exit_signal_ = Send_Exit_Signal;} while(false)
#if defined(ALLOW_DEP_4CODER)
static inline bool32 global_set_setting(Application_Links *app, Global_Setting_ID setting, int32_t value){return(app->global_set_setting(app, setting, value));}
static inline bool32 global_set_mapping(Application_Links *app, void *data, int32_t size){return(app->global_set_mapping(app, data, size));}
static inline bool32 exec_command(Application_Links *app, Command_ID command_id){return(app->exec_command(app, command_id));}
static inline bool32 exec_system_command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer_id, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags){return(app->exec_system_command(app, view, buffer_id, path, path_len, command, command_len, flags));}
static inline void clipboard_post(Application_Links *app, int32_t clipboard_id, char *str, int32_t len){(app->clipboard_post(app, clipboard_id, str, len));}
@ -470,6 +476,7 @@ static inline bool32 is_fullscreen(Application_Links *app){return(app->is_fullsc
static inline void send_exit_signal(Application_Links *app){(app->send_exit_signal(app));}
#else
static inline bool32 global_set_setting(Application_Links *app, Global_Setting_ID setting, int32_t value){return(app->global_set_setting_(app, setting, value));}
static inline bool32 global_set_mapping(Application_Links *app, void *data, int32_t size){return(app->global_set_mapping_(app, data, size));}
static inline bool32 exec_command(Application_Links *app, Command_ID command_id){return(app->exec_command_(app, command_id));}
static inline bool32 exec_system_command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer_id, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags){return(app->exec_system_command_(app, view, buffer_id, path, path_len, command, command_len, flags));}
static inline void clipboard_post(Application_Links *app, int32_t clipboard_id, char *str, int32_t len){(app->clipboard_post_(app, clipboard_id, str, len));}

View File

@ -857,6 +857,7 @@ DOC(Values for built in command maps.)
ENUM(int32_t, Map_ID){
mapid_global = (1 << 24),
mapid_file,
mapid_ui,
mapid_nomap
};

View File

@ -11,202 +11,11 @@ TYPE: 'build-target'
#include "4coder_default_include.cpp"
void
default_keys(Bind_Helper *context){
begin_map(context, mapid_global);
bind(context, 'p', MDFR_CTRL, open_panel_vsplit);
bind(context, '_', MDFR_CTRL, open_panel_hsplit);
bind(context, 'P', MDFR_CTRL, close_panel);
bind(context, ',', MDFR_CTRL, change_active_panel);
bind(context, '<', MDFR_CTRL, change_active_panel_backwards);
bind(context, 'n', MDFR_CTRL, interactive_new);
bind(context, 'o', MDFR_CTRL, interactive_open_or_new);
bind(context, 'o', MDFR_ALT, open_in_other);
bind(context, 'k', MDFR_CTRL, interactive_kill_buffer);
bind(context, 'i', MDFR_CTRL, interactive_switch_buffer);
bind(context, 'w', MDFR_CTRL, save_as);
bind(context, 'h', MDFR_CTRL, project_go_to_root_directory);
bind(context, 'S', MDFR_CTRL, save_all_dirty_buffers);
bind(context, 'c', MDFR_ALT, open_color_tweaker);
bind(context, 'd', MDFR_ALT, open_debug);
bind(context, '.', MDFR_ALT, change_to_build_panel);
bind(context, ',', MDFR_ALT, close_build_panel);
bind(context, 'n', MDFR_ALT, goto_next_error);
bind(context, 'N', MDFR_ALT, goto_prev_error);
bind(context, 'M', MDFR_ALT, goto_first_error);
bind(context, 'm', MDFR_ALT, build_in_build_panel);
bind(context, 'z', MDFR_ALT, execute_any_cli);
bind(context, 'Z', MDFR_ALT, execute_previous_cli);
bind(context, 'x', MDFR_ALT, execute_arbitrary_command);
bind(context, 's', MDFR_ALT, show_scrollbar);
bind(context, 'w', MDFR_ALT, hide_scrollbar);
bind(context, 'b', MDFR_ALT, toggle_filebar);
bind(context, '@', MDFR_ALT, toggle_mouse);
bind(context, key_page_up, MDFR_CTRL, toggle_fullscreen);
bind(context, 'E', MDFR_ALT, exit_4coder);
bind(context, key_f1, MDFR_NONE, project_fkey_command);
bind(context, key_f2, MDFR_NONE, project_fkey_command);
bind(context, key_f3, MDFR_NONE, project_fkey_command);
bind(context, key_f4, MDFR_NONE, project_fkey_command);
bind(context, key_f5, MDFR_NONE, project_fkey_command);
bind(context, key_f6, MDFR_NONE, project_fkey_command);
bind(context, key_f7, MDFR_NONE, project_fkey_command);
bind(context, key_f8, MDFR_NONE, project_fkey_command);
bind(context, key_f9, MDFR_NONE, project_fkey_command);
bind(context, key_f10, MDFR_NONE, project_fkey_command);
bind(context, key_f11, MDFR_NONE, project_fkey_command);
bind(context, key_f12, MDFR_NONE, project_fkey_command);
bind(context, key_f13, MDFR_NONE, project_fkey_command);
bind(context, key_f14, MDFR_NONE, project_fkey_command);
bind(context, key_f15, MDFR_NONE, project_fkey_command);
bind(context, key_f16, MDFR_NONE, project_fkey_command);
end_map(context);
begin_map(context, default_code_map);
// NOTE(allen|a3.1): Set this map (default_code_map == mapid_user_custom) to
// inherit from mapid_file. When searching if a key is bound
// in this map, if it is not found here it will then search mapid_file.
//
// If this is not set, it defaults to mapid_global.
inherit_map(context, mapid_file);
// NOTE(allen|a3.1): Children can override parent's bindings.
bind(context, key_right, MDFR_CTRL, seek_alphanumeric_or_camel_right);
bind(context, key_left, MDFR_CTRL, seek_alphanumeric_or_camel_left);
// NOTE(allen|a3.2): Specific keys can override vanilla keys,
// and write character writes whichever character corresponds
// to the key that triggered the command.
bind(context, '\n', MDFR_NONE, write_and_auto_tab);
bind(context, '\n', MDFR_SHIFT, write_and_auto_tab);
bind(context, '}', MDFR_NONE, write_and_auto_tab);
bind(context, ')', MDFR_NONE, write_and_auto_tab);
bind(context, ']', MDFR_NONE, write_and_auto_tab);
bind(context, ';', MDFR_NONE, write_and_auto_tab);
bind(context, '#', MDFR_NONE, write_and_auto_tab);
bind(context, '\t', MDFR_NONE, word_complete);
bind(context, '\t', MDFR_CTRL, auto_tab_range);
bind(context, '\t', MDFR_SHIFT, auto_tab_line_at_cursor);
bind(context, 'h', MDFR_ALT, write_hack);
bind(context, 'r', MDFR_ALT, write_block);
bind(context, 't', MDFR_ALT, write_todo);
bind(context, 'y', MDFR_ALT, write_note);
bind(context, '[', MDFR_CTRL, open_long_braces);
bind(context, '{', MDFR_CTRL, open_long_braces_semicolon);
bind(context, '}', MDFR_CTRL, open_long_braces_break);
bind(context, 'i', MDFR_ALT, if0_off);
bind(context, '1', MDFR_ALT, open_file_in_quotes);
bind(context, '2', MDFR_ALT, open_matching_file_cpp);
bind(context, '0', MDFR_CTRL, write_zero_struct);
bind(context, 'I', MDFR_CTRL, list_all_functions_current_buffer);
end_map(context);
begin_map(context, mapid_file);
// NOTE(allen|a3.4.4): Binding this essentially binds
// all key combos that would normally insert a character
// into a buffer. If the code for the key is not an enum
// value such as key_left or key_back then it is a vanilla key.
// It is possible to override this binding for individual keys.
bind_vanilla_keys(context, write_character);
// NOTE(allen|a4.0.7): You can now bind left and right clicks.
// They only trigger on mouse presses. Modifiers do work
// so control+click shift+click etc can now have special meanings.
bind(context, key_mouse_left, MDFR_NONE, click_set_cursor);
bind(context, key_mouse_right, MDFR_NONE, click_set_mark);
// NOTE(allen|a4.0.11): You can now bind left and right mouse
// button releases. Modifiers do work so control+release shift+release
// etc can now have special meanings.
bind(context, key_mouse_left_release, MDFR_NONE, click_set_mark);
bind(context, key_left, MDFR_NONE, move_left);
bind(context, key_right, MDFR_NONE, move_right);
bind(context, key_del, MDFR_NONE, delete_char);
bind(context, key_del, MDFR_SHIFT, delete_char);
bind(context, key_back, MDFR_NONE, backspace_char);
bind(context, key_back, MDFR_SHIFT, backspace_char);
bind(context, key_up, MDFR_NONE, move_up);
bind(context, key_down, MDFR_NONE, move_down);
bind(context, key_end, MDFR_NONE, seek_end_of_line);
bind(context, key_home, MDFR_NONE, seek_beginning_of_line);
bind(context, key_page_up, MDFR_NONE, page_up);
bind(context, key_page_down, MDFR_NONE, page_down);
bind(context, key_right, MDFR_CTRL, seek_whitespace_right);
bind(context, key_left, MDFR_CTRL, seek_whitespace_left);
bind(context, key_up, MDFR_CTRL, seek_whitespace_up_end_line);
bind(context, key_down, MDFR_CTRL, seek_whitespace_down_end_line);
bind(context, key_up, MDFR_ALT, move_up_10);
bind(context, key_down, MDFR_ALT, move_down_10);
bind(context, key_back, MDFR_CTRL, backspace_word);
bind(context, key_del, MDFR_CTRL, delete_word);
bind(context, key_back, MDFR_ALT, snipe_token_or_word);
bind(context, key_del, MDFR_ALT, snipe_token_or_word_right);
bind(context, ' ', MDFR_CTRL, set_mark);
bind(context, 'a', MDFR_CTRL, replace_in_range);
bind(context, 'c', MDFR_CTRL, copy);
bind(context, 'd', MDFR_CTRL, delete_range);
bind(context, 'e', MDFR_CTRL, center_view);
bind(context, 'E', MDFR_CTRL, left_adjust_view);
bind(context, 'f', MDFR_CTRL, search);
bind(context, 'F', MDFR_CTRL, list_all_locations);
bind(context, 'F', MDFR_ALT, list_all_substring_locations_case_insensitive);
bind(context, 'g', MDFR_CTRL, goto_line);
bind(context, 'j', MDFR_CTRL, to_lowercase);
bind(context, 'K', MDFR_CTRL, kill_buffer);
bind(context, 'l', MDFR_CTRL, toggle_line_wrap);
bind(context, 'm', MDFR_CTRL, cursor_mark_swap);
bind(context, 'O', MDFR_CTRL, reopen);
bind(context, 'q', MDFR_CTRL, query_replace);
bind(context, 'Q', MDFR_CTRL, query_replace_identifier);
bind(context, 'r', MDFR_CTRL, reverse_search);
bind(context, 's', MDFR_CTRL, save);
bind(context, 't', MDFR_CTRL, search_identifier);
bind(context, 'T', MDFR_CTRL, list_all_locations_of_identifier);
bind(context, 'u', MDFR_CTRL, to_uppercase);
bind(context, 'v', MDFR_CTRL, paste_and_indent);
bind(context, 'v', MDFR_ALT, toggle_virtual_whitespace);
bind(context, 'V', MDFR_CTRL, paste_next_and_indent);
bind(context, 'x', MDFR_CTRL, cut);
bind(context, 'y', MDFR_CTRL, redo);
bind(context, 'z', MDFR_CTRL, undo);
bind(context, '2', MDFR_CTRL, decrease_line_wrap);
bind(context, '3', MDFR_CTRL, increase_line_wrap);
bind(context, '?', MDFR_CTRL, toggle_show_whitespace);
bind(context, '~', MDFR_CTRL, clean_all_lines);
bind(context, '\n', MDFR_NONE, newline_or_goto_position);
bind(context, '\n', MDFR_SHIFT, newline_or_goto_position_same_panel);
bind(context, ' ', MDFR_SHIFT, write_character);
end_map(context);
}
// NOTE(allen|a4.0.22): This no longer serves as very good example code.
// Good example code will be coming soon, but in the mean time you can go
// to 4coder_remapping_commands.cpp for examples of what binding code looks like.
#ifndef NO_BINDING
#if !defined(NO_BINDING)
extern "C" int32_t
get_bindings(void *data, int32_t size){
Bind_Helper context_ = begin_bind_helper(data, size);

View File

@ -677,6 +677,30 @@ lexer_keywords_default_init(Partition *part, Cpp_Keyword_Table *kw_out, Cpp_Keyw
}
//
// Dynamic Mapping Changes
//
struct Named_Mapping{
String name;
Custom_Command_Function *remap_command;
};
static Named_Mapping *named_maps = 0;
static int32_t named_map_count = 0;
static void
change_mapping(Application_Links *app, String mapping){
for (int32_t i = 0; i < named_map_count; ++i){
if (match(mapping, named_maps[i].name)){
exec_command(app, named_maps[i].remap_command);
break;
}
}
print_message(app, literal("Leaving bindings unaltered.\n"));
}
//
// Configuration
//
@ -774,7 +798,7 @@ process_config_file(Application_Links *app){
Partition *part = &global_part;
FILE *file = fopen("config.4coder", "rb");
if (!file){
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));
@ -783,7 +807,7 @@ process_config_file(Application_Links *app){
file = fopen(str.str, "rb");
}
if (file){
if (file != 0){
Temp_Memory temp = begin_temp_memory(part);
char *mem = 0;
@ -793,58 +817,67 @@ process_config_file(Application_Links *app){
if (file_read_success){
fclose(file);
Cpp_Token_Array array;
Cpp_Token_Array array = {0};
array.count = 0;
array.max_count = (1 << 20)/sizeof(Cpp_Token);
array.tokens = push_array(&global_part, Cpp_Token, array.max_count);
array.tokens = push_array(part, Cpp_Token, array.max_count);
Cpp_Keyword_Table kw_table = {0};
Cpp_Keyword_Table pp_table = {0};
lexer_keywords_default_init(part, &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, mem, 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;
if (array.tokens != 0){
Cpp_Keyword_Table kw_table = {0};
Cpp_Keyword_Table pp_table = {0};
lexer_keywords_default_init(part, &kw_table, &pp_table);
for (int32_t i = 0; i < array.count; ++i){
Config_Line config_line = read_config_line(array, &i);
Cpp_Lex_Data S = cpp_lex_data_init(false, kw_table, pp_table);
Cpp_Lex_Result result = cpp_lex_step(&S, mem, 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;
if (config_line.read_success){
Config_Item item = get_config_item(config_line, mem, array);
for (int32_t i = 0; i < array.count; ++i){
Config_Line config_line = read_config_line(array, &i);
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);
{
if (config_line.read_success){
Config_Item item = get_config_item(config_line, mem, 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);
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)){
set_extensions(&treat_as_code_exts, str);
}
config_bool_var(item, "automatically_load_project", 0, &automatically_load_project);
config_bool_var(item, "lalt_lctrl_is_altgr", 0, &lalt_lctrl_is_altgr);
}
config_bool_var(item, "automatically_load_project", 0, &automatically_load_project);
config_bool_var(item, "lalt_lctrl_is_altgr", 0, &lalt_lctrl_is_altgr);
}
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);
}
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"));
}
}

View File

@ -18,7 +18,22 @@ TYPE: 'internal-for-default-system'
#include "languages/4coder_language_cs.h"
#include "languages/4coder_language_java.h"
CUSTOM_COMMAND_SIG(set_bindings_choose);
CUSTOM_COMMAND_SIG(set_bindings_default);
CUSTOM_COMMAND_SIG(set_bindings_mac_4coder_like);
CUSTOM_COMMAND_SIG(set_bindings_mac_default);
static Named_Mapping named_maps_values[] = {
{make_lit_string("choose") , set_bindings_choose },
{make_lit_string("default") , set_bindings_default },
{make_lit_string("mac_4coder_like"), set_bindings_mac_4coder_like},
{make_lit_string("mac_default") , set_bindings_mac_default },
};
START_HOOK_SIG(default_start){
named_maps = named_maps_values;
named_map_count = ArrayCount(named_maps_values);
default_4coder_initialize(app);
default_4coder_side_by_side_panels(app, files, file_count);

View File

@ -518,6 +518,8 @@ CUSTOM_COMMAND_SIG(execute_arbitrary_command){
}
}
#include "4coder_remapping_commands.cpp"
#endif
// BOTTOM

View File

@ -237,12 +237,25 @@ set_input_filter(Bind_Helper *helper, Input_Filter_Function *func){
inline int32_t
end_bind_helper(Bind_Helper *helper){
int32_t result;
if (helper->header){
helper->header->header.total_size = (int32_t)(helper->cursor - helper->start);
helper->header->header.error = helper->error;
}
result = helper->write_total;
int32_t result = helper->write_total;
return(result);
}
struct Bind_Buffer{
void *data;
int32_t size;
};
inline Bind_Buffer
end_bind_helper_get_buffer(Bind_Helper *helper){
int32_t size = end_bind_helper(helper);
Bind_Buffer result = {0};
result.data = helper->start;
result.size = size;
return(result);
}

View File

@ -75,7 +75,10 @@ make_part(void *memory, i32_4tech size){
inline void*
partition_allocate(Partition *data, i32_4tech size){
void *ret = 0;
if (size > 0 && data->pos + size <= data->max){
if (size < 0){
size = 0;
}
if (data->pos + size <= data->max){
ret = data->base + data->pos;
data->pos += size;
}
@ -109,7 +112,7 @@ inline Partition
partition_sub_part(Partition *data, i32_4tech size){
Partition result = {};
void *d = partition_allocate(data, size);
if (d){
if (d != 0){
result = make_part(d, size);
}
return(result);

View File

@ -0,0 +1,279 @@
/*
4coder_remapping_commands.cpp - Commands that remap all of the keys to one of the maps
in the set of default maps.
TYPE: 'drop-in-command-pack'
*/
// TOP
#if !defined(FCODER_REMAPPING_COMMANDS_CPP)
#define FCODER_REMAPPING_COMMANDS_CPP
//
// Buffer Filling Helpers
//
void
default_keys(Bind_Helper *context){
// NOTE(allen|a4.0.22): GLOBAL
begin_map(context, mapid_global);
bind(context, 'p', MDFR_CTRL, open_panel_vsplit);
bind(context, '_', MDFR_CTRL, open_panel_hsplit);
bind(context, 'P', MDFR_CTRL, close_panel);
bind(context, ',', MDFR_CTRL, change_active_panel);
bind(context, '<', MDFR_CTRL, change_active_panel_backwards);
bind(context, 'n', MDFR_CTRL, interactive_new);
bind(context, 'o', MDFR_CTRL, interactive_open_or_new);
bind(context, 'o', MDFR_ALT, open_in_other);
bind(context, 'k', MDFR_CTRL, interactive_kill_buffer);
bind(context, 'i', MDFR_CTRL, interactive_switch_buffer);
bind(context, 'w', MDFR_CTRL, save_as);
bind(context, 'h', MDFR_CTRL, project_go_to_root_directory);
bind(context, 'S', MDFR_CTRL, save_all_dirty_buffers);
bind(context, 'c', MDFR_ALT, open_color_tweaker);
bind(context, 'd', MDFR_ALT, open_debug);
bind(context, '.', MDFR_ALT, change_to_build_panel);
bind(context, ',', MDFR_ALT, close_build_panel);
bind(context, 'n', MDFR_ALT, goto_next_error);
bind(context, 'N', MDFR_ALT, goto_prev_error);
bind(context, 'M', MDFR_ALT, goto_first_error);
bind(context, 'm', MDFR_ALT, build_in_build_panel);
bind(context, 'z', MDFR_ALT, execute_any_cli);
bind(context, 'Z', MDFR_ALT, execute_previous_cli);
bind(context, 'x', MDFR_ALT, execute_arbitrary_command);
bind(context, 's', MDFR_ALT, show_scrollbar);
bind(context, 'w', MDFR_ALT, hide_scrollbar);
bind(context, 'b', MDFR_ALT, toggle_filebar);
bind(context, '@', MDFR_ALT, toggle_mouse);
bind(context, key_page_up, MDFR_CTRL, toggle_fullscreen);
bind(context, 'E', MDFR_ALT, exit_4coder);
bind(context, key_f1, MDFR_NONE, project_fkey_command);
bind(context, key_f2, MDFR_NONE, project_fkey_command);
bind(context, key_f3, MDFR_NONE, project_fkey_command);
bind(context, key_f4, MDFR_NONE, project_fkey_command);
bind(context, key_f5, MDFR_NONE, project_fkey_command);
bind(context, key_f6, MDFR_NONE, project_fkey_command);
bind(context, key_f7, MDFR_NONE, project_fkey_command);
bind(context, key_f8, MDFR_NONE, project_fkey_command);
bind(context, key_f9, MDFR_NONE, project_fkey_command);
bind(context, key_f10, MDFR_NONE, project_fkey_command);
bind(context, key_f11, MDFR_NONE, project_fkey_command);
bind(context, key_f12, MDFR_NONE, project_fkey_command);
bind(context, key_f13, MDFR_NONE, project_fkey_command);
bind(context, key_f14, MDFR_NONE, project_fkey_command);
bind(context, key_f15, MDFR_NONE, project_fkey_command);
bind(context, key_f16, MDFR_NONE, project_fkey_command);
end_map(context);
// NOTE(allen|a4.0.22): FILE
begin_map(context, mapid_file);
bind_vanilla_keys(context, write_character);
bind(context, key_mouse_left, MDFR_NONE, click_set_cursor);
bind(context, key_mouse_right, MDFR_NONE, click_set_mark);
bind(context, key_mouse_left_release, MDFR_NONE, click_set_mark);
bind(context, key_left, MDFR_NONE, move_left);
bind(context, key_right, MDFR_NONE, move_right);
bind(context, key_del, MDFR_NONE, delete_char);
bind(context, key_del, MDFR_SHIFT, delete_char);
bind(context, key_back, MDFR_NONE, backspace_char);
bind(context, key_back, MDFR_SHIFT, backspace_char);
bind(context, key_up, MDFR_NONE, move_up);
bind(context, key_down, MDFR_NONE, move_down);
bind(context, key_end, MDFR_NONE, seek_end_of_line);
bind(context, key_home, MDFR_NONE, seek_beginning_of_line);
bind(context, key_page_up, MDFR_NONE, page_up);
bind(context, key_page_down, MDFR_NONE, page_down);
bind(context, key_right, MDFR_CTRL, seek_whitespace_right);
bind(context, key_left, MDFR_CTRL, seek_whitespace_left);
bind(context, key_up, MDFR_CTRL, seek_whitespace_up_end_line);
bind(context, key_down, MDFR_CTRL, seek_whitespace_down_end_line);
bind(context, key_up, MDFR_ALT, move_up_10);
bind(context, key_down, MDFR_ALT, move_down_10);
bind(context, key_back, MDFR_CTRL, backspace_word);
bind(context, key_del, MDFR_CTRL, delete_word);
bind(context, key_back, MDFR_ALT, snipe_token_or_word);
bind(context, key_del, MDFR_ALT, snipe_token_or_word_right);
bind(context, ' ', MDFR_CTRL, set_mark);
bind(context, 'a', MDFR_CTRL, replace_in_range);
bind(context, 'c', MDFR_CTRL, copy);
bind(context, 'd', MDFR_CTRL, delete_range);
bind(context, 'e', MDFR_CTRL, center_view);
bind(context, 'E', MDFR_CTRL, left_adjust_view);
bind(context, 'f', MDFR_CTRL, search);
bind(context, 'F', MDFR_CTRL, list_all_locations);
bind(context, 'F', MDFR_ALT, list_all_substring_locations_case_insensitive);
bind(context, 'g', MDFR_CTRL, goto_line);
bind(context, 'j', MDFR_CTRL, to_lowercase);
bind(context, 'K', MDFR_CTRL, kill_buffer);
bind(context, 'l', MDFR_CTRL, toggle_line_wrap);
bind(context, 'm', MDFR_CTRL, cursor_mark_swap);
bind(context, 'O', MDFR_CTRL, reopen);
bind(context, 'q', MDFR_CTRL, query_replace);
bind(context, 'Q', MDFR_CTRL, query_replace_identifier);
bind(context, 'r', MDFR_CTRL, reverse_search);
bind(context, 's', MDFR_CTRL, save);
bind(context, 't', MDFR_CTRL, search_identifier);
bind(context, 'T', MDFR_CTRL, list_all_locations_of_identifier);
bind(context, 'u', MDFR_CTRL, to_uppercase);
bind(context, 'v', MDFR_CTRL, paste_and_indent);
bind(context, 'v', MDFR_ALT, toggle_virtual_whitespace);
bind(context, 'V', MDFR_CTRL, paste_next_and_indent);
bind(context, 'x', MDFR_CTRL, cut);
bind(context, 'y', MDFR_CTRL, redo);
bind(context, 'z', MDFR_CTRL, undo);
bind(context, '2', MDFR_CTRL, decrease_line_wrap);
bind(context, '3', MDFR_CTRL, increase_line_wrap);
bind(context, '?', MDFR_CTRL, toggle_show_whitespace);
bind(context, '~', MDFR_CTRL, clean_all_lines);
bind(context, '\n', MDFR_NONE, newline_or_goto_position);
bind(context, '\n', MDFR_SHIFT, newline_or_goto_position_same_panel);
bind(context, ' ', MDFR_SHIFT, write_character);
end_map(context);
// NOTE(allen|a4.0.22): CODE
begin_map(context, default_code_map);
inherit_map(context, mapid_file);
bind(context, key_right, MDFR_CTRL, seek_alphanumeric_or_camel_right);
bind(context, key_left, MDFR_CTRL, seek_alphanumeric_or_camel_left);
bind(context, '\n', MDFR_NONE, write_and_auto_tab);
bind(context, '\n', MDFR_SHIFT, write_and_auto_tab);
bind(context, '}', MDFR_NONE, write_and_auto_tab);
bind(context, ')', MDFR_NONE, write_and_auto_tab);
bind(context, ']', MDFR_NONE, write_and_auto_tab);
bind(context, ';', MDFR_NONE, write_and_auto_tab);
bind(context, '#', MDFR_NONE, write_and_auto_tab);
bind(context, '\t', MDFR_NONE, word_complete);
bind(context, '\t', MDFR_CTRL, auto_tab_range);
bind(context, '\t', MDFR_SHIFT, auto_tab_line_at_cursor);
bind(context, 'h', MDFR_ALT, write_hack);
bind(context, 'r', MDFR_ALT, write_block);
bind(context, 't', MDFR_ALT, write_todo);
bind(context, 'y', MDFR_ALT, write_note);
bind(context, '[', MDFR_CTRL, open_long_braces);
bind(context, '{', MDFR_CTRL, open_long_braces_semicolon);
bind(context, '}', MDFR_CTRL, open_long_braces_break);
bind(context, 'i', MDFR_ALT, if0_off);
bind(context, '1', MDFR_ALT, open_file_in_quotes);
bind(context, '2', MDFR_ALT, open_matching_file_cpp);
bind(context, '0', MDFR_CTRL, write_zero_struct);
bind(context, 'I', MDFR_CTRL, list_all_functions_current_buffer);
end_map(context);
}
void
mac_4coder_like_keys(Bind_Helper *context){
begin_map(context, mapid_global);
bind(context, 'j', MDFR_ALT, execute_arbitrary_command);
end_map(context);
}
void
mac_default_keys(Bind_Helper *context){
begin_map(context, mapid_global);
bind(context, 'x', MDFR_ALT, execute_arbitrary_command);
end_map(context);
}
//
// Remapping Commands
//
static Bind_Helper
get_context_on_global_part(void){
Bind_Helper result = {0};
int32_t size = (1 << 20);
for (;;){
void *data = push_array(&global_part, char, size);
if (data != 0){
result = begin_bind_helper(data, size);
break;
}
size = (size >> 1);
}
return(result);
}
CUSTOM_COMMAND_SIG(set_bindings_choose){
#if defined(_WIN32) || defined(__linux__)
set_bindings_default(app);
#elif defined(__APPLE__) && defined(__MACH__)
set_bindings_mac_default(app);
#endif
}
CUSTOM_COMMAND_SIG(set_bindings_default){
Temp_Memory temp = begin_temp_memory(&global_part);
Bind_Helper context = get_context_on_global_part();
set_all_default_hooks(&context);
default_keys(&context);
Bind_Buffer result = end_bind_helper_get_buffer(&context);
global_set_mapping(app, result.data, result.size);
end_temp_memory(temp);
}
CUSTOM_COMMAND_SIG(set_bindings_mac_4coder_like){
Temp_Memory temp = begin_temp_memory(&global_part);
Bind_Helper context = get_context_on_global_part();
set_all_default_hooks(&context);
mac_4coder_like_keys(&context);
Bind_Buffer result = end_bind_helper_get_buffer(&context);
global_set_mapping(app, result.data, result.size);
end_temp_memory(temp);
}
CUSTOM_COMMAND_SIG(set_bindings_mac_default){
Temp_Memory temp = begin_temp_memory(&global_part);
Bind_Helper context = get_context_on_global_part();
set_all_default_hooks(&context);
mac_default_keys(&context);
Bind_Buffer result = end_bind_helper_get_buffer(&context);
global_set_mapping(app, result.data, result.size);
end_temp_memory(temp);
}
#endif
// BOTTOM

515
4ed.cpp
View File

@ -388,7 +388,7 @@ panel_make_empty(System_Functions *system, Models *models, Panel *panel){
Assert(panel->view == 0);
View_And_ID new_view = live_set_alloc_view(&models->live_set, panel, models);
view_set_file(system, new_view.view, models->scratch_buffer, models);
new_view.view->map = get_map(models, models->scratch_buffer->settings.base_map_id);
new_view.view->map = models->scratch_buffer->settings.base_map_id;
return(new_view.view);
}
@ -604,7 +604,266 @@ COMMAND_DECL(user_callback){
if (binding.custom) binding.custom(&models->app_links);
}
global Command_Function command_table[cmdid_count];
global Command_Function *command_table[cmdid_count];
SCROLL_RULE_SIG(fallback_scroll_rule){
b32 result = false;
if (target_x != *scroll_x){
*scroll_x = target_x;
result = true;
}
if (target_y != *scroll_y){
*scroll_y = target_y;
result = true;
}
return(result);
}
internal void
setup_ui_commands(Command_Map *commands, Partition *part, i32 parent){
map_init(commands, part, 32, parent);
map_clear(commands);
// TODO(allen): This is hacky, when the new UI stuff happens, let's fix it,
// and by that I mean actually fix it, don't just say you fixed it with
// something stupid again.
u8 mdfr_array[] = {MDFR_NONE, MDFR_SHIFT, MDFR_CTRL, MDFR_SHIFT | MDFR_CTRL};
for (i32 i = 0; i < 4; ++i){
u8 mdfr = mdfr_array[i];
map_add(commands, key_left, mdfr, command_null);
map_add(commands, key_right, mdfr, command_null);
map_add(commands, key_up, mdfr, command_null);
map_add(commands, key_down, mdfr, command_null);
map_add(commands, key_back, mdfr, command_null);
}
}
internal void
setup_file_commands(Command_Map *commands, Partition *part, i32 parent){
map_init(commands, part, 10, parent);
}
internal void
setup_top_commands(Command_Map *commands, Partition *part, i32 parent){
map_init(commands, part, 10, parent);
}
internal b32
interpret_binding_buffer(Models *models, void *buffer, i32 size){
b32 result = true;
//General_Memory *gen = &models->mem.general;
Partition *part = &models->mem.part;
Mapping new_mapping = {0};
models->scroll_rule = fallback_scroll_rule;
models->hook_open_file = 0;
models->hook_new_file = 0;
models->hook_save_file = 0;
models->hook_end_file = 0;
models->command_caller = 0;
models->input_filter = 0;
b32 did_top = false;
b32 did_file = false;
Command_Map *map_ptr = 0;
Binding_Unit *unit = (Binding_Unit*)models->app_links.memory;
if (unit->type == unit_header && unit->header.error == 0){
Binding_Unit *end = unit + unit->header.total_size;
i32 user_map_count = unit->header.user_map_count;
new_mapping.map_id_table = push_array(part, i32, user_map_count);
memset(new_mapping.map_id_table, -1, user_map_count*sizeof(i32));
new_mapping.user_maps = push_array(part, Command_Map, user_map_count);
new_mapping.user_map_count = user_map_count;
for (++unit; unit < end; ++unit){
switch (unit->type){
case unit_map_begin:
{
i32 mapid = unit->map_begin.mapid;
i32 count = map_get_count(&new_mapping, mapid);
if (unit->map_begin.replace){
map_set_count(&new_mapping, mapid, unit->map_begin.bind_count);
}
else{
map_set_count(&new_mapping, mapid, unit->map_begin.bind_count + count);
}
}break;
}
}
unit = (Binding_Unit*)models->app_links.memory;
for (++unit; unit < end; ++unit){
switch (unit->type){
case unit_map_begin:
{
i32 mapid = unit->map_begin.mapid;
i32 count = map_get_max_count(&new_mapping, mapid);
i32 table_max = count * 3 / 2;
b32 auto_clear = false;
if (mapid == mapid_global){
map_ptr = &new_mapping.map_top;
auto_clear = map_init(map_ptr, part, table_max, mapid_global);
did_top = true;
}
else if (mapid == mapid_file){
map_ptr = &new_mapping.map_file;
auto_clear = map_init(map_ptr, part, table_max, mapid_global);
did_file = true;
}
else if (mapid < mapid_global){
i32 index = get_or_add_map_index(&new_mapping, mapid);
Assert(index < user_map_count);
map_ptr = new_mapping.user_maps + index;
auto_clear = map_init(map_ptr, part, table_max, mapid_global);
}
else{
map_ptr = 0;
}
if (map_ptr && (unit->map_begin.replace || auto_clear)){
map_clear(map_ptr);
}
}break;
case unit_inherit:
if (map_ptr){
#if 0
Command_Map *parent = 0;
i32 mapid = unit->map_inherit.mapid;
if (mapid == mapid_global){
parent = &new_mapping.map_top;
}
else if (mapid == mapid_file){
parent = &new_mapping.map_file;
}
else if (mapid < mapid_global){
i32 index = get_or_add_map_index(&new_mapping, mapid);
if (index < user_map_count){
parent = new_mapping.user_maps + index;
}
else{
parent = 0;
}
}
map_ptr->parent = parent;
#endif
map_ptr->parent = unit->map_inherit.mapid;
}break;
case unit_binding:
if (map_ptr){
Command_Function *func = 0;
if (unit->binding.command_id >= 0 && unit->binding.command_id < cmdid_count)
func = command_table[unit->binding.command_id];
if (func){
if (unit->binding.code == 0){
u32 index = 0;
if (map_get_modifiers_hash(unit->binding.modifiers, &index)){
map_ptr->vanilla_keyboard_default[index].function = func;
map_ptr->vanilla_keyboard_default[index].custom_id = unit->binding.command_id;
}
}
else{
map_add(map_ptr, unit->binding.code, unit->binding.modifiers, func, unit->binding.command_id);
}
}
}break;
case unit_callback:
if (map_ptr){
Command_Function *func = command_user_callback;
Custom_Command_Function *custom = unit->callback.func;
if (func){
if (unit->callback.code == 0){
u32 index = 0;
if (map_get_modifiers_hash(unit->binding.modifiers, &index)){
map_ptr->vanilla_keyboard_default[index].function = func;
map_ptr->vanilla_keyboard_default[index].custom = custom;
}
}
else{
map_add(map_ptr, unit->callback.code, unit->callback.modifiers, func, custom);
}
}
}break;
case unit_hook:
{
i32 hook_id = unit->hook.hook_id;
if (hook_id >= 0){
if (hook_id < hook_type_count){
models->hooks[hook_id] = (Hook_Function*)unit->hook.func;
}
else{
switch (hook_id){
case special_hook_open_file:
{
models->hook_open_file = (Open_File_Hook_Function*)unit->hook.func;
}break;
case special_hook_new_file:
{
models->hook_new_file = (Open_File_Hook_Function*)unit->hook.func;
}break;
case special_hook_save_file:
{
models->hook_save_file = (Open_File_Hook_Function*)unit->hook.func;
}break;
case special_hook_end_file:
{
models->hook_end_file = (Open_File_Hook_Function*)unit->hook.func;
}break;
case special_hook_command_caller:
{
models->command_caller = (Command_Caller_Hook_Function*)unit->hook.func;
}break;
case special_hook_scroll_rule:
{
models->scroll_rule = (Scroll_Rule_Function*)unit->hook.func;
}break;
case special_hook_input_filter:
{
models->input_filter = (Input_Filter_Function*)unit->hook.func;
}break;
case special_hook_start:
{
models->hook_start = (Start_Hook_Function*)unit->hook.func;
}break;
}
}
}
}break;
}
}
}
if (!did_top){
setup_top_commands(&new_mapping.map_top, part, mapid_global);
}
if (!did_file){
setup_file_commands(&new_mapping.map_file, part, mapid_global);
}
setup_ui_commands(&new_mapping.map_ui, part, mapid_global);
models->mapping = new_mapping;
return(result);
}
#include "4ed_api_implementation.cpp"
@ -646,35 +905,6 @@ app_links_init(System_Functions *system, Application_Links *app_links, void *dat
app_links->system_links = system;
}
internal void
setup_ui_commands(Command_Map *commands, Partition *part, Command_Map *parent){
map_init(commands, part, 32, parent);
map_clear(commands);
// TODO(allen): This is hacky, when the new UI stuff happens, let's fix it,
// and by that I mean actually fix it, don't just say you fixed it with
// something stupid again.
u8 mdfr_array[] = {MDFR_NONE, MDFR_SHIFT, MDFR_CTRL, MDFR_SHIFT | MDFR_CTRL};
for (i32 i = 0; i < 4; ++i){
u8 mdfr = mdfr_array[i];
map_add(commands, key_left, mdfr, command_null);
map_add(commands, key_right, mdfr, command_null);
map_add(commands, key_up, mdfr, command_null);
map_add(commands, key_down, mdfr, command_null);
map_add(commands, key_back, mdfr, command_null);
}
}
internal void
setup_file_commands(Command_Map *commands, Partition *part, Command_Map *parent){
map_init(commands, part, 10, parent);
}
internal void
setup_top_commands(Command_Map *commands, Partition *part, Command_Map *parent){
map_init(commands, part, 10, parent);
}
internal void
setup_command_table(){
#define SET(n) command_table[cmdid_##n] = command_##n
@ -979,19 +1209,6 @@ App_Read_Command_Line_Sig(app_read_command_line){
return(out_size);
}
SCROLL_RULE_SIG(fallback_scroll_rule){
b32 result = false;
if (target_x != *scroll_x){
*scroll_x = target_x;
result = true;
}
if (target_y != *scroll_y){
*scroll_y = target_y;
result = true;
}
return(result);
}
App_Init_Sig(app_init){
App_Vars *vars = (App_Vars*)memory->vars_memory;
Models *models = &vars->models;
@ -1055,202 +1272,14 @@ App_Init_Sig(app_init){
}
{
models->scroll_rule = fallback_scroll_rule;
models->hook_open_file = 0;
models->hook_new_file = 0;
models->hook_save_file = 0;
models->hook_end_file = 0;
models->command_caller = 0;
models->input_filter = 0;
setup_command_table();
Command_Map *global_map = &models->map_top;
Assert(models->config_api.get_bindings != 0);
i32 wanted_size = models->config_api.get_bindings(models->app_links.memory, models->app_links.memory_size);
b32 did_top = false;
b32 did_file = false;
if (wanted_size <= models->app_links.memory_size){
Command_Map *map_ptr = 0;
Binding_Unit *unit = (Binding_Unit*)models->app_links.memory;
if (unit->type == unit_header && unit->header.error == 0){
Binding_Unit *end = unit + unit->header.total_size;
i32 user_map_count = unit->header.user_map_count;
models->map_id_table = push_array(&models->mem.part, i32, user_map_count);
memset(models->map_id_table, -1, user_map_count*sizeof(i32));
models->user_maps = push_array(&models->mem.part, Command_Map, user_map_count);
models->user_map_count = user_map_count;
for (++unit; unit < end; ++unit){
switch (unit->type){
case unit_map_begin:
{
i32 mapid = unit->map_begin.mapid;
i32 count = map_get_count(models, mapid);
if (unit->map_begin.replace){
map_set_count(models, mapid, unit->map_begin.bind_count);
}
else{
map_set_count(models, mapid, unit->map_begin.bind_count + count);
}
};
}
}
unit = (Binding_Unit*)models->app_links.memory;
for (++unit; unit < end; ++unit){
switch (unit->type){
case unit_map_begin:
{
i32 mapid = unit->map_begin.mapid;
i32 count = map_get_max_count(models, mapid);
i32 table_max = count * 3 / 2;
b32 auto_clear = false;
if (mapid == mapid_global){
map_ptr = &models->map_top;
auto_clear = map_init(map_ptr, &models->mem.part, table_max, global_map);
did_top = true;
}
else if (mapid == mapid_file){
map_ptr = &models->map_file;
auto_clear = map_init(map_ptr, &models->mem.part, table_max, global_map);
did_file = true;
}
else if (mapid < mapid_global){
i32 index = get_or_add_map_index(models, mapid);
Assert(index < user_map_count);
map_ptr = models->user_maps + index;
auto_clear = map_init(map_ptr, &models->mem.part, table_max, global_map);
}
else{
map_ptr = 0;
}
if (map_ptr && (unit->map_begin.replace || auto_clear)){
map_clear(map_ptr);
}
}break;
case unit_inherit:
if (map_ptr){
Command_Map *parent = 0;
i32 mapid = unit->map_inherit.mapid;
if (mapid == mapid_global) parent = &models->map_top;
else if (mapid == mapid_file) parent = &models->map_file;
else if (mapid < mapid_global){
i32 index = get_or_add_map_index(models, mapid);
if (index < user_map_count) parent = models->user_maps + index;
else parent = 0;
}
map_ptr->parent = parent;
}break;
case unit_binding:
if (map_ptr){
Command_Function func = 0;
if (unit->binding.command_id >= 0 && unit->binding.command_id < cmdid_count)
func = command_table[unit->binding.command_id];
if (func){
if (unit->binding.code == 0){
u32 index = 0;
if (map_get_modifiers_hash(unit->binding.modifiers, &index)){
map_ptr->vanilla_keyboard_default[index].function = func;
map_ptr->vanilla_keyboard_default[index].custom_id = unit->binding.command_id;
}
}
else{
map_add(map_ptr, unit->binding.code, unit->binding.modifiers, func, unit->binding.command_id);
}
}
}break;
case unit_callback:
if (map_ptr){
Command_Function func = command_user_callback;
Custom_Command_Function *custom = unit->callback.func;
if (func){
if (unit->callback.code == 0){
u32 index = 0;
if (map_get_modifiers_hash(unit->binding.modifiers, &index)){
map_ptr->vanilla_keyboard_default[index].function = func;
map_ptr->vanilla_keyboard_default[index].custom = custom;
}
}
else{
map_add(map_ptr, unit->callback.code, unit->callback.modifiers, func, custom);
}
}
}break;
case unit_hook:
{
i32 hook_id = unit->hook.hook_id;
if (hook_id >= 0){
if (hook_id < hook_type_count){
models->hooks[hook_id] = (Hook_Function*)unit->hook.func;
}
else{
switch (hook_id){
case special_hook_open_file:
{
models->hook_open_file = (Open_File_Hook_Function*)unit->hook.func;
}break;
case special_hook_new_file:
{
models->hook_new_file = (Open_File_Hook_Function*)unit->hook.func;
}break;
case special_hook_save_file:
{
models->hook_save_file = (Open_File_Hook_Function*)unit->hook.func;
}break;
case special_hook_end_file:
{
models->hook_end_file = (Open_File_Hook_Function*)unit->hook.func;
}break;
case special_hook_command_caller:
{
models->command_caller = (Command_Caller_Hook_Function*)unit->hook.func;
}break;
case special_hook_scroll_rule:
{
models->scroll_rule = (Scroll_Rule_Function*)unit->hook.func;
}break;
case special_hook_input_filter:
{
models->input_filter = (Input_Filter_Function*)unit->hook.func;
}break;
case special_hook_start:
{
models->hook_start = (Start_Hook_Function*)unit->hook.func;
}break;
}
}
}
}break;
}
}
}
}
Assert(wanted_size <= models->app_links.memory_size);
interpret_binding_buffer(models, models->app_links.memory, wanted_size);
memset(models->app_links.memory, 0, wanted_size);
if (!did_top) setup_top_commands(&models->map_top, &models->mem.part, global_map);
if (!did_file) setup_file_commands(&models->map_file, &models->mem.part, global_map);
setup_ui_commands(&models->map_ui, &models->mem.part, global_map);
}
// NOTE(allen): file setup
@ -1737,14 +1766,11 @@ App_Step_Sig(app_step){
Key_Event_Data key = get_single_key(&key_data, event->key_i);
cmd->key = key;
Command_Map *map = 0;
if (view){
i32 map = mapid_global;
if (view != 0){
map = view->map;
}
if (map == 0){
map = &models->map_top;
}
Command_Binding cmd_bind = map_extract_recursive(map, key);
Command_Binding cmd_bind = map_extract_recursive(&models->mapping, map, key);
user_in.type = UserInputKey;
user_in.key = key;
@ -1951,14 +1977,9 @@ App_Step_Sig(app_step){
Command_Data *command = cmd;
USE_VIEW(view);
Assert(view);
Assert(view != 0);
Command_Map *map = view->map;
if (map == 0){
map = &models->map_top;
}
Command_Binding cmd_bind = map_extract_recursive(map, key);
Command_Binding cmd_bind = map_extract_recursive(&models->mapping, view->map, key);
if (cmd_bind.function){
if (key.keycode == key_esc){

View File

@ -188,6 +188,20 @@ DOC_SEE(Global_Setting_ID)
return(result);
}
API_EXPORT bool32
Global_Set_Mapping(Application_Links *app, void *data, int32_t size)
/*
DOC_PARAM(data, The beginning of a binding buffer. Bind_Helper is designed to make it easy to produce such a buffer.)
DOC_PARAM(size, The size of the binding buffer in bytes.)
DOC_RETURN(Returns non-zero if no errors occurred while interpretting the binding buffer. A return value of zero does not indicate that the old mappings are still in place.)
DOC(Dumps away the previous mappings and instantiates the mappings described in the binding buffer. If any of the open buffers were bound to a command map that used to exist, but no command map with the same id exist after the new mappings are instantiated, the buffer's command map will be set to mapid_file and a warning will be posted to *messages*.)
*/{
Command_Data *cmd = (Command_Data*)app->cmd_context;
Models *models = cmd->models;
bool32 result = interpret_binding_buffer(models, data, size);
return(result);
}
API_EXPORT bool32
Exec_Command(Application_Links *app, Command_ID command_id)
/*
@ -200,7 +214,7 @@ DOC_SEE(Command_ID)
if (command_id < cmdid_count){
Command_Data *cmd = (Command_Data*)app->cmd_context;
Command_Function function = command_table[command_id];
Command_Function *function = command_table[command_id];
Command_Binding binding = {};
binding.function = function;
if (function) function(cmd->system, cmd, binding);
@ -1042,8 +1056,8 @@ DOC_SEE(Buffer_Setting_ID)
case BufferSetting_MapID:
{
if (value < mapid_global){
new_mapid = get_map_index(models, value);
if (new_mapid < models->user_map_count){
new_mapid = get_map_index(&models->mapping, value);
if (new_mapid < models->mapping.user_map_count){
file->settings.base_map_id = value;
}
else{
@ -1057,7 +1071,7 @@ DOC_SEE(Buffer_Setting_ID)
for (View_Iter iter = file_view_iter_init(&models->layout, file, 0);
file_view_iter_good(iter);
iter = file_view_iter_next(iter)){
iter.view->map = get_map(models, file->settings.base_map_id);
iter.view->map = file->settings.base_map_id;
}
}break;

View File

@ -48,12 +48,7 @@ struct Models{
Font_ID global_font_id;
Command_Map map_top;
Command_Map map_file;
Command_Map map_ui;
Command_Map *user_maps;
i32 *map_id_table;
i32 user_map_count;
Mapping mapping;
Command_Binding prev_command;

View File

@ -12,10 +12,10 @@
#define Command_Function_Sig(name) \
void (name)(System_Functions *system, struct Command_Data *command, struct Command_Binding binding)
typedef Command_Function_Sig(*Command_Function);
typedef Command_Function_Sig(Command_Function);
struct Command_Binding{
Command_Function function;
Command_Function *function;
union{
Custom_Command_Function *custom;
u64 custom_id;
@ -25,12 +25,95 @@ struct Command_Binding{
static Command_Binding null_command_binding = {0};
struct Command_Map{
Command_Map *parent;
i32 parent;
Command_Binding vanilla_keyboard_default[8];
Command_Binding *commands;
u32 count, max;
};
struct Mapping{
Command_Map map_top;
Command_Map map_file;
Command_Map map_ui;
i32 *map_id_table;
Command_Map *user_maps;
i32 user_map_count;
};
internal i32
get_or_add_map_index(Mapping *mapping, i32 mapid){
i32 result = 0;
i32 user_map_count = mapping->user_map_count;
i32 *map_id_table = mapping->map_id_table;
for (result = 0; result < user_map_count; ++result){
if (map_id_table[result] == mapid){
break;
}
if (map_id_table[result] == -1){
map_id_table[result] = mapid;
break;
}
}
return(result);
}
internal i32
get_map_index(Mapping *mapping, i32 mapid){
i32 result = 0;
i32 user_map_count = mapping->user_map_count;
i32 *map_id_table = mapping->map_id_table;
for (result = 0; result < user_map_count; ++result){
if (map_id_table[result] == mapid){
break;
}
if (map_id_table[result] == 0){
result = user_map_count;
break;
}
}
return(result);
}
internal Command_Map*
get_map_base(Mapping *mapping, i32 mapid, b32 add){
Command_Map *map = 0;
if (mapid < mapid_global){
i32 map_index = 0;
if (add){
map_index = get_or_add_map_index(mapping, mapid);
}
else{
map_index = get_map_index(mapping, mapid);
}
if (map_index < mapping->user_map_count){
map = &mapping->user_maps[map_index];
}
}
else if (mapid == mapid_global){
map = &mapping->map_top;
}
else if (mapid == mapid_file){
map = &mapping->map_file;
}
else if (mapid == mapid_ui){
map = &mapping->map_ui;
}
return(map);
}
internal Command_Map*
get_or_add_map(Mapping *mapping, i32 mapid){
Command_Map *map = get_map_base(mapping, mapid, true);
return(map);
}
internal Command_Map*
get_map(Mapping *mapping, i32 mapid){
Command_Map *map = get_map_base(mapping, mapid, false);
return(map);
}
#define COMMAND_HASH_EMPTY 0
#define COMMAND_HASH_ERASED max_u64
@ -43,7 +126,7 @@ map_hash(Key_Code event_code, u8 modifiers){
}
internal b32
map_add(Command_Map *map, Key_Code event_code, u8 modifiers, Command_Function function, Custom_Command_Function *custom = 0, b32 override_original = true){
map_add(Command_Map *map, Key_Code event_code, u8 modifiers, Command_Function *function, Custom_Command_Function *custom = 0, b32 override_original = true){
b32 result = false;
Assert(map->count * 8 < map->max * 7);
u64 hash = map_hash(event_code, modifiers);
@ -73,7 +156,7 @@ map_add(Command_Map *map, Key_Code event_code, u8 modifiers, Command_Function fu
}
inline b32
map_add(Command_Map *map, Key_Code event_code, u8 modifiers, Command_Function function, u64 custom_id, b32 override_original = true){
map_add(Command_Map *map, Key_Code event_code, u8 modifiers, Command_Function *function, u64 custom_id, b32 override_original = true){
return (map_add(map, event_code, modifiers, function, (Custom_Command_Function*)custom_id, override_original));
}
@ -126,7 +209,7 @@ map_clear(Command_Map *commands){
}
internal b32
map_init(Command_Map *commands, Partition *part, u32 max, Command_Map *parent){
map_init(Command_Map *commands, Partition *part, u32 max, i32 parent){
b32 result = false;
if (commands->commands == 0){
max = clamp_bottom((u32)6, max);
@ -198,7 +281,12 @@ map_extract(Command_Map *map, Key_Event_Data key){
}
internal Command_Binding
map_extract_recursive(Command_Map *map, Key_Event_Data key){
map_extract_recursive(Mapping *mapping, i32 map_id, Key_Event_Data key){
Command_Map *map = get_map(mapping, map_id);
if (map == 0){
map = &mapping->map_top;
}
Command_Binding cmd_bind = {0};
Command_Map *visited_maps[16] = {0};
i32 visited_top = 0;
@ -208,7 +296,7 @@ map_extract_recursive(Command_Map *map, Key_Event_Data key){
if (cmd_bind.function == 0){
if (visited_top < ArrayCount(visited_maps)){
visited_maps[visited_top++] = map;
map = map->parent;
map = get_map(mapping, map->parent);
for (i32 i = 0; i < visited_top; ++i){
if (map == visited_maps[i]){
map = 0;

View File

@ -9,78 +9,9 @@
// TOP
internal i32
get_or_add_map_index(Models *models, i32 mapid){
i32 result = 0;
i32 user_map_count = models->user_map_count;
i32 *map_id_table = models->map_id_table;
for (result = 0; result < user_map_count; ++result){
if (map_id_table[result] == mapid){
break;
}
if (map_id_table[result] == -1){
map_id_table[result] = mapid;
break;
}
}
return(result);
}
internal i32
get_map_index(Models *models, i32 mapid){
i32 result = 0;
i32 user_map_count = models->user_map_count;
i32 *map_id_table = models->map_id_table;
for (result = 0; result < user_map_count; ++result){
if (map_id_table[result] == mapid){
break;
}
if (map_id_table[result] == 0){
result = user_map_count;
break;
}
}
return(result);
}
internal Command_Map*
get_map_base(Models *models, i32 mapid, b32 add){
Command_Map *map = 0;
if (mapid < mapid_global){
if (add){
mapid = get_or_add_map_index(models, mapid);
}
else{
mapid = get_map_index(models, mapid);
}
if (mapid < models->user_map_count){
map = models->user_maps + mapid;
}
}
else if (mapid == mapid_global){
map = &models->map_top;
}
else if (mapid == mapid_file){
map = &models->map_file;
}
return(map);
}
internal Command_Map*
get_or_add_map(Models *models, i32 mapid){
Command_Map *map = get_map_base(models, mapid, 1);
return(map);
}
internal Command_Map*
get_map(Models *models, i32 mapid){
Command_Map *map = get_map_base(models, mapid, 0);
return(map);
}
internal void
map_set_count(Models *models, i32 mapid, u32 count){
Command_Map *map = get_or_add_map(models, mapid);
map_set_count(Mapping *mapping, i32 mapid, u32 count){
Command_Map *map = get_or_add_map(mapping, mapid);
Assert(map->commands == 0);
map->count = count;
if (map->max < count){
@ -89,20 +20,22 @@ map_set_count(Models *models, i32 mapid, u32 count){
}
internal u32
map_get_count(Models *models, i32 mapid){
Command_Map *map = get_or_add_map(models, mapid);
map_get_count(Mapping *mapping, i32 mapid){
Command_Map *map = get_or_add_map(mapping, mapid);
u32 count = map->count;
Assert(map->commands == 0);
return(count);
}
internal u32
map_get_max_count(Models *models, i32 mapid){
Command_Map *map = get_or_add_map(models, mapid);
map_get_max_count(Mapping *mapping, i32 mapid){
Command_Map *map = get_or_add_map(mapping, mapid);
u32 count = map->max;
return(count);
}
/////////////////
inline void*
get_view_body(View *view){
char *result = (char*)view;
@ -2788,14 +2721,17 @@ view_cursor_move(System_Functions *system, View *view, i32 line, i32 character){
view_cursor_move(view, cursor);
}
// TODO(allen): Eliminate models.
inline void
view_show_file(View *view, Models *models){
Editing_File *file = view->file_data.file;
if (file){
view->map = get_map(models, file->settings.base_map_id);
if (file != 0){
//view->map = get_map(&models->mapping, file->settings.base_map_id);
view->map = file->settings.base_map_id;
}
else{
view->map = get_map(models, mapid_global);
//view->map = get_map(&models->mapping, mapid_global);
view->map = mapid_global;
}
if (view->showing_ui != VUI_None){
@ -3659,7 +3595,7 @@ global_set_font(System_Functions *system, Models *models, Font_ID font_id){
inline void
view_show_GUI(View *view, Models *models, View_UI ui){
view->map = &models->map_ui;
view->map = mapid_ui;
view->showing_ui = ui;
view->changed_context_in_step = true;
}
@ -3672,7 +3608,7 @@ view_show_interactive(System_Functions *system, View *view, Models *models, Inte
view->dest = make_fixed_width_string(view->dest_);
view->list_i = 0;
view->map = &models->map_ui;
view->map = mapid_ui;
hot_directory_clean_end(&models->hot_directory);
hot_directory_reload(system, &models->hot_directory);
@ -3681,7 +3617,7 @@ view_show_interactive(System_Functions *system, View *view, Models *models, Inte
inline void
view_show_theme(View *view, Models *models){
view->map = &models->map_ui;
view->map = mapid_ui;
view->showing_ui = VUI_Theme;
view->color_mode = CV_Mode_Library;
view->color = super_color_create(0xFF000000);
@ -5333,25 +5269,23 @@ step_file_view(System_Functions *system, View *view, Models *models, View *activ
SHOW_GUI_BLANK(0);
{
Command_Map *map = view_ptr->map;
i32 map = view_ptr->map;
#define MAP_LABEL "command map"
if (map == &models->map_top){
if (map == mapid_global){
SHOW_GUI_STRING(1, h_align, MAP_LABEL, "global");
}
else if (map == &models->map_file){
else if (map == mapid_file){
SHOW_GUI_STRING(1, h_align, MAP_LABEL, "file");
}
else if (map == &models->map_ui){
else if (map == mapid_ui){
SHOW_GUI_STRING(1, h_align, MAP_LABEL, "gui");
}
else if (map == 0){
else if (map == mapid_nomap){
SHOW_GUI_STRING(1, h_align, MAP_LABEL, "nomap");
}
else if (map >= models->user_maps){
i32 map_index = (i32)(view_ptr->map - models->user_maps);
i32 map_id = models->map_id_table[map_index];
else{
SHOW_GUI_STRING(1, h_align, MAP_LABEL, "user");
SHOW_GUI_INT(2, h_align, "custom map id", map_id);
SHOW_GUI_INT(2, h_align, "custom map id", map);
}
}

View File

@ -98,7 +98,8 @@ struct View{
View *next, *prev;
Panel *panel;
b32 in_use;
Command_Map *map;
i32 map;
//Command_Map *map;
File_Viewing_Data file_data;

View File

@ -80,7 +80,6 @@ PLAT_THREAD_SIG(coroutine_main){
Assert(me->yield_ctx != 0);
Assert(me->function != 0);
DBG_POINT();
me->function(&me->head);
// NOTE(allen): Wake up the caller and set this coroutine back to being dead.

View File

@ -24,23 +24,18 @@ system_get_binary_path_string(String *out){
internal void
init_shared_vars(){
DBG_POINT();
umem scratch_size = KB(128);
void *scratch_memory = system_memory_allocate(scratch_size);
shared_vars.scratch = make_part(scratch_memory, (i32)scratch_size);
DBG_POINT();
shared_vars.track_table_size = KB(16);
shared_vars.track_table = system_memory_allocate(shared_vars.track_table_size);
DBG_POINT();
shared_vars.track_node_size = KB(16);
void *track_nodes = system_memory_allocate(shared_vars.track_node_size);
DBG_POINT();
i32 track_result = init_track_system(&shared_vars.track, &shared_vars.scratch, shared_vars.track_table, shared_vars.track_table_size, track_nodes, shared_vars.track_node_size);
DBG_POINT();
if (track_result != FileTrack_Good){
exit(1);
}
@ -563,21 +558,17 @@ launch_rendering(System_Functions *system, Render_Target *t){
internal void
font_load_page_inner(Partition *part, Render_Font *font, FT_Library ft, FT_Face face, b32 use_hinting, Glyph_Page *page, u32 page_number, i32 tab_width){
DBG_POINT();
Temp_Memory temp = begin_temp_memory(part);
Assert(page != 0);
page->page_number = page_number;
DBG_POINT();
// prepare to read glyphs into a temporary texture buffer
i32 max_glyph_w = face->size->metrics.x_ppem;
DBG_POINT();
i32 max_glyph_h = font_get_height(font);
i32 tex_width = 64;
i32 tex_height = 0;
DBG_POINT();
do {
tex_width *= 2;
float glyphs_per_row = ceilf(tex_width / (float) max_glyph_w);
@ -585,13 +576,11 @@ font_load_page_inner(Partition *part, Render_Font *font, FT_Library ft, FT_Face
tex_height = ceil32(rows * (max_glyph_h + 2));
} while(tex_height > tex_width);
DBG_POINT();
tex_height = round_up_pot_u32(tex_height);
i32 pen_x = 0;
i32 pen_y = 0;
DBG_POINT();
u32* pixels = push_array(part, u32, tex_width * tex_height);
memset(pixels, 0, tex_width * tex_height * sizeof(u32));
@ -662,22 +651,15 @@ font_load_page_inner(Partition *part, Render_Font *font, FT_Library ft, FT_Face
page->tex_width = tex_width;
page->tex_height = tex_height;
DBG_POINT();
glGenTextures(1, &page->tex);
DBG_POINT();
glBindTexture(GL_TEXTURE_2D, page->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_INT, pixels);
glBindTexture(GL_TEXTURE_2D, 0);
end_temp_memory(temp);
// whitespace spacing stuff

View File

@ -370,29 +370,23 @@ INTERNAL_Sys_Get_Thread_States_Sig(system_internal_get_thread_states){
internal void
work_system_init(){
DBG_POINT();
AssertThreadSizes();
DBG_POINT();
u32 core_count = CORE_COUNT;
i32 thread_system_memory_size = core_count*(sizeof(Thread_Context) + sizeof(Thread_Memory));
void *thread_system_memory = system_memory_allocate(thread_system_memory_size);
Partition thread_part = make_part(thread_system_memory, thread_system_memory_size);
DBG_POINT();
for (i32 i = 0; i < LOCK_COUNT; ++i){
system_init_lock(&threadvars.locks[i]);
}
DBG_POINT();
for (i32 i = 0; i < CV_COUNT; ++i){
system_init_cv(&threadvars.conds[i]);
}
DBG_POINT();
threadvars.thread_memory = push_array(&thread_part, Thread_Memory, core_count);
DBG_POINT();
for (u32 group_i = 0; group_i < THREAD_GROUP_COUNT; ++group_i){
Thread_Context *threads = push_array(&thread_part, Thread_Context, core_count);
threadvars.groups[group_i].threads = threads;
@ -400,10 +394,8 @@ work_system_init(){
threadvars.groups[group_i].cancel_lock0 = CANCEL_LOCK0;
threadvars.groups[group_i].cancel_cv0 = CANCEL_CV0;
DBG_POINT();
system_init_semaphore(&threadvars.queues[group_i].semaphore, core_count);
DBG_POINT();
for (u32 i = 0; i < core_count; ++i){
Thread_Context *thread = threads + i;
thread->id = i + 1;
@ -417,7 +409,6 @@ work_system_init(){
system_init_and_launch_thread(&thread->thread, job_thread_proc, thread);
}
DBG_POINT();
initialize_unbounded_queue(&threadvars.groups[group_i].queue);
}
}

View File

@ -1,3 +1,12 @@
// Command Mapping
// "" - Leave the bindings unaltered from their startup value.
// "choose" - Ask 4coder to choose based on platform.
// "default" - Use the default keybindings 4coder has always had.
// "mac-4coder-like" - Use keybindings for Mac similar to 4coder's bindings on other platforms.
// "mac-default" - Use keybindings similar to those found in other Mac applications.
// <my-own-string> - If you use the custom layer to make a named mapping you can use that here too.
mapping = "";
// Code Wrapping
enable_code_wrapping = true;
automatically_adjust_wrapping = true;

View File

@ -72,8 +72,8 @@ Long name commands that can be typed in after \STYLE{code} <alt x> \END for infr
\ITEM \STYLE{code} "load project" \END Load a project.4coder file, ditching any previously loaded project
\ITEM \STYLE{code} "open all code" \END Open all code files in the current directory, extensions set in config.4coder, default to C/C++ extensions
\ITEM \STYLE{code} "open all code recursive" \END Like \STYLE{code} "open all code" \END but recurses through folders
\ITEM \STYLE{code} "dos lines" \END Switch the bufer to 'dos' line ending mode CRLF
\ITEM \STYLE{code} "nix lines" \END Switch the bufer to 'nix' line ending mode LF
\ITEM \STYLE{code} "dos lines" \END Switch the buffer to 'dos' line ending mode CRLF
\ITEM \STYLE{code} "nix lines" \END Switch the buffer to 'nix' line ending mode LF
\END
\END