diff --git a/4coder_custom.h b/4coder_custom.h index 84e1b96e..54fd2f4a 100644 --- a/4coder_custom.h +++ b/4coder_custom.h @@ -172,55 +172,57 @@ typedef struct File_List{ enum Command_ID{ cmdid_null, - cmdid_write_character, + cmdid_seek_left, cmdid_seek_right, - cmdid_seek_whitespace_up, - cmdid_seek_whitespace_down, + cmdid_center_view, + cmdid_word_complete, - cmdid_set_mark, + cmdid_copy, cmdid_cut, cmdid_paste, cmdid_paste_next, - cmdid_delete_range, + cmdid_undo, cmdid_redo, cmdid_history_backward, cmdid_history_forward, + cmdid_interactive_new, cmdid_interactive_open, cmdid_reopen, cmdid_save, - cmdid_change_active_panel, cmdid_interactive_switch_buffer, cmdid_interactive_kill_buffer, cmdid_kill_buffer, - cmdid_toggle_line_wrap, - cmdid_toggle_endline_mode, + + cmdid_change_active_panel, + cmdid_to_uppercase, cmdid_to_lowercase, + + cmdid_toggle_line_wrap, cmdid_toggle_show_whitespace, - cmdid_clean_all_lines, + cmdid_eol_dosify, cmdid_eol_nixify, + + cmdid_clean_all_lines, cmdid_auto_tab_range, + cmdid_open_panel_vsplit, cmdid_open_panel_hsplit, cmdid_close_panel, - cmdid_move_left, - cmdid_move_right, - cmdid_delete, - cmdid_backspace, - cmdid_move_up, - cmdid_move_down, + cmdid_seek_end_of_line, cmdid_seek_beginning_of_line, cmdid_page_up, cmdid_page_down, - cmdid_open_color_tweaker, cmdid_cursor_mark_swap, + + cmdid_open_color_tweaker, cmdid_open_menu, cmdid_hide_scrollbar, cmdid_show_scrollbar, @@ -240,6 +242,7 @@ enum Param_ID{ par_lex_as_cpp_file, par_wrap_lines, par_key_mapid, + par_show_whitespace, par_cli_path, par_cli_command, par_clear_blank_lines, @@ -270,9 +273,9 @@ enum Special_Hook_ID{ _hook_scroll_rule = hook_type_count, }; -// NOTE(allen): None of the members of *_Summary structs nor any of the -// data pointed to by the members should be modified, I would have made -// them all const... but that causes a lot problems for C++ reasons. +// None of the members of *_Summary structs nor any of the data pointed +// to by the members should be modified, I would have made them all +// const... but that causes a lot problems for C++ reasons. struct Buffer_Summary{ int exists; int ready; @@ -305,8 +308,9 @@ struct View_Summary{ Full_Cursor cursor; Full_Cursor mark; float preferred_x; - int line_height; + float line_height; int unwrapped_lines; + int show_whitespace; }; inline View_Summary view_summary_zero(){ diff --git a/4coder_default_bindings.cpp b/4coder_default_bindings.cpp index 2a18a793..da15c181 100644 --- a/4coder_default_bindings.cpp +++ b/4coder_default_bindings.cpp @@ -49,44 +49,6 @@ CUSTOM_COMMAND_SIG(switch_to_compilation){ app->view_set_buffer(app, &view, buffer.buffer_id); } -CUSTOM_COMMAND_SIG(move_up_10){ - View_Summary view; - float x, y; - - view = app->get_active_view(app); - x = view.preferred_x; - - if (view.unwrapped_lines){ - y = view.cursor.unwrapped_y; - } - else{ - y = view.cursor.wrapped_y; - } - - y -= 10*view.line_height; - - app->view_set_cursor(app, &view, seek_xy(x, y, 0, view.unwrapped_lines), 0); -} - -CUSTOM_COMMAND_SIG(move_down_10){ - View_Summary view; - float x, y; - - view = app->get_active_view(app); - x = view.preferred_x; - - if (view.unwrapped_lines){ - y = view.cursor.unwrapped_y; - } - else{ - y = view.cursor.wrapped_y; - } - - y += 10*view.line_height; - - app->view_set_cursor(app, &view, seek_xy(x, y, 0, view.unwrapped_lines), 0); -} - CUSTOM_COMMAND_SIG(rewrite_as_single_caps){ View_Summary view; Buffer_Summary buffer; @@ -264,7 +226,7 @@ HOOK_SIG(my_file_settings){ 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); } @@ -272,7 +234,7 @@ HOOK_SIG(my_file_settings){ void default_keys(Bind_Helper *context){ begin_map(context, mapid_global); - + bind(context, 'p', MDFR_CTRL, cmdid_open_panel_vsplit); bind(context, '_', MDFR_CTRL, cmdid_open_panel_hsplit); bind(context, 'P', MDFR_CTRL, cmdid_close_panel); @@ -284,40 +246,40 @@ default_keys(Bind_Helper *context){ bind(context, 'c', MDFR_ALT, cmdid_open_color_tweaker); bind(context, 'o', MDFR_ALT, open_in_other); bind(context, 'w', MDFR_CTRL, save_as); - + bind(context, 'm', MDFR_ALT, build_search); bind(context, 'x', MDFR_ALT, execute_arbitrary_command); bind(context, 'z', MDFR_ALT, execute_any_cli); bind(context, 'Z', MDFR_ALT, execute_previous_cli); - + // NOTE(allen): These callbacks may not actually be useful to you, but // go look at them and see what they do. bind(context, 'M', MDFR_ALT | MDFR_CTRL, open_my_files); bind(context, 'M', MDFR_ALT, build_at_launch_location); - + end_map(context); begin_map(context, my_empty_map1); inherit_map(context, mapid_nomap); end_map(context); - + begin_map(context, my_empty_map2); inherit_map(context, mapid_nomap); end_map(context); - + begin_map(context, my_code_map); - + // NOTE(allen|a3.1): Set this map (my_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. @@ -327,11 +289,11 @@ default_keys(Bind_Helper *context){ 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, cmdid_word_complete); bind(context, '\t', MDFR_CTRL, cmdid_auto_tab_range); bind(context, '\t', MDFR_SHIFT, auto_tab_line_at_cursor); - + bind(context, '=', MDFR_CTRL, write_increment); bind(context, 't', MDFR_ALT, write_allen_todo); bind(context, 'n', MDFR_ALT, write_allen_note); @@ -341,54 +303,53 @@ default_keys(Bind_Helper *context){ bind(context, 'i', MDFR_ALT, if0_off); bind(context, '1', MDFR_ALT, open_file_in_quotes); bind(context, '0', MDFR_CTRL, write_zero_struct); - + 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, cmdid_write_character); - - bind(context, key_left, MDFR_NONE, cmdid_move_left); - bind(context, key_right, MDFR_NONE, cmdid_move_right); - bind(context, key_del, MDFR_NONE, cmdid_delete); - bind(context, key_back, MDFR_NONE, cmdid_backspace); - bind(context, key_up, MDFR_NONE, cmdid_move_up); - bind(context, key_down, MDFR_NONE, cmdid_move_down); + bind_vanilla_keys(context, write_character); + + 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_back, MDFR_NONE, backspace_char); + bind(context, key_up, MDFR_NONE, move_up); + bind(context, key_down, MDFR_NONE, move_down); bind(context, key_end, MDFR_NONE, cmdid_seek_end_of_line); bind(context, key_home, MDFR_NONE, cmdid_seek_beginning_of_line); bind(context, key_page_up, MDFR_NONE, cmdid_page_up); bind(context, key_page_down, MDFR_NONE, cmdid_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, cmdid_seek_whitespace_up); - bind(context, key_down, MDFR_CTRL, cmdid_seek_whitespace_down); - + bind(context, key_up, MDFR_CTRL, seek_whitespace_up); + bind(context, key_down, MDFR_CTRL, seek_whitespace_down); + 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_back, MDFR_ALT, snipe_token_or_word); - - bind(context, ' ', MDFR_CTRL, cmdid_set_mark); + + bind(context, ' ', MDFR_CTRL, set_mark); bind(context, 'a', MDFR_CTRL, replace_in_range); bind(context, 'c', MDFR_CTRL, cmdid_copy); - bind(context, 'd', MDFR_CTRL, cmdid_delete_range); + bind(context, 'd', MDFR_CTRL, 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, 'l', MDFR_CTRL, cmdid_toggle_line_wrap); bind(context, 'j', MDFR_CTRL, cmdid_to_lowercase); bind(context, 'K', MDFR_CTRL, cmdid_kill_buffer); - bind(context, 'L', MDFR_CTRL, cmdid_toggle_endline_mode); + bind(context, 'l', MDFR_CTRL, cmdid_toggle_line_wrap); bind(context, 'm', MDFR_CTRL, cmdid_cursor_mark_swap); bind(context, 'O', MDFR_CTRL, cmdid_reopen); bind(context, 'q', MDFR_CTRL, query_replace); @@ -411,7 +372,7 @@ default_keys(Bind_Helper *context){ 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, ' ', MDFR_SHIFT, write_character); end_map(context); } @@ -427,7 +388,7 @@ get_bindings(void *data, int size){ // 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); diff --git a/4coder_default_include.cpp b/4coder_default_include.cpp index da08c946..a5f49440 100644 --- a/4coder_default_include.cpp +++ b/4coder_default_include.cpp @@ -8,14 +8,289 @@ #include -static void -write_string(Application_Links *app, String string){ - Buffer_Summary buffer = get_active_buffer(app); - app->buffer_replace_range(app, &buffer, buffer.buffer_cursor_pos, buffer.buffer_cursor_pos, string.str, string.size); +inline float +get_view_y(View_Summary view){ + float y; + if (view.unwrapped_lines){ + y = view.cursor.unwrapped_y; + } + else{ + y = view.cursor.wrapped_y; + } + return(y); } -CUSTOM_COMMAND_SIG(write_increment){ - write_string(app, make_lit_string("++")); +inline float +get_view_x(View_Summary view){ + float x; + if (view.unwrapped_lines){ + x = view.cursor.unwrapped_x; + } + else{ + x = view.cursor.wrapped_x; + } + return(x); +} + +// +// Fundamental Editing +// + +CUSTOM_COMMAND_SIG(write_character){ + View_Summary view = app->get_active_view(app); + + User_Input in = app->get_command_input(app); + char character = 0; + + if (in.type == UserInputKey){ + character = in.key.character; + } + + if (character != 0){ + Buffer_Summary buffer = app->get_buffer(app, view.buffer_id); + int pos = view.cursor.pos; + int next_pos = pos + 1; + app->buffer_replace_range(app, &buffer, + pos, pos, &character, 1); + app->view_set_cursor(app, &view, seek_pos(next_pos), true); + } +} + +CUSTOM_COMMAND_SIG(delete_char){ + View_Summary view = app->get_active_view(app); + Buffer_Summary buffer = app->get_buffer(app, view.buffer_id); + + int pos = view.cursor.pos; + if (0 < buffer.size && pos < buffer.size){ + app->buffer_replace_range(app, &buffer, + pos, pos+1, 0, 0); + } +} + +CUSTOM_COMMAND_SIG(backspace_char){ + View_Summary view = app->get_active_view(app); + Buffer_Summary buffer = app->get_buffer(app, view.buffer_id); + + int pos = view.cursor.pos; + if (0 < pos && pos <= buffer.size){ + app->buffer_replace_range(app, &buffer, + pos-1, pos, 0, 0); + + app->view_set_cursor(app, &view, seek_pos(pos-1), true); + } +} + +CUSTOM_COMMAND_SIG(set_mark){ + View_Summary view = app->get_active_view(app); + + app->view_set_mark(app, &view, seek_pos(view.cursor.pos)); +} + +CUSTOM_COMMAND_SIG(delete_range){ + View_Summary view = app->get_active_view(app); + Buffer_Summary buffer = app->get_buffer(app, view.buffer_id); + + Range range = get_range(&view); + + app->buffer_replace_range(app, &buffer, + range.min, range.max, + 0, 0); +} + +// +// Basic Navigation +// + +inline void +move_vertical(Application_Links *app, float line_multiplier){ + View_Summary view = app->get_active_view(app); + + float new_y = get_view_y(view) + line_multiplier*view.line_height; + float x = view.preferred_x; + + app->view_set_cursor(app, &view, + seek_xy(x, new_y, false, view.unwrapped_lines), + false); +} + +CUSTOM_COMMAND_SIG(move_up){ + move_vertical(app, -1.f); +} + +CUSTOM_COMMAND_SIG(move_down){ + move_vertical(app, 1.f); +} + +CUSTOM_COMMAND_SIG(move_up_10){ + move_vertical(app, -10.f); +} + +CUSTOM_COMMAND_SIG(move_down_10){ + move_vertical(app, 10.f); +} + + +CUSTOM_COMMAND_SIG(move_left){ + View_Summary view = app->get_active_view(app); + int new_pos = view.cursor.pos - 1; + app->view_set_cursor(app, &view, + seek_pos(new_pos), + true); +} + +CUSTOM_COMMAND_SIG(move_right){ + View_Summary view = app->get_active_view(app); + int new_pos = view.cursor.pos + 1; + app->view_set_cursor(app, &view, + seek_pos(new_pos), + true); +} + +// +// Various Forms of Seek +// + +static int +buffer_seek_whitespace_up(Application_Links *app, Buffer_Summary *buffer, int pos){ + char chunk[1024]; + int chunk_size = sizeof(chunk); + Stream_Chunk stream = {0}; + + int no_hard; + int still_looping; + char at_pos; + + --pos; + if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){ + // Step 1: Find the first non-whitespace character + // behind the current position. + still_looping = true; + do{ + for (; pos >= stream.start; --pos){ + at_pos = stream.data[pos]; + if (!char_is_whitespace(at_pos)){ + goto double_break_1; + } + } + still_looping = backward_stream_chunk(&stream); + } while(still_looping); + double_break_1:; + + // Step 2: Continue scanning backward, at each '\n' + // mark the beginning of another line by setting + // no_hard to true, set it back to false if a + // non-whitespace character is discovered before + // the next '\n' + no_hard = false; + while (still_looping){ + for (; pos >= stream.start; --pos){ + at_pos = stream.data[pos]; + if (at_pos == '\n'){ + if (no_hard){ + goto double_break_2; + } + else{ + no_hard = true; + } + } + else if (!char_is_whitespace(at_pos)){ + no_hard = false; + } + } + still_looping = backward_stream_chunk(&stream); + } + double_break_2:; + + if (pos != 0){ + ++pos; + } + } + + return(pos); +} + +static int +buffer_seek_whitespace_down(Application_Links *app, Buffer_Summary *buffer, int pos){ + char chunk[1024]; + int chunk_size = sizeof(chunk); + Stream_Chunk stream = {0}; + + int no_hard; + int prev_endline; + int still_looping; + char at_pos; + + if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){ + // Step 1: Find the first non-whitespace character + // ahead of the current position. + still_looping = true; + do{ + for (; pos < stream.end; ++pos){ + at_pos = stream.data[pos]; + if (!char_is_whitespace(at_pos)){ + goto double_break_1; + } + } + still_looping = forward_stream_chunk(&stream); + } while(still_looping); + double_break_1:; + + // Step 2: Continue scanning forward, at each '\n' + // mark it as the beginning of a new line by updating + // the prev_endline value. If another '\n' is found + // with non-whitespace then the previous line was + // all whitespace. + no_hard = false; + prev_endline = -1; + while(still_looping){ + for (; pos < stream.end; ++pos){ + at_pos = stream.data[pos]; + if (at_pos == '\n'){ + if (no_hard){ + goto double_break_2; + } + else{ + no_hard = true; + prev_endline = pos; + } + } + else if (!char_is_whitespace(at_pos)){ + no_hard = false; + } + } + still_looping = forward_stream_chunk(&stream); + } + double_break_2:; + + if (prev_endline == -1 || prev_endline+1 >= buffer->size){ + pos = buffer->size; + } + else{ + pos = prev_endline+1; + } + } + + return(pos); +} + +CUSTOM_COMMAND_SIG(seek_whitespace_up){ + View_Summary view = app->get_active_view(app); + Buffer_Summary buffer = app->get_buffer(app, view.locked_buffer_id); + + int new_pos = buffer_seek_whitespace_up(app, &buffer, view.cursor.pos); + app->view_set_cursor(app, &view, + seek_pos(new_pos), + true); +} + +CUSTOM_COMMAND_SIG(seek_whitespace_down){ + View_Summary view = app->get_active_view(app); + Buffer_Summary buffer = app->get_buffer(app, view.locked_buffer_id); + + int new_pos = buffer_seek_whitespace_down(app, &buffer, view.cursor.pos); + app->view_set_cursor(app, &view, + seek_pos(new_pos), + true); } static void @@ -38,6 +313,23 @@ SEEK_COMMAND(alphanumeric, left, BoundryAlphanumeric) SEEK_COMMAND(alphanumeric_or_camel, right, BoundryAlphanumeric | BoundryCamelCase) SEEK_COMMAND(alphanumeric_or_camel, left, BoundryAlphanumeric | BoundryCamelCase) + +// +// Special string writing commands +// + +static void +write_string(Application_Links *app, String string){ + Buffer_Summary buffer = get_active_buffer(app); + app->buffer_replace_range(app, &buffer, + buffer.buffer_cursor_pos, buffer.buffer_cursor_pos, + string.str, string.size); +} + +CUSTOM_COMMAND_SIG(write_increment){ + write_string(app, make_lit_string("++")); +} + static void long_braces(Application_Links *app, char *text, int size){ View_Summary view; @@ -672,7 +964,7 @@ CUSTOM_COMMAND_SIG(auto_tab_whole_file){ } CUSTOM_COMMAND_SIG(write_and_auto_tab){ - exec_command(app, cmdid_write_character); + exec_command(app, write_character); exec_command(app, auto_tab_line_at_cursor); } diff --git a/4ed.cpp b/4ed.cpp index 3444ebb4..6f83f9fe 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -227,24 +227,6 @@ COMMAND_DECL(null){ AllowLocal(command); } -COMMAND_DECL(write_character){ - - USE_MODELS(models); - REQ_OPEN_VIEW(view); - REQ_FILE(file, view); - - char character; - i32 pos, next_cursor_pos; - - character = command->key.character; - if (character != 0){ - pos = view->recent->cursor.pos; - next_cursor_pos = view->recent->cursor.pos + 1; - view_replace_range(system, models, view, pos, pos, &character, 1, next_cursor_pos); - view_cursor_move(view, next_cursor_pos); - } -} - internal i32 seek_token_left(Cpp_Token_Stack *tokens, i32 pos){ Cpp_Get_Token_Result get = cpp_get_token(tokens, pos); @@ -275,7 +257,6 @@ seek_token_right(Cpp_Token_Stack *tokens, i32 pos){ } COMMAND_DECL(seek_left){ - REQ_READABLE_VIEW(view); REQ_FILE(file, view); @@ -328,7 +309,6 @@ COMMAND_DECL(seek_left){ } COMMAND_DECL(seek_right){ - REQ_READABLE_VIEW(view); REQ_FILE(file, view); @@ -382,26 +362,7 @@ COMMAND_DECL(seek_right){ view_cursor_move(view, new_pos); } -COMMAND_DECL(seek_whitespace_up){ - - REQ_READABLE_VIEW(view); - REQ_FILE(file, view); - - i32 pos = buffer_seek_whitespace_up(&file->state.buffer, view->recent->cursor.pos); - view_cursor_move(view, pos); -} - -COMMAND_DECL(seek_whitespace_down){ - - REQ_READABLE_VIEW(view); - REQ_FILE(file, view); - - i32 pos = buffer_seek_whitespace_down(&file->state.buffer, view->recent->cursor.pos); - view_cursor_move(view, pos); -} - COMMAND_DECL(center_view){ - USE_VIEW(view); REQ_FILE(file, view); @@ -420,7 +381,6 @@ COMMAND_DECL(center_view){ } COMMAND_DECL(word_complete){ - USE_MODELS(models); USE_VARS(vars); REQ_OPEN_VIEW(view); @@ -579,14 +539,6 @@ COMMAND_DECL(word_complete){ } } -COMMAND_DECL(set_mark){ - REQ_READABLE_VIEW(view); - REQ_FILE(file, view); - - view->recent->mark = (i32)view->recent->cursor.pos; - view->recent->preferred_x = view_get_cursor_x(view); -} - COMMAND_DECL(copy){ USE_MODELS(models); REQ_READABLE_VIEW(view); @@ -729,24 +681,6 @@ COMMAND_DECL(paste_next){ } } -COMMAND_DECL(delete_range){ - USE_MODELS(models); - REQ_OPEN_VIEW(view); - REQ_FILE(file, view); - - Range range; - i32 next_cursor_pos; - - range = make_range(view->recent->cursor.pos, view->recent->mark); - if (range.start < range.end){ - next_cursor_pos = range.start; - Assert(range.end <= buffer_size(&file->state.buffer)); - view_replace_range(system, models, view, range.start, range.end, 0, 0, next_cursor_pos); - view_cursor_move(view, next_cursor_pos); - view->recent->mark = range.start; - } -} - COMMAND_DECL(undo){ USE_MODELS(models); REQ_OPEN_VIEW(view); @@ -755,7 +689,6 @@ COMMAND_DECL(undo){ view_undo(system, models, view); Assert(file->state.undo.undo.size >= 0); - } COMMAND_DECL(redo){ @@ -1279,6 +1212,7 @@ COMMAND_DECL(close_panel){ } } +#if 0 COMMAND_DECL(move_left){ REQ_READABLE_VIEW(view); @@ -1303,18 +1237,17 @@ COMMAND_DECL(delete){ USE_MODELS(models); REQ_OPEN_VIEW(view); REQ_FILE(file, view); - + i32 size = buffer_size(&file->state.buffer); i32 cursor_pos = view->recent->cursor.pos; if (0 < size && cursor_pos < size){ i32 start, end; start = cursor_pos; end = cursor_pos+1; - - Assert(end - start > 0); - + i32 next_cursor_pos = start; - view_replace_range(system, models, view, start, end, 0, 0, next_cursor_pos); + view_replace_range(system, models, view, + start, end, 0, 0, next_cursor_pos); view_cursor_move(view, next_cursor_pos); } } @@ -1331,41 +1264,12 @@ COMMAND_DECL(backspace){ end = cursor_pos; start = cursor_pos-1; - i32 shift = (end - start); - Assert(shift > 0); - - i32 next_cursor_pos = view->recent->cursor.pos - shift; + i32 next_cursor_pos = view->recent->cursor.pos - 1; view_replace_range(system, models, view, start, end, 0, 0, next_cursor_pos); view_cursor_move(view, next_cursor_pos); } } - -COMMAND_DECL(move_up){ - USE_MODELS(models); - REQ_READABLE_VIEW(view); - REQ_FILE(file, view); - - f32 line_height = (f32)get_font_info(models->font_set, models->global_font.font_id)->height; - f32 cy = view_get_cursor_y(view)-line_height; - f32 px = view->recent->preferred_x; - if (cy >= 0){ - view->recent->cursor = view_compute_cursor_from_xy(view, px, cy); - file->state.cursor_pos = view->recent->cursor.pos; - } -} - -COMMAND_DECL(move_down){ - - USE_MODELS(models); - REQ_READABLE_VIEW(view); - REQ_FILE(file, view); - - f32 line_height = (f32)get_font_info(models->font_set, models->global_font.font_id)->height; - f32 cy = view_get_cursor_y(view)+line_height; - f32 px = view->recent->preferred_x; - view->recent->cursor = view_compute_cursor_from_xy(view, px, cy); - file->state.cursor_pos = view->recent->cursor.pos; -} +#endif COMMAND_DECL(seek_end_of_line){ REQ_READABLE_VIEW(view); @@ -1463,6 +1367,8 @@ COMMAND_DECL(set_settings){ Editing_File *file = 0; b32 set_mapid = 0; i32 new_mapid = 0; + b32 set_show_whitespace = 0; + b32 show_whitespace = 0; Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); @@ -1512,13 +1418,19 @@ COMMAND_DECL(set_settings){ } } }break; + + case par_show_whitespace: + { + set_show_whitespace = 1; + show_whitespace = dynamic_to_bool(¶m->param.value); + }break; } } if (set_mapid){ for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); - file_view_iter_good(iter); - iter = file_view_iter_next(iter)){ + file_view_iter_good(iter); + iter = file_view_iter_next(iter)){ iter.view->map = get_map(models, file->settings.base_map_id); } } @@ -1760,12 +1672,14 @@ fill_view_summary(View_Summary *view, View *vptr, Live_Views *live_set, Working_ i32 lock_level; int buffer_id; *view = view_summary_zero(); - + if (vptr->in_use){ view->exists = 1; view->view_id = (int)(vptr - live_set->views) + 1; - view->line_height = vptr->line_height; + view->line_height = (float)(vptr->line_height); view->unwrapped_lines = vptr->file_data.unwrapped_lines; + view->show_whitespace = vptr->file_data.show_whitespace; + if (vptr->file_data.file){ lock_level = view_lock_level(vptr); @@ -1929,121 +1843,6 @@ extern "C"{ return(buffer); } -#if 0 - BUFFER_SEEK_DELIMITER_SIG(external_buffer_seek_delimiter){ - Command_Data *cmd = (Command_Data*)app->cmd_context; - Editing_File *file; - Working_Set *working_set; - int result = 0; - int size; - - if (buffer->exists){ - working_set = &cmd->models->working_set; - file = working_set_get_active_file(working_set, buffer->buffer_id); - if (file && file_is_ready(file)){ - size = buffer_size(&file->state.buffer); - result = 1; - - if (start < 0 && !seek_forward) *out = start; - else if (start >= size && seek_forward) *out = start; - else{ - if (seek_forward){ - *out = buffer_seek_delimiter(&file->state.buffer, start, delim); - } - else{ - *out = buffer_reverse_seek_delimiter(&file->state.buffer, start, delim); - } - } - - fill_buffer_summary(buffer, file, working_set); - } - } - - return(result); - } - - BUFFER_SEEK_STRING_SIG(external_buffer_seek_string){ - Command_Data *cmd = (Command_Data*)app->cmd_context; - Models *models; - Editing_File *file; - Working_Set *working_set; - Partition *part; - Temp_Memory temp; - char *spare; - int result = 0; - int size; - - if (buffer->exists){ - models = cmd->models; - working_set = &models->working_set; - file = working_set_get_active_file(working_set, buffer->buffer_id); - if (file && file_is_ready(file)){ - size = buffer_size(&file->state.buffer); - - if (start < 0 && !seek_forward) *out = start; - else if (start >= size && seek_forward) *out = start; - else{ - part = &models->mem.part; - temp = begin_temp_memory(part); - spare = push_array(part, char, len); - result = 1; - if (seek_forward){ - *out = buffer_find_string(&file->state.buffer, start, size, str, len, spare); - } - else{ - *out = buffer_rfind_string(&file->state.buffer, start, str, len, spare); - } - end_temp_memory(temp); - } - fill_buffer_summary(buffer, file, working_set); - } - } - - return(result); - } - - // TODO(allen): Reduce duplication between this and external_buffer_seek_string - BUFFER_SEEK_STRING_SIG(external_buffer_seek_string_insensitive){ - Command_Data *cmd = (Command_Data*)app->cmd_context; - Models *models; - Editing_File *file; - Working_Set *working_set; - Partition *part; - Temp_Memory temp; - char *spare; - int result = 0; - int size; - - if (buffer->exists){ - models = cmd->models; - working_set = &models->working_set; - file = working_set_get_active_file(working_set, buffer->buffer_id); - if (file && file_is_ready(file)){ - size = buffer_size(&file->state.buffer); - - if (start < 0 && !seek_forward) *out = start; - else if (start >= size && seek_forward) *out = start; - else{ - part = &models->mem.part; - temp = begin_temp_memory(part); - spare = push_array(part, char, len); - result = 1; - if (seek_forward){ - *out = buffer_find_string_insensitive(&file->state.buffer, start, size, str, len, spare); - } - else{ - *out = buffer_rfind_string_insensitive(&file->state.buffer, start, str, len, spare); - } - end_temp_memory(temp); - } - fill_buffer_summary(buffer, file, working_set); - } - } - - return(result); - } -#endif - REFRESH_BUFFER_SIG(external_refresh_buffer){ int result; *buffer = external_get_buffer(app, buffer->buffer_id); @@ -2523,12 +2322,6 @@ app_links_init(System_Functions *system, Application_Links *app_links, void *dat app_links->refresh_buffer = external_refresh_buffer; -#if 0 - app_links->buffer_seek_delimiter = external_buffer_seek_delimiter; - app_links->buffer_seek_string = external_buffer_seek_string; - app_links->buffer_seek_string_insensitive = external_buffer_seek_string_insensitive; -#endif - app_links->buffer_read_range = external_buffer_read_range; app_links->buffer_replace_range = external_buffer_replace_range; @@ -2598,21 +2391,15 @@ setup_top_commands(Command_Map *commands, Partition *part, Command_Map *parent){ internal void setup_command_table(){ #define SET(n) command_table[cmdid_##n] = command_##n - SET(null); - SET(write_character); SET(seek_left); SET(seek_right); - SET(seek_whitespace_up); - SET(seek_whitespace_down); SET(center_view); SET(word_complete); - SET(set_mark); SET(copy); SET(cut); SET(paste); SET(paste_next); - SET(delete_range); SET(undo); SET(redo); SET(history_backward); @@ -2621,14 +2408,13 @@ setup_command_table(){ SET(interactive_open); SET(reopen); SET(save); - //SET(interactive_save_as); SET(change_active_panel); SET(interactive_switch_buffer); SET(interactive_kill_buffer); SET(kill_buffer); - SET(toggle_line_wrap); SET(to_uppercase); SET(to_lowercase); + SET(toggle_line_wrap); SET(toggle_show_whitespace); SET(clean_all_lines); SET(eol_dosify); @@ -2637,12 +2423,7 @@ setup_command_table(){ SET(open_panel_vsplit); SET(open_panel_hsplit); SET(close_panel); - SET(move_left); - SET(move_right); - SET(delete); - SET(backspace); - SET(move_up); - SET(move_down); + SET(seek_end_of_line); SET(seek_beginning_of_line); SET(page_up); @@ -4049,12 +3830,11 @@ App_Step_Sig(app_step){ summary.mouse = mouse_state; } - GUI_Scroll_Vars *vars = view->current_scroll; // TODO(allen): I feel like the scroll context should actually not // be allowed to change in here at all. - result = do_input_file_view(system, view, panel->inner, active, - &summary, *vars, view->scroll_region); + result = do_step_file_view(system, view, panel->inner, active, + &summary, *vars, view->scroll_region); if (result.is_animating){ app_result.animating = 1; } diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 858b2e76..5571cf0f 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -4542,10 +4542,10 @@ struct Input_Process_Result{ }; internal Input_Process_Result -do_input_file_view(System_Functions *system, - View *view, i32_Rect rect, b32 is_active, - Input_Summary *user_input, - GUI_Scroll_Vars vars, i32_Rect region){ +do_step_file_view(System_Functions *system, + View *view, i32_Rect rect, b32 is_active, + Input_Summary *user_input, + GUI_Scroll_Vars vars, i32_Rect region){ Input_Process_Result result = {0}; b32 is_file_scroll = 0; @@ -4554,6 +4554,8 @@ do_input_file_view(System_Functions *system, GUI_Target *target = &view->gui_target; GUI_Interpret_Result interpret_result = {0}; + vars.target_y = clamp(0.f, vars.target_y, vars.max_y); + result.vars = vars; result.region = region; diff --git a/4ed_gui.cpp b/4ed_gui.cpp index 2492c2fe..63f5995e 100644 --- a/4ed_gui.cpp +++ b/4ed_gui.cpp @@ -1240,8 +1240,8 @@ gui_standard_list(GUI_Target *target, GUI_id id, GUI_Scroll_Vars *vars, i32_Rect if (update->has_index_position){ GUI_View_Jump jump = gui_compute_view_jump(scroll_region, update->index_position); - jump.view_min = clamp_bottom(0.f, jump.view_min + 45.f); - jump.view_max = clamp_bottom(0.f, jump.view_max - 45.f); + jump.view_min = jump.view_min + 45.f; + jump.view_max = jump.view_max - 45.f; *vars = gui_do_jump(target, jump, *vars); } diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp index f7ec17a3..7d8aacb4 100644 --- a/buffer/4coder_buffer_abstract.cpp +++ b/buffer/4coder_buffer_abstract.cpp @@ -128,6 +128,8 @@ buffer_reverse_seek_delimiter(Buffer_Type *buffer, int pos, char delim){ return(pos); } + +#if 0 internal_4tech int buffer_seek_whitespace_down(Buffer_Type *buffer, int pos){ Buffer_Stringify_Type loop; @@ -219,6 +221,7 @@ buffer_seek_whitespace_up_end: return pos; } +#endif internal_4tech int buffer_seek_whitespace_right(Buffer_Type *buffer, int pos){