diff --git a/4coder_custom.cpp b/4coder_custom.cpp index 5f56ca88..c3bd0c62 100644 --- a/4coder_custom.cpp +++ b/4coder_custom.cpp @@ -228,7 +228,8 @@ extern "C" GET_BINDING_DATA(get_bindings){ bind(context, '?', MDFR_CTRL, cmdid_toggle_show_whitespace); bind(context, '~', MDFR_CTRL, cmdid_clean_all_lines); - // NOTE(allen): These whitespace manipulators are not currently functional + // NOTE(allen): These now only set the mode of the file for writing to disk + // they do no longer effect the internal representation. bind(context, '1', MDFR_CTRL, cmdid_eol_dosify); bind(context, '!', MDFR_CTRL, cmdid_eol_nixify); diff --git a/4coder_custom.h b/4coder_custom.h index b0da4862..833a6109 100644 --- a/4coder_custom.h +++ b/4coder_custom.h @@ -96,6 +96,9 @@ enum Command_ID{ cmdid_eol_dosify, cmdid_eol_nixify, cmdid_auto_tab, + cmdid_auto_tab_range, + cmdid_auto_tab_line_at_cursor, + cmdid_auto_tab_whole_file, cmdid_open_panel_vsplit, cmdid_open_panel_hsplit, cmdid_close_panel, diff --git a/4ed.cpp b/4ed.cpp index de9dd2dc..2fcc1cde 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -128,6 +128,7 @@ globalvar Application_Links app_links; #define REQ_DBG_VIEW(n) Debug_View *n = view_to_debug_view(command->view); if (!n) return #define COMMAND_DECL(n) internal void command_##n(Command_Data *command, Command_Binding binding) +#define COMPOSE_DECL(n) internal void n(Command_Data *command, Command_Binding binding) struct Command_Data{ Mem_Options *mem; @@ -249,40 +250,6 @@ COMMAND_DECL(seek_whitespace_down){ i32 pos = buffer_seek_whitespace_down(&file->buffer, view->cursor.pos); view_cursor_move(view, pos); - -#if BUFFER_EXPERIMENT_SCALPEL - ProfileMomentFunction(); - REQ_FILE_VIEW(view); - REQ_FILE(file, view); - - i32 size = file->buffer.size; - char* data = file->buffer.data; - i32 pos = view->cursor.pos; - while (pos < size && char_is_whitespace(data[pos])){ - ++pos; - } - - bool32 no_hard_character = 0; - i32 prev_endline = -1; - while (pos < size){ - if (starts_new_line(data[pos])){ - if (no_hard_character) break; - else{ - no_hard_character = 1; - prev_endline = pos; - } - } - else if (!char_is_whitespace(data[pos])){ - no_hard_character = 0; - } - ++pos; - } - - if (prev_endline == -1 || prev_endline+1 >= size) pos = size; - else pos = prev_endline+1; - - view_cursor_move(view, pos); -#endif } internal i32 @@ -387,7 +354,7 @@ COMMAND_DECL(seek_alphanumeric_left){ } COMMAND_DECL(seek_alphanumeric_or_camel_right){ -#if BUFFER_EXPERIMENT_SCALPEL +#if 0 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); @@ -413,7 +380,7 @@ COMMAND_DECL(seek_alphanumeric_or_camel_right){ } COMMAND_DECL(seek_alphanumeric_or_camel_left){ -#if BUFFER_EXPERIMENT_SCALPEL +#if 0 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); @@ -1020,7 +987,7 @@ case_change_range(Mem_Options *mem, File_View *view, Editing_File *file, if (file->still_lexing) system_cancel_job(BACKGROUND_THREADS, file->lex_job); - view_update_history_before_edit(mem, file, step, 0, hist_normal, view->cursor.pos); + view_update_history_before_edit(mem, file, step, 0, hist_normal); u8 *data = (u8*)file->buffer.data; for (i32 i = range.start; i < range.end; ++i){ @@ -1063,27 +1030,21 @@ COMMAND_DECL(clean_all_lines){ } COMMAND_DECL(eol_dosify){ -#if 0 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - USE_MEM(mem); - view_endline_convert(mem, view, ENDLINE_RN, ENDLINE_ERASE, ENDLINE_RN); - view_measure_wraps(&mem->general, view); -#endif + file->dos_write_mode = 1; + file->last_4ed_edit_time = system_get_now(); } COMMAND_DECL(eol_nixify){ -#if 0 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); - USE_MEM(mem); - view_endline_convert(mem, view, ENDLINE_N, ENDLINE_ERASE, ENDLINE_N); - view_measure_wraps(&mem->general, view); -#endif + file->dos_write_mode = 0; + file->last_4ed_edit_time = system_get_now(); } COMMAND_DECL(auto_tab){ @@ -1091,13 +1052,54 @@ COMMAND_DECL(auto_tab){ ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); + USE_LAYOUT(layout); USE_MEM(mem); - Range range = get_range(view->cursor.pos, view->mark); - view_auto_tab(mem, view, range.smaller, range.larger); - view_measure_wraps(&mem->general, view); + + if (file->token_stack.tokens && file->tokens_complete){ + Range range = get_range(view->cursor.pos, view->mark); + view_auto_tab_tokens(mem, view, layout, range.start, range.end); + } #endif } +COMMAND_DECL(auto_tab_range){ + ProfileMomentFunction(); + REQ_FILE_VIEW(view); + REQ_FILE(file, view); + USE_LAYOUT(layout); + USE_MEM(mem); + + if (file->token_stack.tokens && file->tokens_complete){ + Range range = get_range(view->cursor.pos, view->mark); + view_auto_tab_tokens(mem, view, layout, range.start, range.end, 1); + } +} + +COMMAND_DECL(auto_tab_line_at_cursor){ + ProfileMomentFunction(); + REQ_FILE_VIEW(view); + REQ_FILE(file, view); + USE_LAYOUT(layout); + USE_MEM(mem); + + if (file->token_stack.tokens && file->tokens_complete){ + i32 pos = view->cursor.pos; + view_auto_tab_tokens(mem, view, layout, pos, pos, 0); + } +} + +COMMAND_DECL(auto_tab_whole_file){ + ProfileMomentFunction(); + REQ_FILE_VIEW(view); + REQ_FILE(file, view); + USE_LAYOUT(layout); + USE_MEM(mem); + + if (file->token_stack.tokens && file->tokens_complete){ + view_auto_tab_tokens(mem, view, layout, 0, buffer_size(&file->buffer), 1); + } +} + COMMAND_DECL(open_panel_vsplit){ ProfileMomentFunction(); USE_LAYOUT(layout); @@ -1542,6 +1544,11 @@ COMMAND_DECL(set_settings){ } } +COMPOSE_DECL(compose_write_auto_tab_line){ + command_write_character(command, binding); + command_auto_tab_line_at_cursor(command, binding); +} + globalvar Command_Function command_table[cmdid_count]; extern "C"{ @@ -1704,13 +1711,19 @@ setup_file_commands(Command_Map *commands, Partition *part, Key_Codes *codes, Co map_add(commands, 'u', MDFR_CTRL, command_to_uppercase); map_add(commands, 'j', MDFR_CTRL, command_to_lowercase); map_add(commands, '~', MDFR_CTRL, command_clean_all_lines); - map_add(commands, '1', MDFR_CTRL, command_eol_dosify); - map_add(commands, '!', MDFR_CTRL, command_eol_nixify); map_add(commands, 'f', MDFR_CTRL, command_search); map_add(commands, 'r', MDFR_CTRL, command_rsearch); map_add(commands, 'g', MDFR_CTRL, command_goto_line); - map_add(commands, '\t', MDFR_CTRL, command_auto_tab); + map_add(commands, '\n', MDFR_NONE, compose_write_auto_tab_line); + map_add(commands, '}', MDFR_NONE, compose_write_auto_tab_line); + map_add(commands, ')', MDFR_NONE, compose_write_auto_tab_line); + map_add(commands, ']', MDFR_NONE, compose_write_auto_tab_line); + map_add(commands, ';', MDFR_NONE, compose_write_auto_tab_line); + + map_add(commands, '\t', MDFR_NONE, command_auto_tab_line_at_cursor); + map_add(commands, '\t', MDFR_CTRL, command_auto_tab_range); + map_add(commands, '\t', MDFR_CTRL | MDFR_SHIFT, command_write_character); map_add(commands, 'K', MDFR_CTRL, command_kill_buffer); map_add(commands, 'O', MDFR_CTRL, command_reopen); @@ -1807,6 +1820,9 @@ setup_command_table(){ SET(eol_dosify); SET(eol_nixify); SET(auto_tab); + SET(auto_tab_range); + SET(auto_tab_line_at_cursor); + SET(auto_tab_whole_file); SET(open_panel_vsplit); SET(open_panel_hsplit); SET(close_panel); diff --git a/4ed_command.cpp b/4ed_command.cpp index 8a1c050b..1084f9ed 100644 --- a/4ed_command.cpp +++ b/4ed_command.cpp @@ -115,9 +115,9 @@ map_extract(Command_Map *map, Key_Single key){ Command_Binding bind = {}; u8 command = MDFR_NONE; - bool32 ctrl = key.modifiers[CONTROL_KEY_CONTROL]; - bool32 alt = key.modifiers[CONTROL_KEY_ALT]; - bool32 shift = key.modifiers[CONTROL_KEY_SHIFT] && key.key.loose_keycode; + b32 ctrl = key.modifiers[CONTROL_KEY_CONTROL]; + b32 alt = key.modifiers[CONTROL_KEY_ALT]; + b32 shift = key.modifiers[CONTROL_KEY_SHIFT] && key.key.loose_keycode; if (shift) command |= MDFR_SHIFT; if (ctrl) command |= MDFR_CTRL; diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index ea641fd4..f7bba12f 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -10,9 +10,14 @@ // TOP #include "buffer/4coder_shared.cpp" -#include "buffer/4coder_gap_buffer.cpp" +#if BUFFER_EXPERIMENT_SCALPEL +#include "buffer/4coder_golden_array.cpp" +#define Buffer_Type Buffer +#else +#include "buffer/4coder_gap_buffer.cpp" #define Buffer_Type Gap_Buffer +#endif #include "buffer/4coder_buffer_abstract.cpp" struct Range{ @@ -74,7 +79,7 @@ struct Undo_Data{ }; struct Editing_File{ - Gap_Buffer buffer; + Buffer_Type buffer; Undo_Data undo; @@ -95,7 +100,9 @@ struct Editing_File{ b32 tokens_exist; b32 still_lexing; u32 lex_job; + i32 base_map_id; + i32 dos_write_mode; u64 last_4ed_write_time; u64 last_4ed_edit_time; @@ -1113,16 +1120,18 @@ file_save(Partition *part, Editing_File *file, u8 *filename){ bool32 result = 0; Temp_Memory temp = begin_temp_memory(part); i32 max = partition_remaining(part); - i32 size = 0; - char *data = push_array(part, char, max); - i32 data_size = buffer_size(&file->buffer); - for (Gap_Buffer_Stringify_Loop loop = buffer_stringify_loop(&file->buffer, 0, data_size, data_size); - buffer_stringify_good(&loop); - buffer_stringify_next(&loop)){ - memcpy(data + size, loop.data, loop.size); - size += loop.size; + if (file->dos_write_mode){ + char *data = push_array(part, char, max); + i32 size = buffer_convert_out(&file->buffer, data, max); + result = system_save_file(filename, data, size); + } + else{ + char *data = push_array(part, char, max); + i32 size = buffer_size(&file->buffer); + Assert(size <= max); + buffer_stringify(&file->buffer, 0, size, data); + result = system_save_file(filename, data, size); } - result = system_save_file(filename, data, size); end_temp_memory(temp); file_synchronize_times(file, filename); return result; @@ -1459,7 +1468,6 @@ file_close(General_Memory *general, Editing_File *file){ internal void file_get_dummy(Editing_File *file){ *file = {}; - file->buffer.data = (char*)&file->buffer.size1; file->is_dummy = 1; } @@ -2209,7 +2217,7 @@ enum History_Mode{ internal void view_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step step, u8 *str, - History_Mode history_mode, i32 next_cursor){ + History_Mode history_mode){ #if BUFFER_EXPERIMENT_SCALPEL General_Memory *general = &mem->general; @@ -2239,14 +2247,10 @@ view_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step if (step.edit.len == 1 && str && char_is_alpha_numeric(*str)) can_merge = 1; if (step.edit.len == 1 && str && (can_merge || char_is_whitespace(*str))) do_merge = 1; - Edit_Step *new_step = 0; - if (history_mode != hist_forward){ - new_step = file_post_history(general, file, step, do_merge, can_merge); - new_step->post_pos = next_cursor; - } + if (history_mode != hist_forward) + file_post_history(general, file, step, do_merge, can_merge); - new_step = file_post_undo(general, file, step, do_merge, can_merge); - new_step->post_pos = next_cursor; + file_post_undo(general, file, step, do_merge, can_merge); }break; case ED_REVERSE_NORMAL: @@ -2396,7 +2400,6 @@ debug_step_match(Edit_Step a, Edit_Step b){ return 1; } -#if 1 inline void file_pre_edit_maintenance(Editing_File *file){ if (file->still_lexing) @@ -2407,12 +2410,12 @@ file_pre_edit_maintenance(Editing_File *file){ internal void view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file, - Editing_Layout *layout, Edit_Spec spec, History_Mode history_mode, i32 next_cursor){ + Editing_Layout *layout, Edit_Spec spec, History_Mode history_mode){ Assert(file); ProfileMomentFunction(); // NOTE(allen): fixing stuff beforewards???? - view_update_history_before_edit(mem, file, spec.step, spec.str, history_mode, next_cursor); + view_update_history_before_edit(mem, file, spec.step, spec.str, history_mode); file_pre_edit_maintenance(file); // NOTE(allen): actual text replacement @@ -2425,7 +2428,7 @@ view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file, i32 shift_amount = 0; #if BUFFER_EXPERIMENT_SCALPEL - while (gap_buffer_replace_range(&file->buffer, start, end, str, str_len, &shift_amount)) + while (buffer_replace_range(&file->buffer, start, end, str, str_len, &shift_amount)) file_grow_as_needed(general, file, shift_amount); // NOTE(allen): fixing stuff afterwards @@ -2433,8 +2436,8 @@ view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file, file_relex_parallel(mem, file, start, end, shift_amount); #endif - i32 line_start = buffer_get_line_index(&file->buffer, start, 0, file->buffer.line_count); - i32 line_end = buffer_get_line_index(&file->buffer, end, 0, file->buffer.line_count); + i32 line_start = buffer_get_line_index(&file->buffer, start); + i32 line_end = buffer_get_line_index(&file->buffer, end); i32 replaced_line_count = line_end - line_start; i32 new_line_count = file_count_newlines(file, start, start+str_len); i32 line_shift = new_line_count - replaced_line_count; @@ -2451,14 +2454,13 @@ view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file, } } -#if BUFFER_EXPERIMENT_SCALPEL - i32 cursor_count = 0; +#if BUFFER_EXPERIMENT_SCALPEL Temp_Memory cursor_temp = begin_temp_memory(&mem->part); i32 cursor_max = layout->panel_max_count * 2; Cursor_With_Index *cursors = push_array(&mem->part, Cursor_With_Index, cursor_max); i32 cursor_count = 0; - Panel *current_panel = layout->panels; + current_panel = layout->panels; for (i32 i = 0; i < panel_count; ++i, ++current_panel){ File_View *current_view = view_to_file_view(current_panel->view); if (current_view && current_view->file == file){ @@ -2503,7 +2505,7 @@ view_do_white_batch_edit(Mem_Options *mem, File_View *view, Editing_File *file, // NOTE(allen): fixing stuff beforewards???? Assert(spec.str == 0); - view_update_history_before_edit(mem, file, spec.step, 0, history_mode, 0); + view_update_history_before_edit(mem, file, spec.step, 0, history_mode); file_pre_edit_maintenance(file); // NOTE(allen): actual text replacement @@ -2600,8 +2602,10 @@ view_replace_range(Mem_Options *mem, File_View *view, Editing_Layout *layout, spec.step.edit.start = start; spec.step.edit.end = end; spec.step.edit.len = len; + spec.step.pre_pos = view->cursor.pos; + spec.step.post_pos = next_cursor; spec.str = str; - view_do_single_edit(mem, view, view->file, layout, spec, hist_normal, next_cursor); + view_do_single_edit(mem, view, view->file, layout, spec, hist_normal); } internal void @@ -2628,9 +2632,10 @@ view_undo_redo(Mem_Options *mem, Editing_Layout *layout, File_View *view, Editin spec.step.edit.str_start = 0; spec.str = stack->strings + step.edit.str_start; - view_do_single_edit(mem, view, file, layout, spec, hist_normal, 0); - - view_cursor_move(view, step.pre_pos); + view_do_single_edit(mem, view, file, layout, spec, hist_normal); + + if (expected_type == ED_UNDO) view_cursor_move(view, step.pre_pos); + else view_cursor_move(view, step.post_pos); view->mark = view->cursor.pos; view_post_paste_effect(view, 10, step.edit.start, step.edit.len, @@ -2686,7 +2691,7 @@ view_history_step(Mem_Options *mem, Editing_Layout *layout, File_View *view, His spec.step.edit.str_start = 0; spec.str = file->undo.history.strings + step.edit.str_start; - view_do_single_edit(mem, view, file, layout, spec, history_mode, step.post_pos); + view_do_single_edit(mem, view, file, layout, spec, history_mode); switch (spec.step.type){ case ED_NORMAL: @@ -2708,8 +2713,6 @@ view_history_step(Mem_Options *mem, Editing_Layout *layout, File_View *view, His } } -#endif - // TODO(allen): should these still be view operations? internal i32 view_find_end_of_line(File_View *view, i32 pos){ @@ -2848,12 +2851,36 @@ clipboard_copy(General_Memory *general, Working_Set *working, u8 *data, Range ra system_post_clipboard(*dest); } -enum Endline_Convert_Type{ - ENDLINE_RN, - ENDLINE_N, - ENDLINE_R, - ENDLINE_ERASE, -}; +internal Edit_Spec +view_compute_whitespace_edit(Mem_Options *mem, Editing_File *file, + Buffer_Edit *edits, char *str_base, i32 str_size, + Buffer_Edit *inverse_array, char *inv_str, i32 inv_max, + i32 edit_count){ + General_Memory *general = &mem->general; + + i32 inv_str_pos = 0; + Buffer_Invert_Batch state = {}; + if (buffer_invert_batch(&state, &file->buffer, edits, edit_count, + inverse_array, inv_str, &inv_str_pos, inv_max)) + Assert(0); + + i32 first_child = + undo_children_push(general, &file->undo.children, + edits, edit_count, (u8*)(str_base), str_size); + i32 inverse_first_child = + undo_children_push(general, &file->undo.children, + inverse_array, edit_count, (u8*)(inv_str), inv_str_pos); + + Edit_Spec spec = {}; + spec.step.type = ED_NORMAL; + spec.step.first_child = first_child; + spec.step.inverse_first_child = inverse_first_child; + spec.step.special_type = 1; + spec.step.child_count = edit_count; + spec.step.inverse_child_count = edit_count; + + return spec; +} internal void view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout){ @@ -2876,7 +2903,8 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout) bool32 all_whitespace = 0; bool32 all_space = 0; i32 hard_start = - buffer_find_hard_start(&file->buffer, start, &all_whitespace, &all_space, &preferred_indentation, 4); + buffer_find_hard_start(&file->buffer, start, &all_whitespace, &all_space, + &preferred_indentation, 4); if (all_whitespace) preferred_indentation = 0; @@ -2902,28 +2930,135 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout) Assert(inverse_array); char *inv_str = (char*)part->base + part->pos; - i32 inv_str_pos = 0; - Buffer_Invert_Batch state = {}; - if (buffer_invert_batch(&state, &file->buffer, edits, edit_count, - inverse_array, inv_str, &inv_str_pos, part->max - part->pos)) - Assert(0); + Edit_Spec spec = + view_compute_whitespace_edit(mem, file, edits, str_base, str_size, + inverse_array, inv_str, part->max - part->pos, edit_count); - General_Memory *general = &mem->general; - i32 first_child = - undo_children_push(general, &file->undo.children, - edits, edit_count, (u8*)(str_base), str_size); - i32 inverse_first_child = - undo_children_push(general, &file->undo.children, - inverse_array, edit_count, (u8*)(inv_str), inv_str_pos); + view_do_white_batch_edit(mem, view, file, layout, spec, hist_normal); + } - Edit_Spec spec = {}; - spec.step.type = ED_NORMAL; - spec.step.first_child = first_child; - spec.step.inverse_first_child = inverse_first_child; - spec.step.special_type = 1; - spec.step.child_count = edit_count; - spec.step.inverse_child_count = edit_count; + end_temp_memory(temp); +#endif +} + +internal void +view_auto_tab_tokens(Mem_Options *mem, File_View *view, Editing_Layout *layout, + i32 start, i32 end, b32 empty_blank_lines){ +#if BUFFER_EXPERIMENT_SCALPEL + Editing_File *file = view->file; + Assert(file && !file->is_dummy); + Partition *part = &mem->part; + Buffer *buffer = &file->buffer; + Cpp_Token_Stack tokens = file->token_stack; + Assert(tokens.tokens); + i32 line_start = buffer_get_line_index(buffer, start); + i32 line_end = buffer_get_line_index(buffer, end) + 1; + + i32 edit_max = (line_end - line_start) * 2; + i32 edit_count = 0; + + i32 indent_mark_count = line_end - line_start; + + Temp_Memory temp = begin_temp_memory(part); + i32 *indent_marks = push_array(part, i32, indent_mark_count); + { + i32 current_indent = 0; + i32 line; + for (line = line_start - 1; line >= 0; --line){ + i32 start = file->buffer.line_starts[line]; + b32 all_whitespace = 0; + b32 all_space = 0; + buffer_find_hard_start(&file->buffer, start, &all_whitespace, &all_space, ¤t_indent, 4); + if (!all_whitespace) break; + } + + if (line < 0) line = 0; + i32 start_pos = file->buffer.line_starts[line]; + Cpp_Get_Token_Result result = cpp_get_token(&tokens, start_pos); + i32 start_token; + if (result.in_whitespace) start_token = result.token_index + 1; + else start_token = result.token_index; + + indent_marks -= line_start; + i32 line_i = line_start; + i32 next_line_start = file->buffer.line_starts[line_i]; + Cpp_Token *token = tokens.tokens + start_token; + switch (token->type){ + case CPP_TOKEN_BRACKET_OPEN: current_indent += 4; break; + case CPP_TOKEN_PARENTHESE_OPEN: current_indent += 4; break; + case CPP_TOKEN_BRACE_OPEN: current_indent += 4; break; + } + ++token; + for (i32 token_i = start_token + 1; line_i < line_end; ++token_i, ++token){ + for (; token->start >= next_line_start && line_i < line_end;){ + next_line_start = file->buffer.line_starts[line_i+1]; + i32 this_indent = current_indent; + if (token->start < next_line_start){ + switch (token->type){ + case CPP_TOKEN_BRACKET_CLOSE: this_indent -= 4; break; + case CPP_TOKEN_PARENTHESE_CLOSE: this_indent -= 4; break; + case CPP_TOKEN_BRACE_CLOSE: this_indent -= 4; break; + } + } + if (this_indent < 0) this_indent = 0; + indent_marks[line_i] = this_indent; + ++line_i; + } + switch (token->type){ + case CPP_TOKEN_BRACKET_OPEN: current_indent += 4; break; + case CPP_TOKEN_BRACKET_CLOSE: current_indent -= 4; break; + case CPP_TOKEN_PARENTHESE_OPEN: current_indent += 4; break; + case CPP_TOKEN_PARENTHESE_CLOSE: current_indent -= 4; break; + case CPP_TOKEN_BRACE_OPEN: current_indent += 4; break; + case CPP_TOKEN_BRACE_CLOSE: current_indent -= 4; break; + } + } + } + + Buffer_Edit *edits = push_array(part, Buffer_Edit, edit_max); + + char *str_base = (char*)part->base + part->pos; + i32 str_size = 0; + for (i32 line_i = line_start; line_i < line_end; ++line_i){ + i32 start = file->buffer.line_starts[line_i]; + i32 preferred_indentation; + i32 correct_indentation; + bool32 all_whitespace = 0; + bool32 all_space = 0; + i32 hard_start = + buffer_find_hard_start(&file->buffer, start, &all_whitespace, &all_space, + &preferred_indentation, 4); + + correct_indentation = indent_marks[line_i]; + if (all_whitespace && empty_blank_lines) correct_indentation = 0; + + if ((all_whitespace && hard_start > start) || !all_space || correct_indentation != preferred_indentation){ + Buffer_Edit new_edit; + new_edit.str_start = str_size; + str_size += correct_indentation; + char *str = push_array(part, char, correct_indentation); + for (i32 j = 0; j < correct_indentation; ++j) str[j] = ' '; + new_edit.len = correct_indentation; + new_edit.start = start; + new_edit.end = hard_start; + edits[edit_count++] = new_edit; + } + Assert(edit_count <= edit_max); + } + + if (edit_count > 0){ + Assert(buffer_batch_debug_sort_check(edits, edit_count)); + + // NOTE(allen): computing edit spec, doing batch edit + Buffer_Edit *inverse_array = push_array(part, Buffer_Edit, edit_count); + Assert(inverse_array); + + char *inv_str = (char*)part->base + part->pos; + Edit_Spec spec = + view_compute_whitespace_edit(mem, file, edits, str_base, str_size, + inverse_array, inv_str, part->max - part->pos, edit_count); + view_do_white_batch_edit(mem, view, file, layout, spec, hist_normal); } @@ -3518,6 +3653,7 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act u32 mark_color = style->main.mark_color; Buffer_Render_Item *item = items; i32 prev_ind = -1; + u32 highlight_color = 0; for (i32 i = 0; i < count; ++i, ++item){ i32 ind = item->index; if (tokens_use && ind != prev_ind){ diff --git a/4ed_file_view_golden_array.cpp b/4ed_file_view_golden_array.cpp index 2f96aa8c..bb3496f4 100644 --- a/4ed_file_view_golden_array.cpp +++ b/4ed_file_view_golden_array.cpp @@ -1112,19 +1112,10 @@ internal bool32 file_save(Partition *part, Editing_File *file, u8 *filename){ bool32 result = 0; Temp_Memory temp = begin_temp_memory(part); - Buffer temp_buffer; - temp_buffer.max = partition_remaining(part); - temp_buffer.size = 0; - temp_buffer.data = push_array(part, char, temp_buffer.max); - // TODO(allen): What about using this stringify loop to convert out? - for (Buffer_Stringify_Loop loop = buffer_stringify_loop(&file->buffer, 0, file->buffer.size, file->buffer.size); - buffer_stringify_good(&loop); - buffer_stringify_next(&loop)){ - memcpy(temp_buffer.data, loop.data, loop.size); - temp_buffer.size += loop.size; - buffer_eol_convert_out(&temp_buffer); - result = system_save_file(filename, temp_buffer.data, temp_buffer.size); - } + i32 max = partition_remaining(part); + char *data = push_array(part, char, max); + i32 size = buffer_convert_out(&file->buffer, data, max); + result = system_save_file(filename, data, size); end_temp_memory(temp); file_synchronize_times(file, filename); return result; @@ -1352,8 +1343,7 @@ file_create_from_string(General_Memory *general, Editing_File *file, u8 *filenam file->buffer.max = request_size; if (val.size > 0){ - memcpy(data, val.str, val.size); - buffer_eol_convert_in(&file->buffer); + buffer_initialize(&file->buffer, val.str, val.size); } data[val.size] = 0; diff --git a/4ed_keyboard.cpp b/4ed_keyboard.cpp index 90921d97..49cb48d3 100644 --- a/4ed_keyboard.cpp +++ b/4ed_keyboard.cpp @@ -47,7 +47,7 @@ keycode_init(Key_Codes *codes, Key_Codes *loose_codes){ u16 code, loose = 0; switch (i){ - case VK_SPACE: code = ' '; break; + case VK_SPACE: code = loose = ' '; break; case VK_BACK: code = loose = codes->back; break; case VK_OEM_MINUS: code = '-'; break; case VK_OEM_PLUS: code = '='; break; @@ -60,8 +60,8 @@ keycode_init(Key_Codes *codes, Key_Codes *loose_codes){ case VK_OEM_5: code = '\\'; break; case VK_OEM_4: code = '['; break; case VK_OEM_6: code = ']'; break; - case VK_TAB: code = '\t'; break; - case VK_RETURN: code = '\n'; break; + case VK_TAB: code = loose = '\t'; break; + case VK_RETURN: code = loose = '\n'; break; case VK_OEM_7: code = '\''; break; case VK_OEM_1: code = ';'; break; diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp index dba70194..df4219f5 100644 --- a/buffer/4coder_buffer_abstract.cpp +++ b/buffer/4coder_buffer_abstract.cpp @@ -16,6 +16,36 @@ #define Buffer_Stringify_Type cat_4tech(Buffer_Type, _Stringify_Loop) #define Buffer_Backify_Type cat_4tech(Buffer_Type, _Backify_Loop) +inline_4tech void +buffer_stringify(Buffer_Type *buffer, int start, int end, char *out){ + for (Buffer_Stringify_Loop loop = buffer_stringify_loop(buffer, start, end, end - start); + buffer_stringify_good(&loop); + buffer_stringify_next(&loop)){ + memcpy_4tech(out, loop.data, loop.size); + out += loop.size; + } +} + +internal_4tech int +buffer_convert_out(Buffer_Type *buffer, char *dest, int max){ + Buffer_Stringify_Type loop; + int size, out_size, pos, result; + + size = buffer_size(buffer); + assert_4tech(size + buffer->line_count < max); + + pos = 0; + for (loop = buffer_stringify_loop(buffer, 0, size, size); + buffer_stringify_good(&loop); + buffer_stringify_next(&loop)){ + result = eol_convert_out(dest + pos, max - pos, loop.data, loop.size, &out_size); + assert_4tech(result); + pos += out_size; + } + + return(pos); +} + internal_4tech int buffer_count_newlines(Buffer_Type *buffer, int start, int end){ Buffer_Stringify_Type loop; @@ -166,24 +196,32 @@ buffer_seek_whitespace_left(Buffer_Type *buffer, int pos){ char *data; int end; int size; + + --pos; + if (pos > 0){ + size = buffer_size(buffer); + loop = buffer_backify_loop(buffer, pos, 0, size); - size = buffer_size(buffer); - loop = buffer_backify_loop(buffer, pos, 0, size); + for (;buffer_backify_good(&loop); + buffer_backify_next(&loop)){ + end = loop.absolute_pos; + data = loop.data - loop.absolute_pos; + for (; pos >= end && is_whitespace(data[pos]); --pos); + if (!is_whitespace(data[pos])) break; + } - for (;buffer_backify_good(&loop); - buffer_backify_next(&loop)){ - end = loop.absolute_pos; - data = loop.data - loop.absolute_pos; - for (; pos >= end && is_whitespace(data[pos]); --pos); - if (!is_whitespace(data[pos])) break; + for (;buffer_backify_good(&loop); + buffer_backify_next(&loop)){ + end = loop.absolute_pos; + data = loop.data - loop.absolute_pos; + for (; pos >= end && !is_whitespace(data[pos]); --pos); + if (is_whitespace(data[pos])) break; + } + + if (pos != 0) ++pos; } - - for (;buffer_backify_good(&loop); - buffer_backify_next(&loop)){ - end = loop.absolute_pos; - data = loop.data - loop.absolute_pos; - for (; pos >= end && is_whitespace(data[pos]); --pos); - if (!is_whitespace(data[pos])) break; + else{ + pos = 0; } return(pos); @@ -456,7 +494,7 @@ buffer_measure_wrap_y(Buffer_Type *buffer, float *wraps, } internal_4tech int -buffer_get_line_index(Buffer_Type *buffer, int pos, int l_bound, int u_bound){ +buffer_get_line_index_range(Buffer_Type *buffer, int pos, int l_bound, int u_bound){ int *lines; int start, end; int i; @@ -484,6 +522,13 @@ buffer_get_line_index(Buffer_Type *buffer, int pos, int l_bound, int u_bound){ return(start); } +inline_4tech int +buffer_get_line_index(Buffer_Type *buffer, int pos){ + int result; + result = buffer_get_line_index_range(buffer, pos, 0, buffer->line_count); + return(result); +} + #ifndef NON_ABSTRACT_4TECH internal_4tech int buffer_get_line_index_from_wrapped_y(float *wraps, float y, float font_height, int l_bound, int u_bound){ @@ -666,7 +711,7 @@ buffer_cursor_from_pos(Buffer_Type *buffer, int pos, float *wraps, Full_Cursor result; int line_index; - line_index = buffer_get_line_index(buffer, pos, 0, buffer->line_count); + line_index = buffer_get_line_index_range(buffer, pos, 0, buffer->line_count); result = make_cursor_hint(line_index, buffer->line_starts, wraps, font_height); result = buffer_cursor_seek(buffer, seek_pos(pos), max_width, font_height, advance_data, stride, result); diff --git a/buffer/4coder_golden_array.cpp b/buffer/4coder_golden_array.cpp index aeb71516..5677c80d 100644 --- a/buffer/4coder_golden_array.cpp +++ b/buffer/4coder_golden_array.cpp @@ -124,16 +124,6 @@ buffer_backify_next(Buffer_Backify_Loop *loop){ } } -inline_4tech void -buffer_stringify(Buffer *buffer, int start, int end, char *out){ - for (Buffer_Stringify_Loop loop = buffer_stringify_loop(buffer, start, end, end - start); - buffer_stringify_good(&loop); - buffer_stringify_next(&loop)){ - memcpy_4tech(out, loop.data, loop.size); - out += loop.size; - } -} - internal_4tech int buffer_replace_range(Buffer *buffer, int start, int end, char *str, int len, int *shift_amount){ char *data; @@ -289,13 +279,5 @@ buffer_find_hard_start(Buffer *buffer, int line_start, int *all_whitespace, int return(result); } -internal_4tech void -buffer_eol_convert_out(Buffer *buffer){ - int size; - assert_4tech(buffer_eol_convert_out_size(buffer) < buffer->max); - eol_convert_out(buffer->data, buffer->size, buffer->max, &size); - buffer->size = size; -} - // BOTTOM diff --git a/win32_4ed.cpp b/win32_4ed.cpp index 4417e0ab..d5d6b584 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -54,7 +54,7 @@ #define FPS 30 #define FRAME_TIME (1000000 / FPS) -#define BUFFER_EXPERIMENT_SCALPEL 0 +#define BUFFER_EXPERIMENT_SCALPEL 1 #include "4ed_meta.h" @@ -93,11 +93,7 @@ struct Sys_Bubble : public Bubble{ #include "4ed_command.cpp" #include "4ed_layout.cpp" #include "4ed_style.cpp" -#if BUFFER_EXPERIMENT_SCALPEL -#include "4ed_file_view_golden_array.cpp" -#else #include "4ed_file_view.cpp" -#endif #include "4ed_color_view.cpp" #include "4ed_interactive_view.cpp" #include "4ed_menu_view.cpp"