multi-gap buffer
This commit is contained in:
parent
02d72d118d
commit
afbde90d9e
40
4ed.cpp
40
4ed.cpp
|
@ -123,7 +123,7 @@ globalvar Application_Links app_links;
|
|||
|
||||
#define REQ_VIEW(n) View *n = command->view; if (!n) return
|
||||
#define REQ_FILE_VIEW(n) File_View *n = view_to_file_view(command->view); if (!n) return
|
||||
#define REQ_FILE(n,v) Editing_File *n = (v)->file; if (!n || !n->buffer.data || n->is_dummy) return
|
||||
#define REQ_FILE(n,v) Editing_File *n = (v)->file; if (!n || !buffer_good(&n->buffer) || n->is_dummy) return
|
||||
#define REQ_COLOR_VIEW(n) Color_View *n = view_to_color_view(command->view); if (!n) return
|
||||
#define REQ_DBG_VIEW(n) Debug_View *n = view_to_debug_view(command->view); if (!n) return
|
||||
|
||||
|
@ -215,6 +215,7 @@ COMMAND_DECL(write_character){
|
|||
}
|
||||
|
||||
COMMAND_DECL(seek_whitespace_right){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
@ -222,9 +223,11 @@ COMMAND_DECL(seek_whitespace_right){
|
|||
i32 pos = buffer_seek_whitespace_right(&file->buffer, view->cursor.pos);
|
||||
|
||||
view_cursor_move(view, pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
COMMAND_DECL(seek_whitespace_left){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
@ -232,24 +235,29 @@ COMMAND_DECL(seek_whitespace_left){
|
|||
i32 pos = buffer_seek_whitespace_left(&file->buffer, view->cursor.pos);
|
||||
|
||||
view_cursor_move(view, pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
COMMAND_DECL(seek_whitespace_up){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
||||
i32 pos = buffer_seek_whitespace_up(&file->buffer, view->cursor.pos);
|
||||
view_cursor_move(view, pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
COMMAND_DECL(seek_whitespace_down){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
||||
i32 pos = buffer_seek_whitespace_down(&file->buffer, view->cursor.pos);
|
||||
view_cursor_move(view, pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
internal i32
|
||||
|
@ -304,7 +312,7 @@ COMMAND_DECL(seek_token_right){
|
|||
}
|
||||
|
||||
COMMAND_DECL(seek_white_or_token_right){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
@ -320,7 +328,7 @@ COMMAND_DECL(seek_white_or_token_right){
|
|||
}
|
||||
|
||||
COMMAND_DECL(seek_white_or_token_left){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
@ -336,24 +344,29 @@ COMMAND_DECL(seek_white_or_token_left){
|
|||
}
|
||||
|
||||
COMMAND_DECL(seek_alphanumeric_right){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
||||
i32 pos = buffer_seek_alphanumeric_right(&file->buffer, view->cursor.pos);
|
||||
view_cursor_move(view, pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
COMMAND_DECL(seek_alphanumeric_left){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
||||
i32 pos = buffer_seek_alphanumeric_left(&file->buffer, view->cursor.pos);
|
||||
view_cursor_move(view, pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
COMMAND_DECL(seek_alphanumeric_or_camel_right){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
@ -361,9 +374,11 @@ COMMAND_DECL(seek_alphanumeric_or_camel_right){
|
|||
i32 an_pos = buffer_seek_alphanumeric_right(&file->buffer, view->cursor.pos);
|
||||
i32 pos = buffer_seek_alphanumeric_or_camel_right(&file->buffer, view->cursor.pos, an_pos);
|
||||
view_cursor_move(view, pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
COMMAND_DECL(seek_alphanumeric_or_camel_left){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
@ -371,6 +386,7 @@ COMMAND_DECL(seek_alphanumeric_or_camel_left){
|
|||
i32 an_pos = buffer_seek_alphanumeric_left(&file->buffer, view->cursor.pos);
|
||||
i32 pos = buffer_seek_alphanumeric_or_camel_left(&file->buffer, view->cursor.pos, an_pos);
|
||||
view_cursor_move(view, pos);
|
||||
#endif
|
||||
}
|
||||
|
||||
COMMAND_DECL(search){
|
||||
|
@ -690,7 +706,7 @@ app_open_file(App_Vars *vars, General_Memory *general, Panel *panel,
|
|||
|
||||
new_view->map = app_get_map(vars, target_file->base_map_id);
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
if (created_file && target_file->tokens_exist)
|
||||
file_first_lex_parallel(general, target_file);
|
||||
#endif
|
||||
|
@ -766,7 +782,7 @@ COMMAND_DECL(reopen){
|
|||
*file = temp_file;
|
||||
file->source_path.str = file->source_path_;
|
||||
file->live_name.str = file->live_name_;
|
||||
#if BUFFER_EXPERIMENT_SCALPEL
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
if (file->tokens_exist)
|
||||
file_first_lex_parallel(&mem->general, file);
|
||||
#endif
|
||||
|
@ -920,7 +936,7 @@ COMMAND_DECL(toggle_show_whitespace){
|
|||
}
|
||||
|
||||
COMMAND_DECL(toggle_tokens){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
|
@ -938,6 +954,7 @@ COMMAND_DECL(toggle_tokens){
|
|||
internal void
|
||||
case_change_range(Mem_Options *mem, File_View *view, Editing_File *file,
|
||||
u8 a, u8 z, u8 char_delta){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
Range range = get_range(view->cursor.pos, view->mark);
|
||||
if (range.start < range.end){
|
||||
Edit_Step step = {};
|
||||
|
@ -958,11 +975,10 @@ case_change_range(Mem_Options *mem, File_View *view, Editing_File *file,
|
|||
}
|
||||
}
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL
|
||||
if (file->token_stack.tokens)
|
||||
file_relex_parallel(mem, file, range.start, range.end, 0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
COMMAND_DECL(to_uppercase){
|
||||
|
@ -1452,7 +1468,7 @@ COMMAND_DECL(set_settings){
|
|||
switch (p){
|
||||
case par_lex_as_cpp_file:
|
||||
{
|
||||
#if BUFFER_EXPERIMENT_SCALPEL
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
int v = dynamic_to_bool(¶m->param.value);
|
||||
if (file->tokens_exist){
|
||||
if (!v) file_kill_tokens(&mem->general, file);
|
||||
|
@ -1572,7 +1588,7 @@ extern "C"{
|
|||
if (view){
|
||||
Editing_File *file = view->file;
|
||||
if (file && !file->is_dummy){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
Working_Set *working_set = cmd->working_set;
|
||||
buffer.file_id = (int)(file - working_set->files);
|
||||
buffer.size = file->buffer.size;
|
||||
|
@ -2943,7 +2959,7 @@ app_step(Thread_Context *thread, Key_Codes *codes,
|
|||
view_set_file(file_view, file.file, style,
|
||||
vars->hooks[hook_open_file], &command_data, app_links);
|
||||
new_view->map = app_get_map(vars, file.file->base_map_id);
|
||||
#if BUFFER_EXPERIMENT_SCALPEL
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
if (file.file->tokens_exist) file_first_lex_parallel(general, file.file);
|
||||
#endif
|
||||
}break;
|
||||
|
@ -3058,7 +3074,7 @@ app_step(Thread_Context *thread, Key_Codes *codes,
|
|||
|
||||
Editing_File *file = vars->working_set.files;
|
||||
for (i32 i = vars->working_set.file_index_count; i > 0; --i, ++file){
|
||||
if (file->buffer.data && !file->is_dummy){
|
||||
if (buffer_good(&file->buffer) && !file->is_dummy){
|
||||
file_measure_widths(&vars->mem.general, file, vars->style.font);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1111,13 +1111,14 @@ step_draw_adjusting(Color_View *color_view, i32_Rect rect, View_Message message,
|
|||
|
||||
internal void
|
||||
update_highlighting(Color_View *color_view){
|
||||
Style *style = color_view->main_style;
|
||||
File_View *file_view = color_view->hot_file_view;
|
||||
if (!file_view){
|
||||
color_view->highlight = {};
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
Style *style = color_view->main_style;
|
||||
Editing_File *file = file_view->file;
|
||||
i32 pos = view_get_cursor_pos(file_view);
|
||||
char c = file->buffer.data[pos];
|
||||
|
@ -1181,6 +1182,7 @@ update_highlighting(Color_View *color_view){
|
|||
color_view->highlight.ids[2] = 0;
|
||||
color_view->highlight.ids[3] = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
internal bool32
|
||||
|
|
|
@ -11,13 +11,17 @@
|
|||
|
||||
#include "buffer/4coder_shared.cpp"
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL
|
||||
#if BUFFER_EXPERIMENT_SCALPEL == 0
|
||||
#include "buffer/4coder_golden_array.cpp"
|
||||
#define Buffer_Type Buffer
|
||||
#else
|
||||
#elif BUFFER_EXPERIMENT_SCALPEL == 1
|
||||
#include "buffer/4coder_gap_buffer.cpp"
|
||||
#define Buffer_Type Gap_Buffer
|
||||
#else
|
||||
#include "buffer/4coder_multi_gap_buffer.cpp"
|
||||
#define Buffer_Type Multi_Gap_Buffer
|
||||
#endif
|
||||
|
||||
#include "buffer/4coder_buffer_abstract.cpp"
|
||||
|
||||
struct Range{
|
||||
|
@ -1118,6 +1122,7 @@ file_synchronize_times(Editing_File *file, u8 *filename){
|
|||
internal bool32
|
||||
file_save(Partition *part, Editing_File *file, u8 *filename){
|
||||
bool32 result = 0;
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
Temp_Memory temp = begin_temp_memory(part);
|
||||
i32 max = partition_remaining(part);
|
||||
if (file->dos_write_mode){
|
||||
|
@ -1134,6 +1139,7 @@ file_save(Partition *part, Editing_File *file, u8 *filename){
|
|||
}
|
||||
end_temp_memory(temp);
|
||||
file_synchronize_times(file, filename);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1149,7 +1155,11 @@ file_save_and_set_names(Partition *part, Editing_File *file, u8 *filename){
|
|||
|
||||
inline i32
|
||||
file_count_newlines(Editing_File *file, i32 start, i32 end){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
i32 count = buffer_count_newlines(&file->buffer, start, end);
|
||||
#else
|
||||
i32 count = 0;
|
||||
#endif
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -1173,6 +1183,7 @@ enum File_Bubble_Type{
|
|||
internal i32
|
||||
file_grow_starts_as_needed(General_Memory *general, Editing_File *file, i32 additional_lines){
|
||||
bool32 result = GROW_NOT_NEEDED;
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
i32 max = file->buffer.line_max;
|
||||
i32 count = file->buffer.line_count;
|
||||
i32 target_lines = count + additional_lines;
|
||||
|
@ -1190,11 +1201,13 @@ file_grow_starts_as_needed(General_Memory *general, Editing_File *file, i32 addi
|
|||
result = GROW_FAILED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
file_measure_starts(General_Memory *general, Editing_File *file){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
ProfileMomentFunction();
|
||||
if (!file->buffer.line_starts){
|
||||
i32 max = file->buffer.line_max = Kbytes(1);
|
||||
|
@ -1220,18 +1233,21 @@ file_measure_starts(General_Memory *general, Editing_File *file){
|
|||
file->buffer.line_max = max;
|
||||
}
|
||||
file->buffer.line_count = state.count;
|
||||
#endif
|
||||
}
|
||||
|
||||
internal void
|
||||
file_remeasure_starts(General_Memory *general, Editing_File *file,
|
||||
i32 line_start, i32 line_end, i32 line_shift,
|
||||
i32 character_shift){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct Opaque_Font_Advance{
|
||||
|
@ -1249,6 +1265,7 @@ get_opaque_font_advance(Font *font){
|
|||
|
||||
internal void
|
||||
file_grow_widths_as_needed(General_Memory *general, Editing_File *file){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
i32 line_count = file->buffer.line_count;
|
||||
if (line_count > file->buffer.widths_max){
|
||||
i32 new_max = LargeRoundUp(line_count, Kbytes(1));
|
||||
|
@ -1262,26 +1279,31 @@ file_grow_widths_as_needed(General_Memory *general, Editing_File *file){
|
|||
}
|
||||
file->buffer.widths_max = new_max;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
internal void
|
||||
file_measure_widths(General_Memory *general, Editing_File *file, Font *font){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
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.stride);
|
||||
#endif
|
||||
}
|
||||
|
||||
internal void
|
||||
file_remeasure_widths(General_Memory *general, Editing_File *file, Font *font,
|
||||
i32 line_start, i32 line_end, i32 line_shift){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
ProfileMomentFunction();
|
||||
|
||||
file_grow_widths_as_needed(general, file);
|
||||
Opaque_Font_Advance opad = get_opaque_font_advance(font);
|
||||
buffer_remeasure_widths(&file->buffer, opad.data, opad.stride,
|
||||
line_start, line_end, line_shift);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline i32
|
||||
|
@ -1293,8 +1315,9 @@ view_wrapped_line_span(real32 line_width, real32 max_width){
|
|||
|
||||
internal i32
|
||||
view_compute_lowest_line(File_View *view){
|
||||
i32 last_line = view->line_count - 1;
|
||||
i32 lowest_line = 0;
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
i32 last_line = view->line_count - 1;
|
||||
if (last_line > 0){
|
||||
if (view->unwrapped_lines){
|
||||
lowest_line = last_line;
|
||||
|
@ -1313,11 +1336,13 @@ view_compute_lowest_line(File_View *view){
|
|||
lowest_line += line_span - 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return lowest_line;
|
||||
}
|
||||
|
||||
internal void
|
||||
view_measure_wraps(General_Memory *general, File_View *view){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
ProfileMomentFunction();
|
||||
Editing_File *file = view->file;
|
||||
i32 line_count = file->buffer.line_count;
|
||||
|
@ -1340,23 +1365,35 @@ view_measure_wraps(General_Memory *general, File_View *view){
|
|||
buffer_measure_wrap_y(&file->buffer, view->line_wrap_y, line_height, max_width);
|
||||
|
||||
view->line_count = line_count;
|
||||
#endif
|
||||
}
|
||||
|
||||
internal void*
|
||||
alloc_for_buffer(void *context, int *size){
|
||||
*size = LargeRoundUp(*size, Kbytes(4));
|
||||
void *data = general_memory_allocate((General_Memory*)context, *size, BUBBLE_BUFFER);
|
||||
return data;
|
||||
}
|
||||
|
||||
internal void
|
||||
file_create_from_string(General_Memory *general, Editing_File *file, u8 *filename, Font *font, String val){
|
||||
i32 request_size = LargeRoundUp(1+val.size*2, Kbytes(64));
|
||||
u8 *data = (u8*)general_memory_allocate(general, request_size, BUBBLE_BUFFER);
|
||||
|
||||
// TODO(allen): if we didn't get the memory what is going on?
|
||||
// request_size too large?
|
||||
// need to expand general memory allocator's base pool?
|
||||
// need to release least recently used target?
|
||||
Assert(data);
|
||||
|
||||
*file = {};
|
||||
file->buffer.data = (char*)data;
|
||||
file->buffer.max = request_size;
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||
|
||||
Buffer_Init_Type init = buffer_begin_init(&file->buffer, val.str, val.size);
|
||||
for (; buffer_init_need_more(&init); ){
|
||||
i32 page_size = buffer_init_page_size(&init);
|
||||
page_size = LargeRoundUp(page_size, Kbytes(4));
|
||||
void *data = general_memory_allocate(general, page_size, BUBBLE_BUFFER);
|
||||
buffer_init_provide_page(&init, data, page_size);
|
||||
}
|
||||
i32 init_success = buffer_end_init(&init);
|
||||
Assert(init_success);
|
||||
|
||||
#if 0
|
||||
buffer_initialize(&file->buffer, val.str, val.size);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
file_synchronize_times(file, filename);
|
||||
file_init_strings(file);
|
||||
|
@ -1367,7 +1404,8 @@ file_create_from_string(General_Memory *general, Editing_File *file, u8 *filenam
|
|||
file_measure_starts(general, file);
|
||||
file_measure_widths(general, file, font);
|
||||
file->font = font;
|
||||
|
||||
|
||||
i32 request_size = Kbytes(64);
|
||||
file->undo.undo.max = request_size;
|
||||
file->undo.undo.strings = (u8*)general_memory_allocate(general, request_size, BUBBLE_UNDO_STRING);
|
||||
file->undo.undo.edit_max = request_size / sizeof(Edit_Step);
|
||||
|
@ -1451,9 +1489,11 @@ file_close(General_Memory *general, Editing_File *file){
|
|||
if (file->token_stack.tokens){
|
||||
general_memory_free(general, file->token_stack.tokens);
|
||||
}
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
general_memory_free(general, file->buffer.data);
|
||||
general_memory_free(general, file->buffer.line_starts);
|
||||
general_memory_free(general, file->buffer.line_widths);
|
||||
#endif
|
||||
|
||||
general_memory_free(general, file->undo.undo.strings);
|
||||
general_memory_free(general, file->undo.undo.edits);
|
||||
|
@ -1475,7 +1515,7 @@ struct Shift_Information{
|
|||
i32 start, end, amount;
|
||||
};
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
internal
|
||||
JOB_CALLBACK(job_full_lex){
|
||||
Editing_File *file = (Editing_File*)data[0];
|
||||
|
@ -1553,7 +1593,7 @@ file_kill_tokens(General_Memory *general, Editing_File *file){
|
|||
file->token_stack = {};
|
||||
}
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
internal void
|
||||
file_first_lex_parallel(General_Memory *general, Editing_File *file){
|
||||
Assert(file->token_stack.tokens == 0);
|
||||
|
@ -1659,6 +1699,7 @@ file_relex_parallel(Mem_Options *mem, Editing_File *file,
|
|||
internal bool32
|
||||
file_grow_as_needed(General_Memory *general, Editing_File *file, i32 additional_size){
|
||||
bool32 result = 1;
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
i32 size = buffer_size(&file->buffer);
|
||||
i32 target_size = size + additional_size + 1;
|
||||
if (target_size >= file->buffer.max){
|
||||
|
@ -1669,6 +1710,7 @@ file_grow_as_needed(General_Memory *general, Editing_File *file, i32 additional_
|
|||
void *old_data = buffer_relocate(&file->buffer, new_data, request_size);
|
||||
general_memory_free(general, old_data);
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1746,6 +1788,7 @@ struct Edit_Spec{
|
|||
Edit_Step step;
|
||||
};
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
internal Edit_Step*
|
||||
file_post_undo(General_Memory *general, Editing_File *file,
|
||||
Edit_Step step, bool32 do_merge, bool32 can_merge){
|
||||
|
@ -1809,9 +1852,9 @@ file_post_undo(General_Memory *general, Editing_File *file,
|
|||
result = undo->edits + (undo->edit_count++);
|
||||
*result = inv_step;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void
|
||||
undo_stack_pop(Edit_Stack *stack){
|
||||
|
@ -1821,6 +1864,7 @@ undo_stack_pop(Edit_Stack *stack){
|
|||
}
|
||||
}
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
internal void
|
||||
file_post_redo(General_Memory *general, Editing_File *file, Edit_Step step){
|
||||
Edit_Stack *redo = &file->undo.redo;
|
||||
|
@ -1857,6 +1901,7 @@ file_post_redo(General_Memory *general, Editing_File *file, Edit_Step step){
|
|||
redo->edits[redo->edit_count++] = inv_step;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void
|
||||
file_post_history_block(Editing_File *file, i32 pos){
|
||||
|
@ -1880,6 +1925,7 @@ file_unpost_history_block(Editing_File *file){
|
|||
file->undo.history_head_block = old_head->prev_block;
|
||||
}
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
internal Edit_Step*
|
||||
file_post_history(General_Memory *general, Editing_File *file,
|
||||
Edit_Step step, bool32 do_merge, bool32 can_merge){
|
||||
|
@ -1949,37 +1995,47 @@ file_post_history(General_Memory *general, Editing_File *file,
|
|||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline Full_Cursor
|
||||
view_compute_cursor_from_pos(File_View *view, i32 pos){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
Editing_File *file = view->file;
|
||||
Style *style = view->style;
|
||||
Font *font = style->font;
|
||||
|
||||
real32 max_width = view_compute_width(view);
|
||||
Opaque_Font_Advance opad = get_opaque_font_advance(font);
|
||||
|
||||
|
||||
return buffer_cursor_from_pos(&file->buffer, pos, view->line_wrap_y,
|
||||
max_width, (real32)font->height, opad.data, opad.stride);
|
||||
#else
|
||||
return view->cursor;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline Full_Cursor
|
||||
view_compute_cursor_from_unwrapped_xy(File_View *view, real32 seek_x, real32 seek_y,
|
||||
bool32 round_down = 0){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
Editing_File *file = view->file;
|
||||
Style *style = view->style;
|
||||
Font *font = style->font;
|
||||
|
||||
real32 max_width = view_compute_width(view);
|
||||
Opaque_Font_Advance opad = get_opaque_font_advance(font);
|
||||
|
||||
|
||||
return buffer_cursor_from_unwrapped_xy(&file->buffer, seek_x, seek_y, round_down, view->line_wrap_y,
|
||||
max_width, (real32)font->height, opad.data, opad.stride);
|
||||
#else
|
||||
return view->cursor;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline Full_Cursor
|
||||
view_compute_cursor_from_wrapped_xy(File_View *view, real32 seek_x, real32 seek_y,
|
||||
bool32 round_down = 0){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
Editing_File *file = view->file;
|
||||
Style *style = view->style;
|
||||
Font *font = style->font;
|
||||
|
@ -1989,6 +2045,9 @@ view_compute_cursor_from_wrapped_xy(File_View *view, real32 seek_x, real32 seek_
|
|||
|
||||
return buffer_cursor_from_wrapped_xy(&file->buffer, seek_x, seek_y, round_down, view->line_wrap_y,
|
||||
max_width, (real32)font->height, opad.data, opad.stride);
|
||||
#else
|
||||
return view->cursor;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline Full_Cursor
|
||||
|
@ -2212,6 +2271,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){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
General_Memory *general = &mem->general;
|
||||
|
||||
#if FRED_SLOW
|
||||
|
@ -2376,6 +2436,7 @@ view_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step
|
|||
}
|
||||
|
||||
if (history_mode == hist_normal) file->undo.edit_history_cursor = file->undo.history.edit_count;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline b32
|
||||
|
@ -2409,20 +2470,21 @@ view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file,
|
|||
// NOTE(allen): fixing stuff beforewards????
|
||||
view_update_history_before_edit(mem, file, spec.step, spec.str, history_mode);
|
||||
file_pre_edit_maintenance(file);
|
||||
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
// NOTE(allen): actual text replacement
|
||||
General_Memory *general = &mem->general;
|
||||
|
||||
|
||||
i32 start = spec.step.edit.start;
|
||||
i32 end = spec.step.edit.end;
|
||||
char *str = (char*)spec.str; AllowLocal(str);
|
||||
char *str = (char*)spec.str;
|
||||
i32 str_len = spec.step.edit.len;
|
||||
|
||||
|
||||
i32 shift_amount = 0;
|
||||
while (buffer_replace_range(&file->buffer, start, end, str, str_len, &shift_amount))
|
||||
file_grow_as_needed(general, file, shift_amount);
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
// NOTE(allen): fixing stuff afterwards
|
||||
if (file->tokens_exist)
|
||||
file_relex_parallel(mem, file, start, end, shift_amount);
|
||||
|
@ -2484,11 +2546,13 @@ view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file,
|
|||
}
|
||||
|
||||
end_temp_memory(cursor_temp);
|
||||
#endif
|
||||
}
|
||||
|
||||
internal void
|
||||
view_do_white_batch_edit(Mem_Options *mem, File_View *view, Editing_File *file,
|
||||
Editing_Layout *layout, Edit_Spec spec, History_Mode history_mode){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
Assert(file);
|
||||
ProfileMomentFunction();
|
||||
|
||||
|
@ -2580,6 +2644,7 @@ view_do_white_batch_edit(Mem_Options *mem, File_View *view, Editing_File *file,
|
|||
}
|
||||
end_temp_memory(cursor_temp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void
|
||||
|
@ -2704,7 +2769,7 @@ view_history_step(Mem_Options *mem, Editing_Layout *layout, File_View *view, His
|
|||
// TODO(allen): should these still be view operations?
|
||||
internal i32
|
||||
view_find_end_of_line(File_View *view, i32 pos){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
Editing_File *file = view->file;
|
||||
char *data = file->buffer.data;
|
||||
while (pos < file->buffer.size && data[pos] != '\n') ++pos;
|
||||
|
@ -2715,7 +2780,7 @@ view_find_end_of_line(File_View *view, i32 pos){
|
|||
|
||||
internal i32
|
||||
view_find_beginning_of_line(File_View *view, i32 pos){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
Editing_File *file = view->file;
|
||||
char *data = file->buffer.data;
|
||||
if (pos > 0){
|
||||
|
@ -2729,7 +2794,7 @@ view_find_beginning_of_line(File_View *view, i32 pos){
|
|||
|
||||
internal i32
|
||||
view_find_beginning_of_next_line(File_View *view, i32 pos){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
Editing_File *file = view->file;
|
||||
char *data = file->buffer.data;
|
||||
while (pos < file->buffer.size &&
|
||||
|
@ -2833,11 +2898,13 @@ working_set_lookup_file(Working_Set *working_set, String string){
|
|||
|
||||
internal void
|
||||
clipboard_copy(General_Memory *general, Working_Set *working, Range range, Editing_File *file){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
i32 size = range.end - range.start;
|
||||
String *dest = working_set_next_clipboard_string(general, working, size);
|
||||
buffer_stringify(&file->buffer, range.start, range.end, dest->str);
|
||||
dest->size = size;
|
||||
system_post_clipboard(*dest);
|
||||
#endif
|
||||
}
|
||||
|
||||
internal Edit_Spec
|
||||
|
@ -2845,6 +2912,7 @@ 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){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
General_Memory *general = &mem->general;
|
||||
|
||||
i32 inv_str_pos = 0;
|
||||
|
@ -2867,12 +2935,16 @@ view_compute_whitespace_edit(Mem_Options *mem, Editing_File *file,
|
|||
spec.step.special_type = 1;
|
||||
spec.step.child_count = edit_count;
|
||||
spec.step.inverse_child_count = edit_count;
|
||||
#else
|
||||
Edit_Spec spec = {};
|
||||
#endif
|
||||
|
||||
return spec;
|
||||
}
|
||||
|
||||
internal void
|
||||
view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout){
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
Editing_File *file = view->file;
|
||||
Assert(file && !file->is_dummy);
|
||||
Partition *part = &mem->part;
|
||||
|
@ -2926,12 +2998,13 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout)
|
|||
}
|
||||
|
||||
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
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
Editing_File *file = view->file;
|
||||
Assert(file && !file->is_dummy);
|
||||
Partition *part = &mem->part;
|
||||
|
@ -3654,12 +3727,13 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
|
|||
bar.rect = rect;
|
||||
bar.rect.y1 = bar.rect.y0 + font->height + 2;
|
||||
rect.y0 += font->height + 2;
|
||||
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
i32 max_x = rect.x1 - rect.x0;
|
||||
i32 max_y = rect.y1 - rect.y0 + font->height;
|
||||
|
||||
Assert(file && file->buffer.data && !file->is_dummy);
|
||||
|
||||
Assert(file && buffer_good(&file->buffer) && !file->is_dummy);
|
||||
|
||||
Opaque_Font_Advance opad = get_opaque_font_advance(font);
|
||||
b32 tokens_use = file->tokens_complete && (file->token_stack.count > 0);
|
||||
Cpp_Token_Stack token_stack = file->token_stack;
|
||||
|
@ -3670,7 +3744,7 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
|
|||
partition_align(part, 4);
|
||||
i32 max = partition_remaining(part) / sizeof(Buffer_Render_Item);
|
||||
Buffer_Render_Item *items = push_array(part, Buffer_Render_Item, max);
|
||||
|
||||
|
||||
i32 count;
|
||||
buffer_get_render_data(&file->buffer, view->line_wrap_y, items, max, &count,
|
||||
(real32)rect.x0, (real32)rect.y0, view->scroll_x, view->scroll_y, !view->unwrapped_lines,
|
||||
|
@ -3756,184 +3830,6 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
|
|||
}
|
||||
|
||||
end_temp_memory(temp);
|
||||
|
||||
#if 0
|
||||
|
||||
i32 size = (i32)file->buffer.size;
|
||||
u8 *data = (u8*)file->buffer.data;
|
||||
|
||||
Full_Cursor start_cursor;
|
||||
start_cursor = view_compute_cursor_from_xy(view, 0, view->scroll_y);
|
||||
view->scroll_y_cursor = start_cursor;
|
||||
|
||||
i32 start_character = start_cursor.pos;
|
||||
|
||||
real32 shift_x = rect.x0 - view->scroll_x;
|
||||
real32 shift_y = rect.y0 - view->scroll_y;
|
||||
if (view->unwrapped_lines) shift_y += start_cursor.unwrapped_y;
|
||||
else shift_y += start_cursor.wrapped_y;
|
||||
|
||||
real32 pos_x = 0;
|
||||
real32 pos_y = 0;
|
||||
|
||||
u32 highlight_color = 0;
|
||||
u32 main_color = style->main.default_color;
|
||||
i32 token_i = 0;
|
||||
|
||||
if (tokens_use){
|
||||
Cpp_Get_Token_Result result = cpp_get_token(&token_stack, start_character);
|
||||
token_i = result.token_index;
|
||||
|
||||
main_color = *style_get_color(style, token_stack.tokens[token_i]);
|
||||
++token_i;
|
||||
}
|
||||
|
||||
data[size] = 0;
|
||||
for (i32 i = start_character; i <= size; ++i){
|
||||
u8 to_render;
|
||||
to_render = data[i];
|
||||
|
||||
real32 ch_width = font_get_glyph_width(font, to_render);
|
||||
real32 ch_advance = measure_character(opad.data, opad.stride, to_render);
|
||||
|
||||
if (!view->unwrapped_lines && pos_x + ch_advance > max_x){
|
||||
pos_x = 0;
|
||||
pos_y += font->height;
|
||||
}
|
||||
|
||||
u32 fade_color = 0xFFFF00FF;
|
||||
real32 fade_amount = 0.f;
|
||||
if (view->paste_effect.tick_down > 0 &&
|
||||
view->paste_effect.start <= i && i < view->paste_effect.end){
|
||||
fade_color = view->paste_effect.color;
|
||||
fade_amount = (real32)(view->paste_effect.tick_down) / view->paste_effect.tick_max;
|
||||
}
|
||||
|
||||
highlight_color = 0;
|
||||
if (tokens_use){
|
||||
Cpp_Token current_token = token_stack.tokens[token_i-1];
|
||||
|
||||
if (token_i < token_stack.count){
|
||||
if (i >= token_stack.tokens[token_i].start){
|
||||
main_color =
|
||||
*style_get_color(style, token_stack.tokens[token_i]);
|
||||
current_token = token_stack.tokens[token_i];
|
||||
++token_i;
|
||||
}
|
||||
else if (i >= current_token.start + current_token.size){
|
||||
main_color = 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_token.type == CPP_TOKEN_JUNK &&
|
||||
i >= current_token.start && i <= current_token.start + current_token.size){
|
||||
highlight_color = style->main.highlight_junk_color;
|
||||
}
|
||||
}
|
||||
if (highlight_color == 0 && view->show_whitespace && char_is_whitespace(data[i])){
|
||||
highlight_color = style->main.highlight_white_color;
|
||||
}
|
||||
|
||||
i32 cursor_mode = 0;
|
||||
if (view->show_temp_highlight){
|
||||
if (view->temp_highlight.pos <= i && i < view->temp_highlight_end_pos)
|
||||
cursor_mode = 2;
|
||||
}
|
||||
else{
|
||||
if (view->cursor.pos == i)
|
||||
cursor_mode = 1;
|
||||
}
|
||||
|
||||
real32_Rect cursor_rect =
|
||||
real32XYWH(shift_x + pos_x, shift_y + pos_y,
|
||||
1 + ch_width, (real32)font->height);
|
||||
|
||||
if (to_render == '\t' || to_render == 0){
|
||||
cursor_rect.x1 = cursor_rect.x0 + font->chardata[' '].xadvance;
|
||||
}
|
||||
|
||||
if (highlight_color != 0){
|
||||
real32_Rect highlight_rect = cursor_rect;
|
||||
highlight_rect.x0 += 1;
|
||||
draw_rectangle(target, highlight_rect, highlight_color);
|
||||
}
|
||||
|
||||
u32 cursor_color = 0;
|
||||
switch (cursor_mode){
|
||||
case 1:
|
||||
cursor_color = style->main.cursor_color; break;
|
||||
case 2:
|
||||
cursor_color = style->main.highlight_color; break;
|
||||
}
|
||||
|
||||
if (is_active){
|
||||
if (cursor_color & 0xFF000000) draw_rectangle(target, cursor_rect, cursor_color);
|
||||
}
|
||||
else{
|
||||
if (cursor_color & 0xFF000000)draw_rectangle_outline(target, cursor_rect, cursor_color);
|
||||
}
|
||||
if (i == view->mark){
|
||||
draw_rectangle_outline(target, cursor_rect, style->main.mark_color);
|
||||
}
|
||||
|
||||
u32 char_color = main_color;
|
||||
u32 special_char_color = main_color;
|
||||
if (to_render == '\r'){
|
||||
special_char_color = char_color = style->main.special_character_color;
|
||||
}
|
||||
if (is_active){
|
||||
switch (cursor_mode){
|
||||
case 1:
|
||||
char_color = style->main.at_cursor_color; break;
|
||||
case 2:
|
||||
special_char_color = char_color = style->main.at_highlight_color; break;
|
||||
}
|
||||
}
|
||||
|
||||
char_color = color_blend(char_color, fade_amount, fade_color);
|
||||
special_char_color = color_blend(special_char_color, fade_amount, fade_color);
|
||||
|
||||
if (to_render == '\r'){
|
||||
font_draw_glyph(target, font, '\\',
|
||||
shift_x + pos_x,
|
||||
shift_y + pos_y,
|
||||
char_color);
|
||||
pos_x += font_get_glyph_width(font, '\\');
|
||||
|
||||
real32 cw = font_get_glyph_width(font, 'r');
|
||||
draw_rectangle(target,
|
||||
real32XYWH(shift_x + pos_x,
|
||||
shift_y + pos_y,
|
||||
cw, (real32)font->height),
|
||||
highlight_color);
|
||||
font_draw_glyph(target, font, 'r',
|
||||
shift_x + pos_x,
|
||||
shift_y + pos_y,
|
||||
special_char_color);
|
||||
pos_x += cw;
|
||||
}
|
||||
|
||||
else if (to_render == '\n'){
|
||||
pos_x = 0;
|
||||
pos_y += font->height;
|
||||
}
|
||||
|
||||
else if (font->glyphs[to_render].exists){
|
||||
font_draw_glyph(target, font, to_render,
|
||||
shift_x + pos_x,
|
||||
shift_y + pos_y,
|
||||
char_color);
|
||||
pos_x += ch_width;
|
||||
}
|
||||
|
||||
else{
|
||||
pos_x += ch_width;
|
||||
}
|
||||
|
||||
if (pos_y > max_y){
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (view->widget.type != FWIDG_NONE){
|
||||
|
@ -4089,7 +3985,7 @@ HANDLE_COMMAND_SIG(handle_command_file_view){
|
|||
|
||||
case FWIDG_SEARCH:
|
||||
{
|
||||
#if BUFFER_EXPERIMENT_SCALPEL
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
String *string = &file_view->isearch.str;
|
||||
Single_Line_Input_Step result =
|
||||
app_single_line_input_step(codes, key, string);
|
||||
|
@ -4100,72 +3996,61 @@ HANDLE_COMMAND_SIG(handle_command_file_view){
|
|||
bool32 step_forward = 0;
|
||||
bool32 step_backward = 0;
|
||||
|
||||
if (binding.function == command_search){
|
||||
step_forward = 1;
|
||||
}
|
||||
if (binding.function == command_rsearch){
|
||||
step_backward = 1;
|
||||
}
|
||||
if (binding.function == command_search) step_forward = 1;
|
||||
if (binding.function == command_rsearch) step_backward = 1;
|
||||
|
||||
i32 start_pos = file_view->isearch.pos;
|
||||
if (step_forward){
|
||||
if (file_view->isearch.reverse){
|
||||
start_pos = file_view->temp_highlight.pos - 1;
|
||||
start_pos = file_view->temp_highlight.pos + 1;
|
||||
file_view->isearch.pos = start_pos;
|
||||
file_view->isearch.reverse = 0;
|
||||
step_forward = 0;
|
||||
}
|
||||
}
|
||||
if (step_backward){
|
||||
if (!file_view->isearch.reverse){
|
||||
start_pos = file_view->temp_highlight.pos + 1;
|
||||
start_pos = file_view->temp_highlight.pos - 1;
|
||||
file_view->isearch.pos = start_pos;
|
||||
file_view->isearch.reverse = 1;
|
||||
step_backward = 0;
|
||||
}
|
||||
}
|
||||
|
||||
String file_string = make_string(file->buffer.data, file->buffer.size);
|
||||
|
||||
Temp_Memory temp = begin_temp_memory(&view->mem->part);
|
||||
char *spare = push_array(&view->mem->part, char, string->size);
|
||||
|
||||
i32 size = buffer_size(&file->buffer);
|
||||
i32 pos;
|
||||
if (file_view->isearch.reverse){
|
||||
if (result.hit_backspace){
|
||||
start_pos = file_view->temp_highlight.pos + 1;
|
||||
file_view->isearch.pos = start_pos;
|
||||
}
|
||||
else{
|
||||
pos = rfind_substr(file_string, start_pos - 1, *string);
|
||||
if (!result.hit_backspace){
|
||||
if (file_view->isearch.reverse){
|
||||
pos = buffer_rfind_string(&file->buffer, start_pos - 1, string->str, string->size, spare);
|
||||
if (pos >= 0){
|
||||
if (step_backward){ // TODO(allen): this if and it's mirror are suspicious
|
||||
if (step_backward){
|
||||
file_view->isearch.pos = pos;
|
||||
start_pos = pos;
|
||||
pos = rfind_substr(file_string, start_pos - 1, *string);
|
||||
if (pos == -1){
|
||||
pos = start_pos;
|
||||
}
|
||||
pos = buffer_rfind_string(&file->buffer, start_pos - 1, string->str, string->size, spare);
|
||||
if (pos == -1) pos = start_pos;
|
||||
}
|
||||
view_set_temp_highlight(file_view, pos, pos+string->size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else{
|
||||
if (result.hit_backspace){
|
||||
start_pos = file_view->temp_highlight.pos - 1;
|
||||
file_view->isearch.pos = start_pos;
|
||||
}
|
||||
|
||||
else{
|
||||
pos = find_substr(file_string, start_pos + 1, *string);
|
||||
if (pos < file->buffer.size){
|
||||
pos = buffer_find_string(&file->buffer, start_pos + 1, string->str, string->size, spare);
|
||||
if (pos < size){
|
||||
if (step_forward){
|
||||
file_view->isearch.pos = pos;
|
||||
start_pos = pos;
|
||||
pos = find_substr(file_string, start_pos + 1, *string);
|
||||
if (pos == file->buffer.size){
|
||||
pos = start_pos;
|
||||
}
|
||||
pos = buffer_find_string(&file->buffer, start_pos + 1, string->str, string->size, spare);
|
||||
if (pos == size) pos = start_pos;
|
||||
}
|
||||
view_set_temp_highlight(file_view, pos, pos+string->size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end_temp_memory(temp);
|
||||
}
|
||||
|
||||
if (result.hit_newline || result.hit_ctrl_newline){
|
||||
|
|
|
@ -77,7 +77,7 @@ _OutDbgStr(u8*);
|
|||
#endif
|
||||
|
||||
#if FRED_SLOW
|
||||
# define Assert(c) if(!(c)){*(int*)0 = 0;}
|
||||
# define Assert(c) assert(c)
|
||||
#else
|
||||
# define Assert(c)
|
||||
#endif
|
||||
|
|
|
@ -13,9 +13,11 @@
|
|||
|
||||
// TOP
|
||||
|
||||
#define Buffer_Init_Type cat_4tech(Buffer_Type, _Init)
|
||||
#define Buffer_Stringify_Type cat_4tech(Buffer_Type, _Stringify_Loop)
|
||||
#define Buffer_Backify_Type cat_4tech(Buffer_Type, _Backify_Loop)
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||
inline_4tech void
|
||||
buffer_stringify(Buffer_Type *buffer, int start, int end, char *out){
|
||||
for (Buffer_Stringify_Type loop = buffer_stringify_loop(buffer, start, end, end - start);
|
||||
|
@ -364,8 +366,8 @@ buffer_seek_alphanumeric_or_camel_left_end:
|
|||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_find_hard_start(Buffer_Type *buffer, int line_start, int *all_whitespace, int *all_space,
|
||||
int *preferred_indent, int tab_width){
|
||||
buffer_find_hard_start(Buffer_Type *buffer, int line_start, int *all_whitespace,
|
||||
int *all_space, int *preferred_indent, int tab_width){
|
||||
Buffer_Stringify_Type loop;
|
||||
char *data;
|
||||
int size, end;
|
||||
|
@ -403,6 +405,69 @@ buffer_find_hard_start_end:
|
|||
return(result);
|
||||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_find_string(Buffer_Type *buffer, int start_pos, char *str, int len, char *spare){
|
||||
Buffer_Stringify_Type loop;
|
||||
char *data;
|
||||
int size, end;
|
||||
int pos;
|
||||
|
||||
size = buffer_size(buffer);
|
||||
|
||||
pos = start_pos;
|
||||
if (len > 0){
|
||||
for (loop = buffer_stringify_loop(buffer, start_pos, size - len + 1, size);
|
||||
buffer_stringify_good(&loop);
|
||||
buffer_stringify_next(&loop)){
|
||||
end = loop.size + loop.absolute_pos;
|
||||
data = loop.data - loop.absolute_pos;
|
||||
for (; pos < end; ++pos){
|
||||
if (*str == data[pos]){
|
||||
buffer_stringify(buffer, pos, pos + len, spare);
|
||||
if (is_match(str, spare, len))
|
||||
goto buffer_find_string_end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buffer_find_string_end:
|
||||
if (pos >= size - len + 1) pos = size;
|
||||
return(pos);
|
||||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_rfind_string(Buffer_Type *buffer, int start_pos, char *str, int len, char *spare){
|
||||
Buffer_Backify_Type loop;
|
||||
char *data;
|
||||
int end, size;
|
||||
int pos;
|
||||
|
||||
size = buffer_size(buffer);
|
||||
|
||||
pos = start_pos;
|
||||
if (pos > size - len) pos = size - len;
|
||||
|
||||
if (len > 0){
|
||||
for (loop = buffer_backify_loop(buffer, start_pos, 0, size);
|
||||
buffer_backify_good(&loop);
|
||||
buffer_backify_next(&loop)){
|
||||
end = loop.absolute_pos;
|
||||
data = loop.data - loop.absolute_pos;
|
||||
for (; pos >= end; --pos){
|
||||
if (*str == data[pos]){
|
||||
buffer_stringify(buffer, pos, pos + len, spare);
|
||||
if (is_match(str, spare, len))
|
||||
goto buffer_rfind_string_end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buffer_rfind_string_end:
|
||||
return(pos);
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
int i;
|
||||
int count;
|
||||
|
@ -1058,6 +1123,7 @@ buffer_get_render_data_end:
|
|||
assert_4tech(item_i <= max);
|
||||
*count = item_i;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NON_ABSTRACT_4TECH
|
||||
#define NON_ABSTRACT_4TECH 1
|
||||
|
|
|
@ -24,6 +24,13 @@ typedef struct{
|
|||
int widths_max;
|
||||
} Gap_Buffer;
|
||||
|
||||
inline_4tech int
|
||||
buffer_good(Gap_Buffer *buffer){
|
||||
int good;
|
||||
good = (buffer->data != 0);
|
||||
return(good);
|
||||
}
|
||||
|
||||
inline_4tech int
|
||||
buffer_size(Gap_Buffer *buffer){
|
||||
int size;
|
||||
|
@ -31,7 +38,79 @@ buffer_size(Gap_Buffer *buffer){
|
|||
return(size);
|
||||
}
|
||||
|
||||
inline_4tech void
|
||||
typedef struct{
|
||||
Gap_Buffer *buffer;
|
||||
char *data;
|
||||
int size;
|
||||
} Gap_Buffer_Init;
|
||||
|
||||
internal_4tech Gap_Buffer_Init
|
||||
buffer_begin_init(Gap_Buffer *buffer, char *data, int size){
|
||||
Gap_Buffer_Init init;
|
||||
init.buffer = buffer;
|
||||
init.data = data;
|
||||
init.size = size;
|
||||
return(init);
|
||||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_init_need_more(Gap_Buffer_Init *init){
|
||||
int result;
|
||||
result = 1;
|
||||
if (init->buffer->data) result = 0;
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_init_page_size(Gap_Buffer_Init *init){
|
||||
int result;
|
||||
result = init->size * 2;
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal_4tech void
|
||||
buffer_init_provide_page(Gap_Buffer_Init *init, void *page, int page_size){
|
||||
Gap_Buffer *buffer;
|
||||
buffer = init->buffer;
|
||||
buffer->data = (char*)page;
|
||||
buffer->max = page_size;
|
||||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_end_init(Gap_Buffer_Init *init){
|
||||
Gap_Buffer *buffer;
|
||||
int osize1, size1, size2, size;
|
||||
int result;
|
||||
|
||||
result = 0;
|
||||
buffer = init->buffer;
|
||||
size = init->size;
|
||||
if (buffer->data){
|
||||
if (buffer->max >= init->size){
|
||||
size2 = size >> 1;
|
||||
size1 = osize1 = size - size2;
|
||||
|
||||
if (size1 > 0){
|
||||
size1 = eol_convert_in(buffer->data, init->data, size1);
|
||||
if (size2 > 0){
|
||||
size2 = eol_convert_in(buffer->data + size1, init->data + osize1, size2);
|
||||
}
|
||||
}
|
||||
|
||||
buffer->size1 = size1;
|
||||
buffer->size2 = size2;
|
||||
buffer->gap_size = buffer->max - size1 - size2;
|
||||
memmove_4tech(buffer->data + size1 + buffer->gap_size, buffer->data + size1, size2);
|
||||
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
#if 0
|
||||
internal_4tech void
|
||||
buffer_initialize(Gap_Buffer *buffer, char *data, int size){
|
||||
int osize1, size1, size2;
|
||||
|
||||
|
@ -51,6 +130,7 @@ buffer_initialize(Gap_Buffer *buffer, char *data, int size){
|
|||
buffer->gap_size = buffer->max - size1 - size2;
|
||||
memmove_4tech(buffer->data + size1 + buffer->gap_size, buffer->data + size1, size2);
|
||||
}
|
||||
#endif
|
||||
|
||||
internal_4tech void*
|
||||
buffer_relocate(Gap_Buffer *buffer, char *new_data, int new_max){
|
||||
|
|
|
@ -24,16 +24,81 @@ typedef struct{
|
|||
int widths_max;
|
||||
} Buffer;
|
||||
|
||||
inline_4tech int
|
||||
buffer_good(Buffer *buffer){
|
||||
int good;
|
||||
good = (buffer->data != 0);
|
||||
return(good);
|
||||
}
|
||||
|
||||
inline_4tech int
|
||||
buffer_size(Buffer *buffer){
|
||||
return buffer->size;
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
Buffer *buffer;
|
||||
char *data;
|
||||
int size;
|
||||
} Buffer_Init;
|
||||
|
||||
internal_4tech Buffer_Init
|
||||
buffer_begin_init(Buffer *buffer, char *data, int size){
|
||||
Buffer_Init init;
|
||||
init.buffer = buffer;
|
||||
init.data = data;
|
||||
init.size = size;
|
||||
return(init);
|
||||
}
|
||||
|
||||
inline_4tech int
|
||||
buffer_init_need_more(Buffer_Init *init){
|
||||
int result;
|
||||
result = 1;
|
||||
if (init->buffer->data) result = 0;
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline_4tech int
|
||||
buffer_init_page_size(Buffer_Init *init){
|
||||
int result;
|
||||
result = init->size * 2;
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline_4tech void
|
||||
buffer_init_provide_page(Buffer_Init *init, void *page, int page_size){
|
||||
Buffer *buffer;
|
||||
buffer = init->buffer;
|
||||
buffer->data = (char*)page;
|
||||
buffer->max = page_size;
|
||||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_end_init(Buffer_Init *init){
|
||||
Buffer *buffer;
|
||||
int result;
|
||||
|
||||
result = 0;
|
||||
buffer = init->buffer;
|
||||
if (buffer->data){
|
||||
if (buffer->max >= init->size){
|
||||
buffer->size = eol_convert_in(buffer->data, init->data, init->size);
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
#if 0
|
||||
internal_4tech void
|
||||
buffer_initialize(Buffer *buffer, char *data, int size){
|
||||
assert_4tech(buffer->data);
|
||||
assert_4tech(size <= buffer->max);
|
||||
buffer->size = eol_convert_in(buffer->data, data, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
internal_4tech void*
|
||||
buffer_relocate(Buffer *buffer, char *new_data, int new_max){
|
||||
|
@ -192,38 +257,5 @@ buffer_batch_edit_step(Buffer_Batch_State *state, Buffer *buffer, Buffer_Edit *s
|
|||
return(result);
|
||||
}
|
||||
|
||||
#if 0
|
||||
internal_4tech int
|
||||
buffer_find_hard_start(Buffer *buffer, int line_start, int *all_whitespace, int *all_space,
|
||||
int *preferred_indent, int tab_width){
|
||||
char *data;
|
||||
int size;
|
||||
int result;
|
||||
char c;
|
||||
|
||||
*all_space = 1;
|
||||
*preferred_indent = 0;
|
||||
|
||||
data = buffer->data;
|
||||
size = buffer->size;
|
||||
|
||||
tab_width -= 1;
|
||||
|
||||
for (result = line_start; result < size; ++result){
|
||||
c = data[result];
|
||||
if (c == '\n' || c == 0){
|
||||
*all_whitespace = 1;
|
||||
break;
|
||||
}
|
||||
if (c >= '!' && c <= '~') break;
|
||||
if (c == '\t') *preferred_indent += tab_width;
|
||||
if (c != ' ') *all_space = 0;
|
||||
*preferred_indent += 1;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
* Four Tech
|
||||
*
|
||||
* public domain -- no warranty is offered or implied; use this code at your own risk
|
||||
*
|
||||
* 30.10.2015
|
||||
*
|
||||
* Buffer data object
|
||||
* type - Multi Gap Buffer
|
||||
*
|
||||
* This scheme was originally introduced to me by Martin Cohen,
|
||||
* who calls it a "Fixed Width Gap Buffer".
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
typedef struct{
|
||||
char *data;
|
||||
int size1, gap_size, size2;
|
||||
int start_pos;
|
||||
} Fixed_Width_Gap_Buffer;
|
||||
|
||||
#define fixed_width_buffer_size Kbytes(8)
|
||||
#define fixed_width_buffer_half_size Kbytes(4)
|
||||
|
||||
typedef struct{
|
||||
Fixed_Width_Gap_Buffer *gaps;
|
||||
int chunk_count;
|
||||
int chunk_max;
|
||||
int size;
|
||||
} Multi_Gap_Buffer;
|
||||
|
||||
inline_4tech int
|
||||
buffer_good(Multi_Gap_Buffer *buffer){
|
||||
int good;
|
||||
good = (buffer->gaps != 0);
|
||||
return(good);
|
||||
}
|
||||
|
||||
inline_4tech int
|
||||
buffer_size(Multi_Gap_Buffer *buffer){
|
||||
int size;
|
||||
size = buffer->size;
|
||||
return(size);
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
Multi_Gap_Buffer *buffer;
|
||||
char *data;
|
||||
int size;
|
||||
int chunk_i;
|
||||
int chunk_count;
|
||||
} Multi_Gap_Buffer_Init;
|
||||
|
||||
|
||||
internal_4tech Multi_Gap_Buffer_Init
|
||||
buffer_begin_init(Multi_Gap_Buffer *buffer, char *data, int size){
|
||||
Multi_Gap_Buffer_Init init;
|
||||
init.buffer = buffer;
|
||||
init.data = data;
|
||||
init.size = size;
|
||||
init.chunk_i = 0;
|
||||
init.chunk_count = div_ceil_4tech(size, fixed_width_buffer_half_size);
|
||||
return(init);
|
||||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_init_need_more(Multi_Gap_Buffer_Init *init){
|
||||
int result;
|
||||
result = 1;
|
||||
if (init->buffer->gaps && init->chunk_i == init->chunk_count)
|
||||
result = 0;
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_init_page_size(Multi_Gap_Buffer_Init *init){
|
||||
Multi_Gap_Buffer *buffer;
|
||||
int result;
|
||||
buffer = init->buffer;
|
||||
if (buffer->gaps) result = fixed_width_buffer_size;
|
||||
else result = init->chunk_count * 2 * sizeof(*buffer->gaps);
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal_4tech void
|
||||
buffer_init_provide_page(Multi_Gap_Buffer_Init *init, void *page, int page_size){
|
||||
Multi_Gap_Buffer *buffer;
|
||||
buffer = init->buffer;
|
||||
|
||||
if (buffer->gaps){
|
||||
assert_4tech(page_size >= fixed_width_buffer_size);
|
||||
buffer->gaps[init->chunk_i].data = (char*)page;
|
||||
++init->chunk_i;
|
||||
}
|
||||
else{
|
||||
buffer->gaps = (Fixed_Width_Gap_Buffer*)page;
|
||||
buffer->chunk_max = page_size / sizeof(*buffer->gaps);
|
||||
}
|
||||
}
|
||||
|
||||
internal_4tech int
|
||||
buffer_end_init(Multi_Gap_Buffer_Init *init){
|
||||
Multi_Gap_Buffer *buffer;
|
||||
Fixed_Width_Gap_Buffer *gap;
|
||||
int result;
|
||||
int i, count;
|
||||
char *data;
|
||||
int pos, size, total_size, start_pos;
|
||||
int osize1, size1, size2;
|
||||
|
||||
result = 0;
|
||||
buffer = init->buffer;
|
||||
if (buffer->gaps){
|
||||
if (buffer->chunk_max >= div_ceil_4tech(init->size, fixed_width_buffer_half_size)){
|
||||
buffer->chunk_count = init->chunk_count;
|
||||
result = 1;
|
||||
|
||||
data = init->data;
|
||||
total_size = init->size;
|
||||
gap = buffer->gaps;
|
||||
count = init->chunk_count;
|
||||
size = fixed_width_buffer_half_size;
|
||||
pos = 0;
|
||||
start_pos = 0;
|
||||
|
||||
for (i = 0; i < count; ++i, ++gap, pos += size){
|
||||
if (pos + size > total_size) size = total_size - pos;
|
||||
|
||||
if (gap->data){
|
||||
size2 = size >> 1;
|
||||
size1 = osize1 = size - size2;
|
||||
|
||||
if (size1 > 0){
|
||||
size1 = eol_convert_in(gap->data, data + pos, size1);
|
||||
if (size2 > 0){
|
||||
size2 = eol_convert_in(gap->data + size1, data + pos + osize1, size2);
|
||||
}
|
||||
}
|
||||
|
||||
gap->size1 = size1;
|
||||
gap->size2 = size2;
|
||||
gap->gap_size = fixed_width_buffer_size - size1 - size2;
|
||||
memmove_4tech(gap->data + size1 + gap->gap_size, gap->data + size1, size2);
|
||||
|
||||
gap->start_pos = start_pos;
|
||||
start_pos += size1 + size2;
|
||||
}
|
||||
else{
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
buffer->size = start_pos;
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
@ -12,18 +12,43 @@
|
|||
|
||||
// TOP
|
||||
|
||||
#ifndef defines_4tech
|
||||
#ifndef inline_4tech
|
||||
#define inline_4tech inline
|
||||
#endif
|
||||
|
||||
#ifndef internal_4tech
|
||||
#define internal_4tech static
|
||||
#endif
|
||||
|
||||
#ifndef memset_4tech
|
||||
#define memset_4tech memset
|
||||
#endif
|
||||
|
||||
#ifndef memcpy_4tech
|
||||
#define memcpy_4tech memcpy
|
||||
#endif
|
||||
|
||||
#ifndef memmove_4tech
|
||||
#define memmove_4tech memmove
|
||||
#define defines_4tech 1
|
||||
#endif
|
||||
|
||||
#ifndef debug_4tech
|
||||
#define debug_4tech(x) x
|
||||
#endif
|
||||
|
||||
#ifndef assert_4tech
|
||||
#define assert_4tech assert
|
||||
#endif
|
||||
|
||||
#ifndef ceil_4tech
|
||||
#define ceil_4tech CEIL32
|
||||
#endif
|
||||
|
||||
#ifndef div_ceil_4tech
|
||||
#define div_ceil_4tech DIVCEIL32
|
||||
#endif
|
||||
|
||||
#ifndef cat_4tech
|
||||
#define cat_4tech_(a,b) a##b
|
||||
#define cat_4tech(a,b) cat_4tech_(a,b)
|
||||
#endif
|
||||
|
@ -397,5 +422,16 @@ is_lower(char c){
|
|||
return (c >= 'a' && c <= 'z');
|
||||
}
|
||||
|
||||
internal_4tech int
|
||||
is_match(char *a, char *b, int len){
|
||||
int result;
|
||||
|
||||
result = 1;
|
||||
for (;len > 0; --len, ++a, ++b)
|
||||
if (*a != *b) { result = 0; break; }
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
|
@ -13,24 +13,28 @@
|
|||
// Fix the OwnDC thing.
|
||||
//
|
||||
|
||||
#ifdef FRED_NOT_PACKAGE
|
||||
|
||||
#define FRED_INTERNAL 1
|
||||
#define FRED_SLOW 1
|
||||
|
||||
#define FRED_PRINT_DEBUG 1
|
||||
#define FRED_PRINT_DEBUG_FILE_LINE 0
|
||||
#define FRED_PROFILING 1
|
||||
#define FRED_PROFILING_OS 0
|
||||
#define FRED_FULL_ERRORS 0
|
||||
|
||||
#ifndef FRED_SLOW
|
||||
#define FRED_SLOW 0
|
||||
#else
|
||||
#undef FRED_SLOW
|
||||
#define FRED_SLOW 1
|
||||
#endif
|
||||
|
||||
#ifndef FRED_INTERNAL
|
||||
#define FRED_SLOW 0
|
||||
#define FRED_INTERNAL 0
|
||||
#else
|
||||
#undef FRED_INTERNAL
|
||||
#define FRED_INTERNAL 1
|
||||
|
||||
#define FRED_PRINT_DEBUG 0
|
||||
#define FRED_PRINT_DEBUG_FILE_LINE 0
|
||||
#define FRED_PROFILING 0
|
||||
#define FRED_PROFILING_OS 0
|
||||
#define FRED_FULL_ERRORS 0
|
||||
|
||||
#endif
|
||||
|
||||
#define SOFTWARE_RENDER 0
|
||||
|
@ -54,7 +58,7 @@
|
|||
#define FPS 30
|
||||
#define FRAME_TIME (1000000 / FPS)
|
||||
|
||||
#define BUFFER_EXPERIMENT_SCALPEL 0
|
||||
#define BUFFER_EXPERIMENT_SCALPEL 2
|
||||
|
||||
#include "4ed_meta.h"
|
||||
|
||||
|
|
Loading…
Reference in New Issue