diff --git a/4coder_base_commands.cpp b/4coder_base_commands.cpp index 240af479..cd72aad1 100644 --- a/4coder_base_commands.cpp +++ b/4coder_base_commands.cpp @@ -243,6 +243,13 @@ CUSTOM_COMMAND_SIG(move_right){ view_set_cursor(app, &view, seek_character_pos(new_pos), 1); } +CUSTOM_COMMAND_SIG(select_all){ + View_Summary view = get_active_view(app, AccessProtected); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); + view_set_cursor(app, &view, seek_character_pos(0), true); + view_set_mark(app, &view, seek_character_pos(buffer.size)); +} + // // Long Seeks // @@ -418,21 +425,6 @@ CUSTOM_COMMAND_SIG(clean_all_lines){ } -// -// Scroll Bar Controlling -// - -CUSTOM_COMMAND_SIG(show_scrollbar){ - View_Summary view = get_active_view(app, AccessProtected); - view_set_setting(app, &view, ViewSetting_ShowScrollbar, true); -} - -CUSTOM_COMMAND_SIG(hide_scrollbar){ - View_Summary view = get_active_view(app, AccessProtected); - view_set_setting(app, &view, ViewSetting_ShowScrollbar, false); -} - - // // Basic Panel Management // @@ -465,6 +457,16 @@ CUSTOM_COMMAND_SIG(open_panel_hsplit){ // Common Settings Commands // +CUSTOM_COMMAND_SIG(show_scrollbar){ + View_Summary view = get_active_view(app, AccessProtected); + view_set_setting(app, &view, ViewSetting_ShowScrollbar, true); +} + +CUSTOM_COMMAND_SIG(hide_scrollbar){ + View_Summary view = get_active_view(app, AccessProtected); + view_set_setting(app, &view, ViewSetting_ShowScrollbar, false); +} + //toggle_fullscreen can be used as a command CUSTOM_COMMAND_SIG(toggle_line_wrap){ @@ -784,6 +786,20 @@ CUSTOM_COMMAND_SIG(query_replace){ } +// +// File Handling Commands +// + +CUSTOM_COMMAND_SIG(save_all_dirty_buffers){ + for (Buffer_Summary buffer = get_buffer_first(app, AccessOpen); + buffer.exists; + get_buffer_next(app, &buffer, AccessOpen)){ + if (buffer.dirty == DirtyState_UnsavedChanges){ + save_buffer(app, &buffer, buffer.file_name, buffer.file_name_len, 0); + } + } +} + // // cmdid wrappers // diff --git a/4coder_build_commands.cpp b/4coder_build_commands.cpp index 52ffb067..a3896a87 100644 --- a/4coder_build_commands.cpp +++ b/4coder_build_commands.cpp @@ -53,17 +53,6 @@ get_build_directory(Application_Links *app, Buffer_Summary *buffer, String *dir_ return(result); } -static void -save_all_dirty_buffers(Application_Links *app){ - for (Buffer_Summary buffer = get_buffer_first(app, AccessOpen); - buffer.exists; - get_buffer_next(app, &buffer, AccessOpen)){ - if (buffer.dirty == DirtyState_UnsavedChanges){ - save_buffer(app, &buffer, buffer.file_name, buffer.file_name_len, 0); - } - } -} - // 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){ diff --git a/4coder_default_bindings.cpp b/4coder_default_bindings.cpp index 4364e8eb..9d34b346 100644 --- a/4coder_default_bindings.cpp +++ b/4coder_default_bindings.cpp @@ -19,6 +19,7 @@ default_keys(Bind_Helper *context){ 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); diff --git a/4coder_default_framework.h b/4coder_default_framework.h index 75bb2469..349da9be 100644 --- a/4coder_default_framework.h +++ b/4coder_default_framework.h @@ -120,6 +120,22 @@ CUSTOM_COMMAND_SIG(change_active_panel){ } } +CUSTOM_COMMAND_SIG(change_active_panel_backwards){ + View_Summary view = get_active_view(app, AccessAll); + View_ID original_view_id = view.view_id; + + do{ + get_view_prev_looped(app, &view, AccessAll); + if (view.view_id != special_note_view_id){ + break; + } + }while(view.view_id != original_view_id); + + if (view.exists){ + set_active_view(app, &view); + } +} + // // View Variabls // diff --git a/4coder_default_include.cpp b/4coder_default_include.cpp index 88d92ba1..c51a6292 100644 --- a/4coder_default_include.cpp +++ b/4coder_default_include.cpp @@ -128,6 +128,46 @@ CUSTOM_COMMAND_SIG(snipe_token_or_word){ } +// +// Line Manipulation +// + +CUSTOM_COMMAND_SIG(duplicate_line){ + View_Summary view = get_active_view(app, AccessOpen); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); + + Partition *part = &global_part; + + Temp_Memory temp = begin_temp_memory(part); + String line_string = {0}; + read_line(app, part, &buffer, view.cursor.line, &line_string); + + push_array(part, char, 1); + ++line_string.memory_size; + append_s_char(&line_string, '\n'); + + int32_t pos = buffer_get_line_end(app, &buffer, view.cursor.line) + 1; + buffer_replace_range(app, &buffer, pos, pos, line_string.str, line_string.size); + + end_temp_memory(temp); +} + +CUSTOM_COMMAND_SIG(delete_line){ + View_Summary view = get_active_view(app, AccessOpen); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); + + Partition *part = &global_part; + + Temp_Memory temp = begin_temp_memory(part); + int32_t start = buffer_get_line_start(app, &buffer, view.cursor.line); + int32_t end = buffer_get_line_end(app, &buffer, view.cursor.line) + 1; + + buffer_replace_range(app, &buffer, start, end, 0, 0); + + end_temp_memory(temp); +} + + // // Clipboard + Indent Combo Command // @@ -338,6 +378,11 @@ CUSTOM_COMMAND_SIG(open_in_other){ exec_command(app, interactive_open); } +CUSTOM_COMMAND_SIG(new_in_other){ + exec_command(app, change_active_panel); + exec_command(app, interactive_new); +} + // // File Navigating diff --git a/4coder_helper/4coder_helper.h b/4coder_helper/4coder_helper.h index eee29503..62587937 100644 --- a/4coder_helper/4coder_helper.h +++ b/4coder_helper/4coder_helper.h @@ -307,6 +307,44 @@ view_open_file(Application_Links *app, View_Summary *view, char *filename, int32 return(result); } +static void +get_view_prev(Application_Links *app, View_Summary *view, uint32_t access){ + if (view->exists){ + View_ID original_id = view->view_id; + View_ID check_id = original_id; + + View_Summary new_view = {0}; + + for (;;){ + --check_id; + if (check_id <= 0){ + check_id = 16; + } + if (check_id == original_id){ + new_view = *view; + break; + } + new_view = get_view(app, check_id, access); + if (new_view.exists){ + break; + } + } + + *view = new_view; + } +} + +static View_Summary +get_view_last(Application_Links *app, uint32_t access){ + View_Summary view = {0}; + view.exists = true; + get_view_prev(app, &view, access); + if (view.view_id < 1 || view.view_id > 16){ + view = null_view_summary; + } + return(view); +} + static void get_view_next_looped(Application_Links *app, View_Summary *view, uint32_t access){ get_view_next(app, view, access); @@ -315,6 +353,14 @@ get_view_next_looped(Application_Links *app, View_Summary *view, uint32_t access } } +static void +get_view_prev_looped(Application_Links *app, View_Summary *view, uint32_t access){ + get_view_prev(app, view, access); + if (!view->exists){ + *view = get_view_last(app, access); + } +} + static void refresh_buffer(Application_Links *app, Buffer_Summary *buffer){ *buffer = get_buffer(app, buffer->buffer_id, AccessAll); diff --git a/4coder_search.cpp b/4coder_search.cpp index 1ba18f60..d6669ad4 100644 --- a/4coder_search.cpp +++ b/4coder_search.cpp @@ -676,7 +676,8 @@ CUSTOM_COMMAND_SIG(list_all_substring_locations_case_insensitive){ generic_search_all_buffers(app, &global_general, &global_part, bar.string, SearchFlag_CaseInsensitive | SearchFlag_MatchSubstring); } -CUSTOM_COMMAND_SIG(list_all_locations_of_identifier){ +static void +list_all_locations_of_identifier_parameters(Application_Links *app, bool32 substrings, bool32 case_insensitive){ View_Summary view = get_active_view(app, AccessProtected); Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); @@ -692,12 +693,31 @@ CUSTOM_COMMAND_SIG(list_all_locations_of_identifier){ if (success){ String str = make_string(space, size); exec_command(app, change_active_panel); - generic_search_all_buffers(app, &global_general, &global_part, str, SearchFlag_MatchWholeWord); + + uint32_t flags = 0; + if (substrings){ + flags |= SearchFlag_MatchSubstring; + } + else{ + flags |= SearchFlag_MatchWholeWord; + } + if (case_insensitive){ + flags |= SearchFlag_CaseInsensitive; + } + generic_search_all_buffers(app, &global_general, &global_part, str, flags); } } } } +CUSTOM_COMMAND_SIG(list_all_locations_of_identifier){ + list_all_locations_of_identifier_parameters(app, false, false); +} + +CUSTOM_COMMAND_SIG(list_all_locations_of_identifier_case_insensitive){ + list_all_locations_of_identifier_parameters(app, false, true); +} + // // Word Complete Command // diff --git a/4coder_windows_bindings.cpp b/4coder_windows_bindings.cpp new file mode 100644 index 00000000..95ad7c28 --- /dev/null +++ b/4coder_windows_bindings.cpp @@ -0,0 +1,198 @@ +/* +4coder_windows_bindings.cpp - Supplies bindings very similar to the bindings in modern style editors like notepad. + +TYPE: 'build-target' +*/ + +// TOP + +#if !defined(FCODER_WINDOWS_BINDINGS_CPP) +#define FCODER_WINDOWS_BINDINGS_CPP + +#include "4coder_default_include.cpp" + +void +default_keys(Bind_Helper *context){ + begin_map(context, mapid_global); + + bind(context, 't', MDFR_CTRL, open_panel_vsplit); + bind(context, 'T', MDFR_CTRL, open_panel_hsplit); + bind(context, 'w', MDFR_CTRL, close_panel); + bind(context, '\t', MDFR_CTRL, change_active_panel); + bind(context, '\t', MDFR_CTRL | MDFR_SHIFT, change_active_panel_backwards); + + bind(context, 'n', MDFR_CTRL, interactive_new); + bind(context, 'n', MDFR_ALT, new_in_other); + bind(context, 'o', MDFR_CTRL, interactive_open); + 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, '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_CTRL, change_to_build_panel); + bind(context, '|', MDFR_CTRL, close_build_panel); + bind(context, key_down, MDFR_ALT, goto_next_error); + bind(context, key_up, MDFR_ALT, goto_prev_error); + bind(context, key_up, MDFR_ALT | MDFR_SHIFT, goto_first_error); + + 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, '@', MDFR_ALT, toggle_mouse); + bind(context, key_page_up, MDFR_CTRL, toggle_fullscreen); + bind(context, 'W', MDFR_CTRL, exit_4coder); + bind(context, key_f4, 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); + 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, key_right, MDFR_ALT, seek_whitespace_right); + bind(context, key_left, MDFR_ALT, seek_whitespace_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, ' ', MDFR_ALT, word_complete); + bind(context, '\t', MDFR_NONE, auto_tab_line_at_cursor); + bind(context, '\t', MDFR_SHIFT, auto_tab_range); + + bind(context, 't', MDFR_ALT, write_todo); + bind(context, 'y', MDFR_ALT, write_note); + bind(context, 'r', MDFR_ALT, write_block); + 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); + bind_vanilla_keys(context, write_character); + + bind(context, key_mouse_left, MDFR_NONE, click_set_cursor); + bind(context, key_mouse_left_release, MDFR_NONE, click_set_mark); + bind(context, key_mouse_right, 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_alphanumeric_or_camel_right); + bind(context, key_left, MDFR_CTRL, seek_alphanumeric_or_camel_left); + bind(context, key_right, MDFR_ALT, seek_whitespace_right); + bind(context, key_left, MDFR_ALT, 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_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, ' ', MDFR_CTRL, set_mark); + bind(context, 'a', MDFR_CTRL, select_all); + bind(context, 'c', MDFR_CTRL, copy); + bind(context, 'd', MDFR_CTRL, duplicate_line); + bind(context, 'f', MDFR_ALT, list_all_locations); + bind(context, 'f', MDFR_CTRL, list_all_substring_locations_case_insensitive); + bind(context, 'F', MDFR_CTRL, list_all_locations_of_identifier); + bind(context, 'F', MDFR_ALT, list_all_locations_of_identifier_case_insensitive); + bind(context, 'e', MDFR_CTRL, center_view); + bind(context, 'E', MDFR_CTRL, left_adjust_view); + bind(context, 'g', MDFR_CTRL, goto_line); + bind(context, 'h', MDFR_CTRL, query_replace); + bind(context, 'H', MDFR_CTRL, replace_in_range); + bind(context, 'i', MDFR_CTRL, search); + bind(context, 'I', MDFR_CTRL, reverse_search); + bind(context, 'K', MDFR_CTRL, kill_buffer); + bind(context, 'l', MDFR_CTRL, delete_line); + bind(context, 'L', MDFR_ALT, toggle_line_wrap); + bind(context, 'O', MDFR_CTRL, reopen); + bind(context, 's', MDFR_CTRL, save); + bind(context, 'S', MDFR_ALT, save_as); + 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); + bind(context, ' ', MDFR_SHIFT, write_character); + + end_map(context); +} + +#ifndef NO_BINDING +extern "C" int32_t +get_bindings(void *data, int32_t size){ + Bind_Helper context_ = begin_bind_helper(data, size); + Bind_Helper *context = &context_; + + set_all_default_hooks(context); + default_keys(context); + + int32_t result = end_bind_helper(context); + return(result); +} +#endif //NO_BINDING + +#endif + +// BOTTOM + diff --git a/4ed.cpp b/4ed.cpp index dbf68ade..7a9192f5 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -1356,8 +1356,7 @@ App_Init_Sig(app_init){ map_add(map_ptr, unit->binding.code, unit->binding.modifiers, func, unit->binding.command_id); } } - } - break; + }break; case unit_callback: if (map_ptr){ @@ -1372,8 +1371,7 @@ App_Init_Sig(app_init){ map_add(map_ptr, unit->callback.code, unit->callback.modifiers, func, custom); } } - } - break; + }break; case unit_hook: { diff --git a/4ed_command.cpp b/4ed_command.cpp index 6b946cc3..c7a8283f 100644 --- a/4ed_command.cpp +++ b/4ed_command.cpp @@ -40,7 +40,8 @@ map_hash(u16 event_code, u8 modifiers){ } internal b32 -map_add(Command_Map *map, u16 event_code, u8 modifiers, Command_Function function, Custom_Command_Function *custom = 0){ +map_add(Command_Map *map, u16 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); Command_Binding bind; bind.function = function; @@ -52,18 +53,21 @@ map_add(Command_Map *map, u16 event_code, u8 modifiers, Command_Function functio Command_Binding entry; while ((entry = map->commands[index]).function && entry.hash != -1){ if (entry.hash == bind.hash){ - return 1; + result = 1; + break; } index = (index + 1) % max; } - map->commands[index] = bind; - ++map->count; - return 0; + if (override_original || !result){ + map->commands[index] = bind; + ++map->count; + } + return(result); } inline b32 -map_add(Command_Map *map, u16 event_code, u8 modifiers, Command_Function function, u64 custom_id){ - return (map_add(map, event_code, modifiers, function, (Custom_Command_Function*)custom_id)); +map_add(Command_Map *map, u16 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); } internal b32