From 6be352e775fc3791426bac7b9b2581633bd34b6b Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Wed, 11 May 2016 22:15:54 -0400 Subject: [PATCH] fixed extra scrolling when switching files --- 4coder_custom.h | 1 - 4coder_default_bindings.cpp | 203 ++++++++++++++++++----------------- 4coder_default_include.cpp | 4 +- 4coder_helper.h | 29 +++++ 4coder_string.h | 8 ++ 4ed.cpp | 25 ++--- 4ed_file_view.cpp | 49 +++++++-- build_all.bat | 3 +- power/4coder_experiments.cpp | 155 +++++++++++++++++++------- 9 files changed, 309 insertions(+), 168 deletions(-) diff --git a/4coder_custom.h b/4coder_custom.h index 9e617eb6..188b7fe3 100644 --- a/4coder_custom.h +++ b/4coder_custom.h @@ -177,7 +177,6 @@ enum Command_ID{ cmdid_paste, cmdid_paste_next, cmdid_delete_range, - cmdid_timeline_scrub, cmdid_undo, cmdid_redo, cmdid_history_backward, diff --git a/4coder_default_bindings.cpp b/4coder_default_bindings.cpp index 3fbdcfc1..31b08e56 100644 --- a/4coder_default_bindings.cpp +++ b/4coder_default_bindings.cpp @@ -15,66 +15,6 @@ enum My_Maps{ my_maps_count }; -HOOK_SIG(my_start){ - exec_command(app, cmdid_open_panel_vsplit); - exec_command(app, cmdid_change_active_panel); - - app->change_theme(app, literal("4coder")); - app->change_font(app, literal("liberation sans")); - - // Theme options: - // "4coder" - // "Handmade Hero" - // "Twilight" - // "Woverine" - // "stb" - - // Font options: - // "liberation sans" - // "liberation mono" - // "hack" - // "cutive mono" - // "inconsolata" - - // no meaning for return - return(0); -} - -HOOK_SIG(my_file_settings){ - // NOTE(allen|a4): In hooks that want parameters, such as this file - // opened hook. The file created hook is guaranteed to have only - // and exactly one buffer parameter. In normal command callbacks - // there are no parameter buffers. - Buffer_Summary buffer = app->get_parameter_buffer(app, 0); - assert(buffer.exists); - - int treat_as_code = 0; - int wrap_lines = 1; - - if (buffer.file_name && buffer.size < (16 << 20)){ - String ext = file_extension(make_string(buffer.file_name, buffer.file_name_len)); - if (match(ext, make_lit_string("cpp"))) treat_as_code = 1; - else if (match(ext, make_lit_string("h"))) treat_as_code = 1; - else if (match(ext, make_lit_string("c"))) treat_as_code = 1; - else if (match(ext, make_lit_string("hpp"))) treat_as_code = 1; - } - - if (treat_as_code){ - wrap_lines = 0; - } - if (buffer.file_name[0] == '*'){ - wrap_lines = 0; - } - - push_parameter(app, par_lex_as_cpp_file, treat_as_code); - push_parameter(app, par_wrap_lines, wrap_lines); - push_parameter(app, par_key_mapid, (treat_as_code)?((int)my_code_map):((int)mapid_file)); - exec_command(app, cmdid_set_settings); - - // no meaning for return - return(0); -} - CUSTOM_COMMAND_SIG(write_allen_todo){ write_string(app, make_lit_string("// TODO(allen): ")); } @@ -265,17 +205,70 @@ CUSTOM_COMMAND_SIG(ruin_theme){ } #endif -int get_bindings(void *data, int size){ - Bind_Helper context_ = begin_bind_helper(data, size); - Bind_Helper *context = &context_; +HOOK_SIG(my_start){ + exec_command(app, cmdid_open_panel_vsplit); + exec_command(app, cmdid_change_active_panel); - // NOTE(allen|a3.1): Hooks have no loyalties to maps. All hooks are global - // and once set they always apply, regardless of what map is active. - set_hook(context, hook_start, my_start); - set_hook(context, hook_open_file, my_file_settings); + app->change_theme(app, literal("4coder")); + app->change_font(app, literal("liberation sans")); + + // Theme options: + // "4coder" + // "Handmade Hero" + // "Twilight" + // "Woverine" + // "stb" - set_scroll_rule(context, smooth_scroll_rule); + // Font options: + // "liberation sans" + // "liberation mono" + // "hack" + // "cutive mono" + // "inconsolata" + // no meaning for return + return(0); +} + +HOOK_SIG(my_file_settings){ + // NOTE(allen|a4): In hooks that want parameters, such as this file + // opened hook. The file created hook is guaranteed to have only + // and exactly one buffer parameter. In normal command callbacks + // there are no parameter buffers. + Buffer_Summary buffer = app->get_parameter_buffer(app, 0); + assert(buffer.exists); + + int treat_as_code = 0; + int wrap_lines = 1; + + if (buffer.file_name && buffer.size < (16 << 20)){ + String ext = file_extension(make_string(buffer.file_name, buffer.file_name_len)); + if (match(ext, make_lit_string("cpp"))) treat_as_code = 1; + else if (match(ext, make_lit_string("h"))) treat_as_code = 1; + else if (match(ext, make_lit_string("c"))) treat_as_code = 1; + else if (match(ext, make_lit_string("hpp"))) treat_as_code = 1; + } + + if (treat_as_code){ + wrap_lines = 0; + } + if (buffer.file_name[0] == '*'){ + wrap_lines = 0; + } + + push_parameter(app, par_lex_as_cpp_file, treat_as_code); + push_parameter(app, par_wrap_lines, wrap_lines); + push_parameter(app, par_key_mapid, (treat_as_code)?((int)my_code_map):((int)mapid_file)); + exec_command(app, cmdid_set_settings); + + // no meaning for return + return(0); +} + +typedef void (Extension_Bindings)(Bind_Helper *context); + +void +default_keys(Bind_Helper *context, Extension_Bindings *extension = 0){ begin_map(context, mapid_global); bind(context, 'p', MDFR_CTRL, cmdid_open_panel_vsplit); @@ -389,49 +382,65 @@ int get_bindings(void *data, int size){ bind(context, key_back, MDFR_ALT, snipe_token_or_word); bind(context, ' ', MDFR_CTRL, cmdid_set_mark); - bind(context, 'm', MDFR_CTRL, cmdid_cursor_mark_swap); + bind(context, 'a', MDFR_CTRL, replace_in_range); bind(context, 'c', MDFR_CTRL, cmdid_copy); - bind(context, 'x', MDFR_CTRL, cmdid_cut); - bind(context, 'v', MDFR_CTRL, cmdid_paste); - bind(context, 'V', MDFR_CTRL, cmdid_paste_next); - bind(context, 'Z', MDFR_CTRL, cmdid_timeline_scrub); - bind(context, 'z', MDFR_CTRL, cmdid_undo); - bind(context, 'y', MDFR_CTRL, cmdid_redo); + bind(context, 'd', MDFR_CTRL, cmdid_delete_range); + bind(context, 'e', MDFR_CTRL, cmdid_center_view); + bind(context, 'f', MDFR_CTRL, search); + bind(context, 'g', MDFR_CTRL, goto_line); bind(context, 'h', MDFR_CTRL, cmdid_history_backward); bind(context, 'H', MDFR_CTRL, cmdid_history_forward); - bind(context, 'd', MDFR_CTRL, cmdid_delete_range); bind(context, 'l', MDFR_CTRL, cmdid_toggle_line_wrap); - bind(context, 'L', MDFR_CTRL, cmdid_toggle_endline_mode); - bind(context, 'u', MDFR_CTRL, cmdid_to_uppercase); bind(context, 'j', MDFR_CTRL, cmdid_to_lowercase); - bind(context, '?', MDFR_CTRL, cmdid_toggle_show_whitespace); - - bind(context, '~', MDFR_CTRL, cmdid_clean_all_lines); - bind(context, '1', MDFR_CTRL, cmdid_eol_dosify); - bind(context, '!', MDFR_CTRL, cmdid_eol_nixify); - - bind(context, 'f', MDFR_CTRL, search); - bind(context, 'r', MDFR_CTRL, reverse_search); - bind(context, 'g', MDFR_CTRL, goto_line); - bind(context, 'q', MDFR_CTRL, query_replace); - bind(context, 'a', MDFR_CTRL, replace_in_range); - bind(context, 's', MDFR_ALT, rewrite_as_single_caps); - bind(context, 'K', MDFR_CTRL, cmdid_kill_buffer); + bind(context, 'L', MDFR_CTRL, cmdid_toggle_endline_mode); + bind(context, 'm', MDFR_CTRL, cmdid_cursor_mark_swap); bind(context, 'O', MDFR_CTRL, cmdid_reopen); + bind(context, 'q', MDFR_CTRL, query_replace); + bind(context, 'r', MDFR_CTRL, reverse_search); + bind(context, 's', MDFR_ALT, rewrite_as_single_caps); bind(context, 's', MDFR_CTRL, cmdid_save); - + bind(context, 'u', MDFR_CTRL, cmdid_to_uppercase); + bind(context, 'v', MDFR_CTRL, cmdid_paste); + bind(context, 'V', MDFR_CTRL, cmdid_paste_next); + bind(context, 'x', MDFR_CTRL, cmdid_cut); + bind(context, 'y', MDFR_CTRL, cmdid_redo); + bind(context, 'z', MDFR_CTRL, cmdid_undo); + + bind(context, '1', MDFR_CTRL, cmdid_eol_dosify); + + bind(context, '?', MDFR_CTRL, cmdid_toggle_show_whitespace); + bind(context, '~', MDFR_CTRL, cmdid_clean_all_lines); + bind(context, '!', MDFR_CTRL, cmdid_eol_nixify); bind(context, '\n', MDFR_SHIFT, write_and_auto_tab); bind(context, ' ', MDFR_SHIFT, cmdid_write_character); - - bind(context, 'e', MDFR_CTRL, cmdid_center_view); - - bind(context, 'T', MDFR_CTRL | MDFR_ALT, begin_html_mode); - + + if (extension != 0){ + extension(context); + } + end_map(context); +} + +#ifndef NO_BINDING + +int get_bindings(void *data, int size){ + Bind_Helper context_ = begin_bind_helper(data, size); + Bind_Helper *context = &context_; + + // NOTE(allen|a3.1): Hooks have no loyalties to maps. All hooks are global + // and once set they always apply, regardless of what map is active. + set_hook(context, hook_start, my_start); + set_hook(context, hook_open_file, my_file_settings); + + set_scroll_rule(context, smooth_scroll_rule); + + default_keys(context); int result = end_bind_helper(context); return(result); } +#endif + // BOTTOM diff --git a/4coder_default_include.cpp b/4coder_default_include.cpp index fe57dcf0..c39c9a5d 100644 --- a/4coder_default_include.cpp +++ b/4coder_default_include.cpp @@ -334,7 +334,9 @@ isearch(Application_Links *app, int start_reversed){ } } else{ - match.end = match.start + bar.string.size; + if (match.end > match.start + bar.string.size){ + match.end = match.start + bar.string.size; + } } app->view_set_highlight(app, &view, match.start, match.end, 1); diff --git a/4coder_helper.h b/4coder_helper.h index 04ccc437..e3269e83 100644 --- a/4coder_helper.h +++ b/4coder_helper.h @@ -224,6 +224,35 @@ get_range(View_Summary *view){ return(range); } +struct Buffer_Rect{ + int char0,line0; + int char1,line1; +}; + +#ifndef Swap +#define Swap(a,b) do{ auto t = a; a = b; b = t; } while(0) +#endif + +inline Buffer_Rect +get_rect(View_Summary *view){ + Buffer_Rect rect; + + rect.char0 = view->mark.character; + rect.line0 = view->mark.line; + + rect.char1 = view->cursor.character; + rect.line1 = view->cursor.line; + + if (rect.line0 > rect.line1){ + Swap(rect.line0, rect.line1); + } + if (rect.char0 > rect.char1){ + Swap(rect.char0, rect.char1); + } + + return(rect); +} + inline void exec_command(Application_Links *app, Command_ID id){ app->exec_command_keep_stack(app, id); diff --git a/4coder_string.h b/4coder_string.h index cf23dc68..dae901a6 100644 --- a/4coder_string.h +++ b/4coder_string.h @@ -192,6 +192,7 @@ FCPP_LINK String file_extension_slowly(char *str); FCPP_LINK char * file_extension_c(String str); FCPP_LINK bool remove_last_folder(String *str); FCPP_LINK void replace_char(String str, char replace, char with); +FCPP_LINK void replace_char(char *str, char replace, char with); inline String make_string(void *str, int size, int mem_size){ String result; @@ -1131,6 +1132,13 @@ replace_char(String str, char replace, char with){ } } +FCPP_LINK void +replace_char(char *str, char replace, char with){ + for (; *str; ++str){ + if (*str == replace) *str = with; + } +} + // NOTE(allen): experimental section, things below here are // not promoted to public API level yet. diff --git a/4ed.cpp b/4ed.cpp index d44638a9..4b965134 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -754,15 +754,6 @@ COMMAND_DECL(delete_range){ } } -COMMAND_DECL(timeline_scrub){ - REQ_OPEN_VIEW(view); - REQ_FILE_HISTORY(file, view); - - view_set_widget(view, FWIDG_TIMELINES); - view->widget.timeline.undo_line = 1; - view->widget.timeline.history_line = 1; -} - COMMAND_DECL(undo){ USE_MODELS(models); REQ_OPEN_VIEW(view); @@ -772,7 +763,6 @@ COMMAND_DECL(undo){ } COMMAND_DECL(redo){ - USE_MODELS(models); REQ_OPEN_VIEW(view); REQ_FILE_HISTORY(file, view); @@ -781,7 +771,6 @@ COMMAND_DECL(redo){ } COMMAND_DECL(history_backward){ - USE_MODELS(models); REQ_OPEN_VIEW(view); REQ_FILE_HISTORY(file, view); @@ -790,7 +779,6 @@ COMMAND_DECL(history_backward){ } COMMAND_DECL(history_forward){ - USE_MODELS(models); REQ_OPEN_VIEW(view); REQ_FILE_HISTORY(file, view); @@ -799,7 +787,6 @@ COMMAND_DECL(history_forward){ } COMMAND_DECL(interactive_new){ - USE_MODELS(models); USE_VIEW(view); @@ -890,8 +877,9 @@ view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){ temp = begin_temp_memory(part); cmd->part = partition_sub_part(part, Kbytes(16)); - view_set_file(panel->view, file, models, system, - models->hooks[hook_open_file], &app_links); + View *view = panel->view; + view_set_file(view, file, models, system, models->hooks[hook_open_file], &app_links); + view_show_file(view, 0); cmd->part = old_part; end_temp_memory(temp); @@ -923,6 +911,7 @@ COMMAND_DECL(reopen){ view_set_file(view, file, models, system, models->hooks[hook_open_file], &app_links); + view_show_file(view, 0); } else{ do_feedback_message(system, models, make_lit_string("ERROR: no file load slot available\n")); @@ -2419,6 +2408,7 @@ extern "C"{ if (file != vptr->file_data.file){ view_set_file(vptr, file, models, cmd->system, models->hooks[hook_open_file], &app_links); + view_show_file(vptr, 0); } } @@ -2649,7 +2639,6 @@ setup_command_table(){ SET(paste); SET(paste_next); SET(delete_range); - SET(timeline_scrub); SET(undo); SET(redo); SET(history_backward); @@ -4030,7 +4019,7 @@ App_Step_Sig(app_step){ "Newest features:\n" "Scroll bar on files and file lists\n" "Arrow navigation in lists\n" - "A new minimal theme\n" + "A new minimal theme editor\n" "\n" "New in alpha 4.0.2:\n" "-The file count limit is over 8 million now\n" @@ -4375,6 +4364,7 @@ App_Step_Sig(app_step){ View *view = panel->view; view_set_file(view, file, models, system, models->hooks[hook_open_file], &app_links); + view_show_file(view, 0); view->map = app_get_map(models, file->settings.base_map_id); Hook_Function *new_file_fnc = models->hooks[hook_new_file]; @@ -4405,6 +4395,7 @@ App_Step_Sig(app_step){ view_set_file(view, file, models, system, models->hooks[hook_open_file], &app_links); + view_show_file(view, 0); view->map = app_get_map(models, file->settings.base_map_id); } }break; diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index e4463e30..04695dd6 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -1295,11 +1295,13 @@ view_set_file( } } +#if 0 if (set_vui){ // TODO(allen): Fix this! There should be a way to easily separate setting a file, // and switching to file mode, so that they don't cross over eachother like this. view->showing_ui = VUI_None; } +#endif } struct Relative_Scrolling{ @@ -2516,6 +2518,7 @@ view_show_menu(View *view, Command_Map *gui_map){ view->map_for_file = view->map; view->map = gui_map; view->showing_ui = VUI_Menu; + view->current_scroll = &view->gui_scroll; } inline void @@ -2523,6 +2526,7 @@ view_show_config(View *view, Command_Map *gui_map){ view->map_for_file = view->map; view->map = gui_map; view->showing_ui = VUI_Config; + view->current_scroll = &view->gui_scroll; } inline void @@ -2537,6 +2541,7 @@ view_show_interactive(System_Functions *system, View *view, view->interaction = interaction; view->dest = make_fixed_width_string(view->dest_); view->list_i = 0; + view->current_scroll = &view->gui_scroll; view->map_for_file = view->map; view->map = gui_map; @@ -2553,6 +2558,7 @@ view_show_theme(View *view, Command_Map *gui_map){ view->color_mode = CV_Mode_Library; view->color = super_color_create(0xFF000000); view->current_color_editing = 0; + view->current_scroll = &view->gui_scroll; } @@ -2565,6 +2571,7 @@ view_show_file(View *view, Command_Map *file_map){ view->map = view->map_for_file; } view->showing_ui = VUI_None; + view->current_scroll = &view->file_scroll; } inline void @@ -2747,7 +2754,6 @@ intbar_draw_string(Render_Target *target, File_Bar *bar, String str, u32 char_co bar->pos_x += font_string_width(target, font_id, str); } -// TODO(allen): wtf is this? internal void view_reinit_scrolling(View *view){ Editing_File *file = view->file_data.file; @@ -2780,10 +2786,14 @@ view_reinit_scrolling(View *view){ view->file_scroll.target_y = target_y; view->file_scroll.scroll_y = target_y; view->file_scroll.prev_target_y = -1000.f; + view->file_scroll.min_y = view->gui_target.scroll_updated.min_y; + view->file_scroll.max_y = view->gui_target.scroll_updated.max_y; view->file_scroll.target_x = target_x; view->file_scroll.scroll_x = target_x; view->file_scroll.prev_target_x = -1000.f; + + gui_post_scroll_vars(&view->gui_target, &view->file_scroll); } #define CursorMaxY_(m,h) ((m) - (h)*3) @@ -2797,18 +2807,17 @@ file_step(View *view, i32_Rect region, Input_Summary *user_input, b32 is_active) i32 is_animating = 0; Editing_File *file = view->file_data.file; if (file && !file->state.is_loading){ - // TODO(allen): rewrite with real scrolling system now. f32 line_height = (f32)view->font_height; f32 delta_y = 3.f*line_height; - f32 cursor_y = view_get_cursor_y(view); - f32 max_visible_y = view_file_height(view); f32 max_x = view_file_width(view); + + f32 cursor_y = view_get_cursor_y(view); f32 cursor_x = view_get_cursor_x(view); - GUI_Scroll_Vars scroll_vars = view->gui_target.scroll_original; + GUI_Scroll_Vars scroll_vars = view->gui_target.scroll_updated; f32 target_y = scroll_vars.target_y; f32 target_x = scroll_vars.target_x; @@ -3434,6 +3443,13 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su switch (view->interaction){ case IInt_Sys_File_List: { + b32 use_item_in_list = 1; + b32 activate_directly = 0; + + if (view->action == IAct_Save_As || view->action == IAct_New){ + use_item_in_list = 0; + } + String message = {0}; switch (view->action){ case IAct_Open: message = make_lit_string("Open: "); break; @@ -3453,16 +3469,19 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su Single_Line_Input_Step step = {0}; Key_Event_Data key = {0}; i32 i; - + for (i = 0; i < keys.count; ++i){ key = get_single_key(&keys, i); step = app_single_file_input_step(system, &models->working_set, key, &hdir->string, hdir, 1, 1, 0); if (step.made_a_change){ view->list_i = 0; } + if (!use_item_in_list && (key.keycode == '\n' || key.keycode == '\t')){ + activate_directly = 1; + } } } - + gui_do_text_field(target, message, hdir->string); view->current_scroll = &view->gui_scroll; @@ -3470,6 +3489,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su gui_begin_scrollable(target, view->showing_ui, view->gui_scroll, 9.f * view->font_height); id.id[0] = (u64)(hdir) + 1; + if (gui_begin_list(target, id, view->list_i, 0, &update)){ gui_standard_list(target, id, &keys, &view->list_i, &update); } @@ -3478,7 +3498,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su begin_exhaustive_loop(&loop, hdir); for (i = 0; i < loop.count; ++i){ file_info = get_exhaustive_info(system, &models->working_set, &loop, i); - + if (file_info.name_match){ id.id[0] = (u64)(file_info.info); if (gui_do_file_option(target, id, file_info.info->filename, file_info.is_folder, file_info.message)){ @@ -3486,16 +3506,20 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su set_last_folder(&hdir->string, file_info.info->filename, '/'); do_new_directory = 1; } - else{ + else if (use_item_in_list){ interactive_view_complete(view, loop.full_path, 0); } } } } } - + gui_end_list(target); - + + if (activate_directly){ + interactive_view_complete(view, hdir->string, 0); + } + if (do_new_directory){ hot_directory_reload(system, hdir, &models->working_set); } @@ -3752,6 +3776,7 @@ do_input_file_view(System_Functions *system, Exchange *exchange, if (view->reinit_scrolling){ view_reinit_scrolling(view); + is_animating = 1; } if (file_step(view, gui_session.rect, user_input, is_active)){ is_animating = 1; @@ -4202,6 +4227,8 @@ draw_file_bar(Render_Target *target, View *view, Editing_File *file, i32_Rect re String line_number = make_fixed_width_string(line_number_space); append(&line_number, " L#"); append_int_to_str(view->file_data.cursor.line, &line_number); + append(&line_number, " C#"); + append_int_to_str(view->file_data.cursor.character, &line_number); intbar_draw_string(target, &bar, line_number, base_color); diff --git a/build_all.bat b/build_all.bat index 85a0b403..7305ade0 100644 --- a/build_all.bat +++ b/build_all.bat @@ -15,7 +15,8 @@ pushd ..\code popd pushd ..\build -call "..\code\buildsuper.bat" ..\code\4coder_default_bindings.cpp +REM call "..\code\buildsuper.bat" ..\code\4coder_default_bindings.cpp +call "..\code\buildsuper.bat" ..\code\power\4coder_experiments.cpp set EXPORTS=/EXPORT:app_get_functions cl %OPTS% %INCLUDES% %DEFINES% ..\code\4ed_app_target.cpp %* /Fe4ed_app /LD /link /INCREMENTAL:NO /OPT:REF %EXPORTS% diff --git a/power/4coder_experiments.cpp b/power/4coder_experiments.cpp index b9c0900d..23205901 100644 --- a/power/4coder_experiments.cpp +++ b/power/4coder_experiments.cpp @@ -1,54 +1,129 @@ -#include "4coder_default_bindings.cpp" +// TOP -enum Experiment_Maps{ - my_experiment_map = my_maps_count -}; +#define NO_BINDING +#include "../4coder_default_bindings.cpp" -HOOK_SIG(my_file_settings){ - Buffer_Summary buffer = app->get_parameter_buffer(app, 0); - assert(buffer.exists); - - int treat_as_code = 0; - int wrap_lines = 1; - - if (buffer.file_name && buffer.size < (16 << 20)){ - String ext = file_extension(make_string(buffer.file_name, buffer.file_name_len)); - if (match(ext, make_lit_string("cpp"))) treat_as_code = 1; - else if (match(ext, make_lit_string("h"))) treat_as_code = 1; - else if (match(ext, make_lit_string("c"))) treat_as_code = 1; - else if (match(ext, make_lit_string("hpp"))) treat_as_code = 1; +CUSTOM_COMMAND_SIG(kill_rect){ + View_Summary view = app->get_active_view(app); + Buffer_Summary buffer = app->get_buffer(app, view.buffer_id); + + Buffer_Rect rect = get_rect(&view); + + for (int line = rect.line1; line >= rect.line0; --line){ + int start = 0; + int end = 0; + + app->view_set_cursor(app, &view, seek_line_char(line, rect.char0), 0); + app->refresh_view(app, &view); + start = view.cursor.pos; + + app->view_set_cursor(app, &view, seek_line_char(line, rect.char1), 0); + app->refresh_view(app, &view); + end = view.cursor.pos; + + app->buffer_replace_range(app, &buffer, start, end, 0, 0); } +} - if (treat_as_code){ - wrap_lines = 0; +CUSTOM_COMMAND_SIG(complete_word){ + app->print_message(app, literal("complete_word\n")); + + View_Summary view = app->get_active_view(app); + Buffer_Summary buffer = app->get_buffer(app, view.buffer_id); + + int start = 0; + int end = 0; + + end = view.cursor.pos; + + push_parameter(app, par_flags, BoundryAlphanumeric); + exec_command(app, cmdid_seek_left); + + app->refresh_view(app, &view); + start = view.cursor.pos; + + String complete_string; + int size = (start - end); + char complete_space[256]; + + if (size < sizeof(complete_space) - 1){ + complete_string = make_fixed_width_string(complete_space); + app->buffer_read_range(app, &buffer, start, end, complete_space); + complete_string.size = size; + complete_string.str[size] = 0; + + // TODO(allen): Complete this when the heavy duty coroutine stuff + // and the hash table are available + + app->print_message(app, complete_string.str, complete_string.size); } - if (buffer.file_name[0] == '*'){ - wrap_lines = 0; +} + +// TODO(allen): Query theme settings +#if 0 +CUSTOM_COMMAND_SIG(save_theme_settings){ + FILE *file = fopen(".4coder_settings", "rb"); + char theme_name[128]; + char font_name[128]; + + fscanf(file, "%*128s %*128s", theme_name, font_name); + + if (file){ + replace_char(theme_name, '#', ' '); + replace_char(font_name, '#', ' '); + + fclose(file); + + app->change_theme(app, theme_name, strlen(theme_name)); + app->change_font(app, font_name, strlen(font_name)); } +} +#endif - push_parameter(app, par_lex_as_cpp_file, treat_as_code); - push_parameter(app, par_wrap_lines, !treat_as_code); - push_parameter(app, par_key_mapid, (treat_as_code)?((int)my_experiment_map):((int)mapid_file)); - exec_command(app, cmdid_set_settings); +void experiment_extension(Bind_Helper *context){ + bind(context, 'k', MDFR_ALT, kill_rect); + bind(context, '+', MDFR_CTRL, complete_word); +} - // no meaning for return +#include + +HOOK_SIG(experimental_start_hook){ + my_start(app); + + FILE *file = fopen(".4coder_settings", "rb"); + char theme_name[128]; + char font_name[128]; + + if (file){ + fscanf(file, "%127s\n%127s", theme_name, font_name); + + replace_char(theme_name, '#', ' '); + replace_char(font_name, '#', ' '); + + fclose(file); + + app->change_theme(app, theme_name, (int)strlen(theme_name)); + app->change_font(app, font_name, (int)strlen(font_name)); + } + return(0); } -CUSTOM_COMMAND_SIG(kill_rect){ - // TODO +int get_bindings(void *data, int size){ + Bind_Helper context_ = begin_bind_helper(data, size); + Bind_Helper *context = &context_; + + set_hook(context, hook_start, experimental_start_hook); + set_hook(context, hook_open_file, my_file_settings); + + set_scroll_rule(context, smooth_scroll_rule); + + default_keys(context, experiment_extension); + + int result = end_bind_helper(context); + return(result); } -void experiments_get_bindings(Bind_Helper *context){ - default_get_bindings(context, 0); - - set_hook(context, hook_start, my_start); - set_hook(context, hook_open_file, experiment_file_settings); - - begin_map(context, my_experiment_map); - inherit_map(my_code_map); - - - end_map(context); -} \ No newline at end of file +// BOTTOM +