diff --git a/4ed.cpp b/4ed.cpp index 14f347a2..59e15061 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -1074,7 +1074,7 @@ COMMAND_DECL(to_uppercase){ spec.end = range.end; spec.str_len = range.end - range.start; spec.next_cursor_pos = view->cursor.pos; - view_pre_replace_range(mem, file, spec); + view_update_history_before_edit(mem, file, spec); if (file->still_lexing){ system_cancel_job(BACKGROUND_THREADS, file->lex_job); @@ -1107,7 +1107,7 @@ COMMAND_DECL(to_lowercase){ spec.end = range.end; spec.str_len = range.end - range.start; spec.next_cursor_pos = view->cursor.pos; - view_pre_replace_range(mem, file, spec); + view_update_history_before_edit(mem, file, spec); if (file->still_lexing){ system_cancel_job(BACKGROUND_THREADS, file->lex_job); diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 5040f19e..991280f0 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -51,7 +51,20 @@ struct Edit_Step{ i32 next_block, prev_block; }; +struct Edit_Stack{ + u8 *strings; + i32 size, max; + + Edit_Step *edits; + i32 edit_count, edit_max; +}; + struct Undo_Data{ + Edit_Stack undo; + Edit_Stack redo; + Edit_Stack history; + +#if 0 u8 *strings; i32 str_size, str_redo, str_max; @@ -63,6 +76,8 @@ struct Undo_Data{ i32 history_block_count, history_head_block; Edit_Step *history; +#endif + i32 edit_history, edit_history_max; i32 edit_history_cursor; i32 current_block_normal; @@ -76,7 +91,7 @@ struct Editing_File{ Font *font; i32 cursor_pos; - bool32 is_dummy; + b32 is_dummy; char source_path_[256]; char live_name_[256]; @@ -86,9 +101,9 @@ struct Editing_File{ String extension; Cpp_Token_Stack token_stack; - bool32 tokens_complete; - bool32 tokens_exist; - bool32 still_lexing; + b32 tokens_complete; + b32 tokens_exist; + b32 still_lexing; u32 lex_job; i32 base_map_id; @@ -1218,6 +1233,18 @@ file_measure_starts(General_Memory *general, Editing_File *file){ file->buffer.line_count = state.count; } +internal void +file_remeasure_starts(General_Memory *general, Editing_File *file, + i32 line_start, i32 line_end, i32 line_shift, + i32 character_shift){ + ProfileMomentFunction(); + + Assert(file->buffer.line_starts); + file_grow_starts_as_needed(general, file, line_shift); + + buffer_remeasure_starts(&file->buffer, line_start, line_end, line_shift, character_shift); +} + struct Opaque_Font_Advance{ void *data; int offset; @@ -1234,9 +1261,7 @@ get_opaque_font_advance(Font *font){ } internal void -file_measure_widths(General_Memory *general, Editing_File *file, Font *font){ - ProfileMomentFunction(); - +file_grow_widths_as_needed(General_Memory *general, Editing_File *file){ i32 line_count = file->buffer.line_count; if (line_count > file->buffer.widths_max){ i32 new_max = LargeRoundUp(line_count, Kbytes(1)); @@ -1250,21 +1275,26 @@ file_measure_widths(General_Memory *general, Editing_File *file, Font *font){ } file->buffer.widths_max = new_max; } +} + +internal void +file_measure_widths(General_Memory *general, Editing_File *file, Font *font){ + ProfileMomentFunction(); + file_grow_widths_as_needed(general, file); Opaque_Font_Advance opad = get_opaque_font_advance(font); buffer_measure_widths(&file->buffer, opad.data, opad.offset, opad.stride); } internal void -file_remeasure_starts(General_Memory *general, Editing_File *file, - i32 line_start, i32 line_end, i32 line_shift, - i32 character_shift){ +file_remeasure_widths(General_Memory *general, Editing_File *file, Font *font, + i32 line_start, i32 line_end, i32 line_shift){ ProfileMomentFunction(); - Assert(file->buffer.line_starts); - file_grow_starts_as_needed(general, file, line_shift); - - buffer_remeasure_starts(&file->buffer, line_start, line_end, line_shift, character_shift); + file_grow_widths_as_needed(general, file); + Opaque_Font_Advance opad = get_opaque_font_advance(font); + buffer_remeasure_widths(&file->buffer, opad.data, opad.offset, opad.stride, + line_start, line_end, line_shift); } inline i32 @@ -1536,7 +1566,7 @@ file_kill_tokens(General_Memory *general, Editing_File *file){ internal void file_first_lex_parallel(General_Memory *general, Editing_File *file){ -#if 0 +#if 1 Assert(file->token_stack.tokens == 0); file->tokens_complete = 0; @@ -1549,8 +1579,9 @@ file_first_lex_parallel(General_Memory *general, Editing_File *file){ job.data[1] = general; job.memory_request = Kbytes(64); file->lex_job = system_post_job(BACKGROUND_THREADS, job); -#endif +#else file_kill_tokens(general, file); +#endif } internal void @@ -1909,9 +1940,7 @@ file_replace_range(Mem_Options *mem, Editing_File *file, i32 line_shift = new_line_count - replaced_line_count; file_remeasure_starts(general, file, line_start, line_end, line_shift, shift_amount); - - // TODO(allen): Can we "remeasure" widths now!? - file_measure_widths(general, file, file->font); + file_remeasure_widths(general, file, file->font, line_start, line_end, line_shift); Shift_Information shift; shift.start = start; @@ -2416,7 +2445,7 @@ struct Edit_Spec{ }; internal void -view_pre_replace_range(Mem_Options *mem, Editing_File *file, Edit_Spec spec){ +view_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Spec spec){ General_Memory *general = &mem->general; bool32 can_merge = 0, do_merge = 0; @@ -2570,8 +2599,15 @@ view_pre_replace_range(Mem_Options *mem, Editing_File *file, Edit_Spec spec){ } internal void -view_post_replace_range(Mem_Options *mem, File_View *view, Editing_File *file, - Editing_Layout *layout, Shift_Information shift){ +view_replace_range(Mem_Options *mem, File_View *view, Editing_File *file, + Editing_Layout *layout, Edit_Spec spec){ + Assert(file); + + view_update_history_before_edit(mem, file, spec); + + Shift_Information shift = + file_replace_range(mem, file, spec.start, spec.end, (char*)spec.str, spec.str_len); + General_Memory *general = &mem->general; i32 panel_count = layout->panel_count; @@ -2616,16 +2652,6 @@ view_post_replace_range(Mem_Options *mem, File_View *view, Editing_File *file, end_temp_memory(temp); } -internal void -view_replace_range(Mem_Options *mem, File_View *view, Editing_File *file, - Editing_Layout *layout, Edit_Spec spec){ - Assert(file); - view_pre_replace_range(mem, file, spec); - Shift_Information shift = - file_replace_range(mem, file, spec.start, spec.end, (char*)spec.str, spec.str_len); - view_post_replace_range(mem, view, file, layout, shift); -} - inline void view_replace_range(Mem_Options *mem, File_View *view, Editing_Layout *layout, i32 start, i32 end, u8 *str, i32 len, i32 next_cursor_pos){ @@ -2827,7 +2853,7 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout) i32 line_count = file->buffer.line_count; i32 edit_max = line_count * 2; Buffer_Edit *edits = push_array(part, Buffer_Edit, edit_max); - i32 edit_i = 0; + i32 edit_count = 0; for (i32 line_i = 0; line_i < line_count; ++line_i){ i32 start = file->buffer.line_starts[line_i]; @@ -2846,19 +2872,20 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout) new_edit.len = preferred_indentation; new_edit.start = start; new_edit.end = hard_start; - edits[edit_i++] = new_edit; + edits[edit_count++] = new_edit; } - Assert(edit_i <= edit_max); + Assert(edit_count <= edit_max); } - Assert(buffer_batch_debug_sort_check(edits, edit_i)); + Assert(buffer_batch_debug_sort_check(edits, edit_count)); General_Memory *general = &mem->general; - i32 shift_amount = buffer_batch_edit_max_shift(edits, edit_i); + i32 shift_amount = buffer_batch_edit_max_shift(edits, edit_count); file_grow_as_needed(general, file, shift_amount); - buffer_batch_edit(&file->buffer, edits, edit_i); + buffer_batch_edit(&file->buffer, edits, edit_count); + // NOTE(allen): meta data Buffer_Measure_Starts state = {}; if (buffer_measure_starts(&state, &file->buffer)) Assert(0); @@ -2868,6 +2895,7 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout) i32 cursor_max = layout->panel_max_count * 2; Cursor_With_Index *cursors = push_array(part, Cursor_With_Index, cursor_max); + // NOTE(allen): cursor fixing i32 panel_count = layout->panel_count; i32 cursor_count = 0; Panel *current_panel = layout->panels; @@ -2882,7 +2910,7 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout) if (cursor_count > 0){ buffer_sort_cursors(cursors, cursor_count); - buffer_batch_edit_update_cursors(cursors, cursor_count, edits, edit_i); + buffer_batch_edit_update_cursors(cursors, cursor_count, edits, edit_count); buffer_unsort_cursors(cursors, cursor_count); } @@ -2897,412 +2925,31 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout) } } + // NOTE(allen): token fixing + if (file->tokens_complete){ + Cpp_Token_Stack tokens = file->token_stack; + Cpp_Token *token = tokens.tokens; + Cpp_Token *end_token = tokens.tokens + tokens.count; + + Buffer_Edit *edit = edits; + Buffer_Edit *end_edit = edits + edit_count; + + i32 shift_amount = 0; + + for (; token < end_token && edit < end_edit; ++edit){ + for (; token->start < edit->start && token < end_token; ++token){ + token->start += shift_amount; + } + shift_amount += (edit->len - (edit->end - edit->start)); + } + for (; token < end_token; ++token){ + token->start += shift_amount; + } + } + end_temp_memory(temp); } -#if 0 -// NOTE(allen): Assumes that whitespace_buffer has at least -// indent.tabs*4 + indent.spaces bytes available. -internal Shift_Information -buffer_set_indent_whitespace(Mem_Options *mem, Editing_File *file, - Indent_Definition indent, - u8 *whitespace_buffer, - i32 line_start){ - i32 i = 0; - while (i < indent.tabs){ - for (i32 j = 0; j < 4; ++j) whitespace_buffer[i++] = ' '; - } - while (i < indent.tabs + indent.spaces){ - whitespace_buffer[i++] = ' '; - } - - Range leading_white; - leading_white.smaller = line_start; - Line_Hard_Start hard_start; - hard_start = buffer_find_hard_start(file, line_start); - leading_white.larger = hard_start.first_character; - Shift_Information shift = {}; - - if (leading_white.smaller < leading_white.larger){ - shift = buffer_replace_range(mem, file, - leading_white.smaller, leading_white.larger, - whitespace_buffer, i); - } - - return shift; -} - -inline Indent_Definition -indent_by_width(i32 width, i32 tab_width){ - Indent_Definition indent; - indent.tabs = 0; - indent.spaces = width; - return indent; -} - -struct Nest_Level{ - i32 brace_level, paren_level, bracket_level; -}; - -struct Nest_Level_Hint{ - Nest_Level start_level; - i32 start_pos; -}; - -internal Nest_Level -buffer_compute_nest_level_raw(Editing_File *file, i32 pos, Nest_Level_Hint hint = {}){ - Nest_Level result = hint.start_level; - for (i32 i = hint.start_pos; i < pos; ++i){ - if (file->data[i] == '/' && - i+1 < file->size && file->data[i+1] == '*'){ - Seek_Result seek = seek_block_comment_end((char*)file->data, file->size, pos); - pos = seek.pos; - } - else if (file->data[i] == '/' && - i+1 < file->size && file->data[i+1] == '/'){ - Seek_Result seek = seek_unescaped_eol((char*)file->data, file->size, pos); - pos = seek.pos; - } - else if (file->data[i] == '"'){ - Seek_Result seek = seek_unescaped_delim((char*)file->data, file->size, pos, '"'); - pos = seek.pos; - } - else if (file->data[i] == '\''){ - Seek_Result seek = seek_unescaped_delim((char*)file->data, file->size, pos, '\''); - pos = seek.pos; - } - switch (file->data[i]){ - case '{': - ++result.brace_level; - break; - case '}': - if (result.brace_level > 0){ - --result.brace_level; - } - break; - case '(': - ++result.paren_level; - break; - case ')': - if (result.paren_level > 0){ - --result.paren_level; - } - break; - case '[': - ++result.bracket_level; - break; - case ']': - if (result.bracket_level > 0){ - --result.bracket_level; - } - break; - } - } - return result; -} - -internal Nest_Level -buffer_compute_nest_level_tokens(Editing_File *file, i32 pos, Nest_Level_Hint hint = {}){ - Nest_Level result = hint.start_level; - Cpp_Token_Stack token_stack = file->token_stack; - i32 start_token; - { - Cpp_Get_Token_Result get_result = cpp_get_token(&file->token_stack, hint.start_pos); - start_token = get_result.token_index; - if (get_result.in_whitespace){ - ++start_token; - } - } - for (i32 i = start_token; i < token_stack.count && token_stack.tokens[i].start < pos; ++i){ - if (token_stack.tokens[i].flags & CPP_TFLAG_PP_BODY){ - continue; - } - switch (token_stack.tokens[i].type){ - case CPP_TOKEN_BRACE_OPEN: - ++result.brace_level; - break; - case CPP_TOKEN_BRACE_CLOSE: - if (result.brace_level > 0){ - --result.brace_level; - } - break; - case CPP_TOKEN_PARENTHESE_OPEN: - ++result.paren_level; - break; - case CPP_TOKEN_PARENTHESE_CLOSE: - if (result.paren_level > 0){ - --result.paren_level; - } - break; - case CPP_TOKEN_BRACKET_OPEN: - ++result.bracket_level; - break; - case CPP_TOKEN_BRACKET_CLOSE: - if (result.bracket_level > 0){ - --result.bracket_level; - } - break; - } - } - return result; -} -#endif - -#if 0 -internal void -view_auto_tab(Mem_Options *mem, File_View *view, i32 start, i32 end){ - Editing_File *file = view->file; - u8 *data = (u8*)file->data; - - start = view_find_beginning_of_line(view, start); - end = view_find_end_of_line(view, end); - - i32 cursor = view->cursor.pos; - i32 mark = view->mark; - - Nest_Level_Hint hint = {}; - while (start < end){ - Line_Hard_Start hard_start; - hard_start = buffer_find_hard_start(file, start); - - i32 x_pos = 0; - - i32 read_until = hard_start.first_character; - u8 first_character = file->data[read_until]; - if (first_character == '}' || - first_character == ')' || - first_character == ']'){ - ++read_until; - } - - Nest_Level nesting; - bool32 is_label = 0; - bool32 is_continuation = 0; - bool32 is_preprocessor = 0; - bool32 is_string_continuation = 0; - AllowLocal(is_string_continuation); - // TODO(allen): Better system for finding out what extra data types a file has? - if (file->tokens_complete){ - nesting = buffer_compute_nest_level_tokens(file, read_until, hint); - - i32 colon_expect_level = 1; - - Cpp_Get_Token_Result token_get = - cpp_get_token(&file->token_stack, hard_start.first_character); - - i32 token_i; - - { - if (token_get.in_whitespace){ - token_i = -1; - } - else{ - token_i = token_get.token_index; - } - } - - while (colon_expect_level != 0){ - Cpp_Token_Type type = CPP_TOKEN_JUNK; - if (token_i >= 0 && token_i < file->token_stack.count){ - type = file->token_stack.tokens[token_i].type; - } - - if (is_keyword(type)){ - Cpp_Token *token = file->token_stack.tokens + token_i; - String lexeme = make_string((char*)file->data + token->start, token->size); - if (colon_expect_level == 1){ - if (match("case", lexeme)){ - colon_expect_level = 2; - } - else if (match("public", lexeme)){ - colon_expect_level = 3; - } - else if (match("private", lexeme)){ - colon_expect_level = 3; - } - else if (match("protected", lexeme)){ - colon_expect_level = 3; - } - } - else{ - colon_expect_level = 0; - } - } - else{ - switch (type){ - case CPP_TOKEN_IDENTIFIER: - { - colon_expect_level = 3; - }break; - - case CPP_TOKEN_COLON: - { - if (colon_expect_level == 3){ - is_label = 1; - colon_expect_level = 0; - } - }break; - - default: - { - colon_expect_level = 0; - }break; - } - } - - ++token_i; - } - - if (!token_get.in_whitespace){ - Cpp_Token *token = file->token_stack.tokens + token_get.token_index; - if (token->type == CPP_TOKEN_STRING_CONSTANT || - token->type == CPP_TOKEN_CHARACTER_CONSTANT){ - is_string_continuation = 1; - } - } - - if (!is_string_continuation){ - token_i = token_get.token_index; - bool32 in_whitespace = token_get.in_whitespace; - if (token_i >= 0){ - Cpp_Token *token = file->token_stack.tokens + token_i; - - bool32 never_continuation = 0; - if (!in_whitespace){ - switch (token->type){ - case CPP_TOKEN_BRACE_CLOSE: - case CPP_TOKEN_BRACE_OPEN: - case CPP_TOKEN_PARENTHESE_OPEN: - case CPP_TOKEN_PARENTHESE_CLOSE: - case CPP_TOKEN_COMMENT: - never_continuation = 1; - break; - } - if (token->flags & CPP_TFLAG_PP_DIRECTIVE || - token->flags & CPP_TFLAG_PP_BODY){ - never_continuation = 1; - } - } - else{ - ++token_i; - } - - if (!never_continuation){ - --token_i; - token = file->token_stack.tokens + token_i; - bool32 keep_looping = 1; - is_continuation = 1; - while (token_i >= 0 && keep_looping){ - --token_i; - keep_looping = 0; - if (token->flags & CPP_TFLAG_PP_DIRECTIVE || - token->flags & CPP_TFLAG_PP_BODY){ - keep_looping = 1; - } - else{ - switch (token->type){ - case CPP_TOKEN_BRACE_CLOSE: - case CPP_TOKEN_BRACE_OPEN: - case CPP_TOKEN_PARENTHESE_OPEN: - case CPP_TOKEN_SEMICOLON: - case CPP_TOKEN_COLON: - case CPP_TOKEN_COMMA: - is_continuation = 0; - break; - - case CPP_TOKEN_COMMENT: - case CPP_TOKEN_JUNK: - keep_looping = 1; - break; - } - } - } - if (token_i == -1){ - is_continuation = 0; - } - } - } - } - - token_i = token_get.token_index; - if (token_i >= 0){ - Cpp_Token *token = file->token_stack.tokens + token_i; - if (!token_get.in_whitespace){ - if (token->flags & CPP_TFLAG_PP_DIRECTIVE || - token->flags & CPP_TFLAG_PP_BODY){ - is_preprocessor = 1; - } - } - } - } - - else{ - nesting = buffer_compute_nest_level_raw(file, read_until, hint); - } - - hint.start_level = nesting; - hint.start_pos = read_until; - - if (is_preprocessor || is_string_continuation){ - x_pos = 0; - } - else{ - x_pos = 4*(nesting.brace_level + nesting.bracket_level + nesting.paren_level); - if (is_continuation){ - x_pos += 4; - } - if (is_label){ - x_pos -= 4; - } - if (x_pos < 0){ - x_pos = 0; - } - } - - // TODO(allen): Need big transient memory for this operation. - // NOTE(allen): This is temporary. IRL it should probably come - // from transient memory space. - u8 whitespace[200]; - - Indent_Definition indent; - // TODO(allen): Revist all this. - indent = indent_by_width(x_pos, 4); - - TentativeAssert(indent.tabs + indent.spaces < 200); - - Shift_Information shift; - shift = buffer_set_indent_whitespace(mem, file, indent, whitespace, start); - - if (hint.start_pos >= shift.start){ - hint.start_pos += shift.amount; - } - - if (cursor >= shift.start && cursor <= shift.end){ - Line_Hard_Start hard_start; - hard_start = buffer_find_hard_start(file, shift.start); - cursor = hard_start.first_character; - } - else if (cursor > shift.end){ - cursor += shift.amount; - } - if (mark >= shift.start && mark <= shift.end){ - Line_Hard_Start hard_start; - hard_start = buffer_find_hard_start(file, shift.start); - mark = hard_start.first_character; - } - else if (mark > shift.end){ - mark += shift.amount; - } - - start = view_find_beginning_of_next_line(view, start); - end += shift.amount; - } - - view_cursor_move(view, cursor); - view->mark = pos_adjust_to_self(mark, data, file->size); -} -#endif - internal u32* style_get_color(Style *style, Cpp_Token token){ u32 *result; diff --git a/4ed_meta.h b/4ed_meta.h index a2370be8..40c2f4ba 100644 --- a/4ed_meta.h +++ b/4ed_meta.h @@ -25,9 +25,13 @@ typedef int16_t i16; typedef i32 bool32; typedef i8 bool8; +typedef i32 b32; +typedef i8 b8; typedef float real32; typedef double real64; +typedef float f32; +typedef double f64; #define internal static #define globalvar static diff --git a/buffer/4coder_golden_array.cpp b/buffer/4coder_golden_array.cpp index b997a8e5..84615c8a 100644 --- a/buffer/4coder_golden_array.cpp +++ b/buffer/4coder_golden_array.cpp @@ -166,6 +166,7 @@ measure_character(void *advance_data, int offset, int stride, int *new_line, cha return(width); } +#if 0 internal_4tech void buffer_measure_widths(Buffer *buffer, void *advance_data, int offset, int stride){ float *widths; @@ -206,6 +207,7 @@ buffer_measure_widths(Buffer *buffer, void *advance_data, int offset, int stride widths[i] = width; } } +#endif internal_4tech void buffer_remeasure_starts(Buffer *buffer, int line_start, int line_end, int line_shift, int text_shift){ @@ -219,6 +221,11 @@ buffer_remeasure_starts(Buffer *buffer, int line_start, int line_end, int line_s lines = buffer->line_starts; line_count = buffer->line_count; + Assert(0 <= line_start); + Assert(line_start <= line_end); + Assert(line_end < line_count); + Assert(line_count + line_shift <= buffer->line_max); + if (line_shift != 0){ memmove_4tech(lines + line_end + line_shift + 1, lines + line_end + 1, sizeof(int)*(line_count - line_end - 1)); @@ -252,9 +259,70 @@ buffer_remeasure_starts(Buffer *buffer, int line_start, int line_end, int line_s } } + Assert(line_count >= 1); buffer->line_count = line_count; } +internal_4tech void +buffer_remeasure_widths(Buffer *buffer, void *advance_data, int offset, int stride, + int line_start, int line_end, int line_shift){ + int *starts; + float *widths; + int line_count; + char *data; + int size; + int i, j, new_line; + float width; + char ch, next; + + starts = buffer->line_starts; + widths = buffer->line_widths; + line_count = buffer->line_count; + + Assert(0 <= line_start); + Assert(line_start <= line_end); + Assert(line_end < line_count); + Assert(line_count <= buffer->widths_max); + + if (line_shift != 0){ + memmove_4tech(widths + line_end + line_shift + 1, widths + line_end + 1, + sizeof(float)*(line_count - line_end - 1)); + line_count += line_shift; + } + + data = buffer->data; + size = buffer->size; + + Assert(size < buffer->max); + data[size] = 0; + + i = line_start; + j = starts[i]; + + for (; i <= line_end; ++i){ + Assert(j == starts[i]); + new_line = 0; + width = 0; + ch = data[j]; + next = data[++j]; + + while (new_line == 0){ + width += measure_character(advance_data, offset, stride, &new_line, ch); + ch = next; + next = data[++j]; + } + + --j; + widths[i] = width; + } +} + +inline_4tech void +buffer_measure_widths(Buffer *buffer, void *advance_data, int offset, int stride){ + Assert(buffer->line_count >= 1); + buffer_remeasure_widths(buffer, advance_data, offset, stride, 0, buffer->line_count-1, 0); +} + internal_4tech int buffer_get_line_index(Buffer *buffer, int pos, int l_bound, int u_bound){ int *lines; @@ -316,25 +384,23 @@ write_cursor_with_index(Cursor_With_Index *positions, int *count, int pos){ ++*count; } -internal_4tech int -buffer_quick_partition_cursors(Cursor_With_Index *positions, int start, int pivot){ - int i; - int pivot_pos; - pivot_pos = positions[pivot].pos; - for (i = start; i < pivot; ++i){ - if (positions[i].pos < pivot_pos){ - Swap(positions[start], positions[i]); - ++start; - } - } - Swap(positions[start], positions[pivot]); - return start; -} +#define CursorSwap__(a,b) { Cursor_With_Index t = a; a = b; b = t; } internal_4tech void buffer_quick_sort_cursors(Cursor_With_Index *positions, int start, int pivot){ - int mid; - mid = buffer_quick_partition_cursors(positions, start, pivot); + int i, mid; + int pivot_pos; + + mid = start; + pivot_pos = positions[pivot].pos; + for (i = mid; i < pivot; ++i){ + if (positions[i].pos < pivot_pos){ + CursorSwap__(positions[mid], positions[i]); + ++mid; + } + } + CursorSwap__(positions[mid], positions[pivot]); + if (start < mid - 1) buffer_quick_sort_cursors(positions, start, mid - 1); if (mid + 1 < pivot) buffer_quick_sort_cursors(positions, mid + 1, pivot); } @@ -345,29 +411,27 @@ buffer_sort_cursors(Cursor_With_Index *positions, int count){ buffer_quick_sort_cursors(positions, 0, count-1); } -internal_4tech int -buffer_quick_unpartition_cursors(Cursor_With_Index *positions, int start, int pivot){ - int i; - int pivot_index; - pivot_index = positions[pivot].index; - for (i = start; i < pivot; ++i){ - if (positions[i].index < pivot_index){ - Swap(positions[start], positions[i]); - ++start; - } - } - Swap(positions[start], positions[pivot]); - return start; -} - internal_4tech void buffer_quick_unsort_cursors(Cursor_With_Index *positions, int start, int pivot){ - int mid; - mid = buffer_quick_unpartition_cursors(positions, start, pivot); + int i, mid; + int pivot_index; + + mid = start; + pivot_index = positions[pivot].index; + for (i = mid; i < pivot; ++i){ + if (positions[i].index < pivot_index){ + CursorSwap__(positions[mid], positions[i]); + ++mid; + } + } + CursorSwap__(positions[mid], positions[pivot]); + if (start < mid - 1) buffer_quick_unsort_cursors(positions, start, mid - 1); if (mid + 1 < pivot) buffer_quick_unsort_cursors(positions, mid + 1, pivot); } +#undef CursorSwap__ + inline_4tech void buffer_unsort_cursors(Cursor_With_Index *positions, int count){ Assert(count > 0); @@ -376,16 +440,14 @@ buffer_unsort_cursors(Cursor_With_Index *positions, int count){ internal_4tech void buffer_update_cursors(Cursor_With_Index *sorted_positions, int count, int start, int end, int len){ - Cursor_With_Index *position, *end_position; + Cursor_With_Index *position; int shift_amount; shift_amount = (len - (end - start)); - position = sorted_positions; - end_position = sorted_positions + count; - for (; position < end_position && position->pos < start; ++position); - for (; position < end_position && position->pos < end; ++position) position->pos = start; - for (; position < end_position; ++position) position->pos += shift_amount; + position = sorted_positions + count - 1; + for (; position >= sorted_positions && position->pos >= end; --position) position->pos += shift_amount; + for (; position >= sorted_positions && position->pos >= start; --position) position->pos = start; } typedef enum{ @@ -450,11 +512,11 @@ typedef struct{ internal_4tech Full_Cursor buffer_cursor_seek(Buffer *buffer, Buffer_Seek seek, - float max_width, float font_height, void *width_data, int offset, int stride, Full_Cursor cursor){ + float max_width, float font_height, void *advance_data, int offset, int stride, Full_Cursor cursor){ Full_Cursor prev_cursor; - char *data, *data_; + char *data, *advances; int size; - int do_newline, do_slashr; + int do_newline; char ch, next; float ch_width; @@ -467,8 +529,11 @@ buffer_cursor_seek(Buffer *buffer, Buffer_Seek seek, Assert(size < buffer->max); data[size] = 0; - data_ = (char*)width_data + offset; + advances = (char*)advance_data + offset; + x = 0; + y = 0; + px = 0; xy_seek = (seek.type == buffer_seek_wrapped_xy || seek.type == buffer_seek_unwrapped_xy); for (;;){ @@ -478,21 +543,21 @@ buffer_cursor_seek(Buffer *buffer, Buffer_Seek seek, next = data[cursor.pos+1]; switch (ch){ - case '\r': do_newline = 0; do_slashr = 1; break; - case '\n': do_newline = 1; do_slashr = 0; break; + case '\n': do_newline = 1; break; + + case '\r': + do_newline = 0; + ++cursor.character; + ch_width = *(float*)(advances + stride * '\\') + *(float*)(advances + stride * 'r'); + break; default: - do_newline = 0; do_slashr = 0; + do_newline = 0; ++cursor.character; - ch_width = *(float*)(data_ + stride * ch); + ch_width = *(float*)(advances + stride * ch); break; } - if (do_slashr){ - ++cursor.character; - ch_width = *(float*)(data_ + stride * '\\') + *(float*)(data_ + stride * 'r'); - } - if (cursor.wrapped_x + ch_width >= max_width){ cursor.wrapped_y += font_height; cursor.wrapped_x = 0; @@ -519,9 +584,6 @@ buffer_cursor_seek(Buffer *buffer, Buffer_Seek seek, } get_out = 0; - x = 0; - y = 0; - px = 0; switch (seek.type){ case buffer_seek_pos: @@ -555,15 +617,14 @@ buffer_cursor_seek(Buffer *buffer, Buffer_Seek seek, break; } - if (seek.round_down){ - if (y > seek.y - font_height && x > seek.x){ - cursor = prev_cursor; + if (y > seek.y - font_height && x >= seek.x){ + if (!seek.round_down){ + if ((seek.x - px) < (x - seek.x)) cursor = prev_cursor; break; } - } - else{ - if (y > seek.y - font_height && x >= seek.x){ - if ((seek.x - px) < (x - seek.x)) cursor = prev_cursor; + + if (x > seek.x){ + cursor = prev_cursor; break; } } @@ -592,7 +653,7 @@ buffer_batch_debug_sort_check(Buffer_Edit *sorted_edits, int edit_count){ if (start_point > edit->start){ result = 0; break; } - start_point = Max(edit->end, edit->start + 1); + start_point = (edit->end < edit->start + 1)?edit->start + 1:edit->end; } return(result); @@ -649,12 +710,13 @@ buffer_batch_edit_step(Buffer_Batch_State *state, Buffer *buffer, Buffer_Edit *s internal_4tech void buffer_batch_edit(Buffer *buffer, Buffer_Edit *sorted_edits, int edit_count){ Buffer_Batch_State state; - int result; + debug_4tech(int result); state.i = 0; state.shift_total = 0; - result = buffer_batch_edit_step(&state, buffer, sorted_edits, edit_count); + debug_4tech(result =) + buffer_batch_edit_step(&state, buffer, sorted_edits, edit_count); Assert(result == 0); } diff --git a/win32_4ed.cpp b/win32_4ed.cpp index 9af60e83..520cdef3 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -947,13 +947,14 @@ WinMain(HINSTANCE hInstance, u32 creation_flag = 0; for (i32 i = 0; i < win32vars.groups[BACKGROUND_THREADS].count; ++i){ Thread_Context *thread = win32vars.groups[BACKGROUND_THREADS].threads + i; - thread->handle = CreateThread(0, 0, ThreadProc, thread, creation_flag, (LPDWORD)&thread->windows_id); thread->id = i + 1; - thread->queue = &win32vars.queues[BACKGROUND_THREADS]; Thread_Memory *memory = win32vars.thread_memory + i; *memory = {}; memory->id = thread->id; + + thread->queue = &win32vars.queues[BACKGROUND_THREADS]; + thread->handle = CreateThread(0, 0, ThreadProc, thread, creation_flag, (LPDWORD)&thread->windows_id); } Assert(win32vars.locks);