starting undo refactoring
This commit is contained in:
parent
c100efd1af
commit
1f1d02ec73
4
4ed.cpp
4
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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue