work on mugab edits

This commit is contained in:
Allen Webster 2015-11-02 19:43:36 -05:00
parent a89b46fda7
commit 60dab2731c
11 changed files with 797 additions and 382 deletions

View File

@ -236,7 +236,7 @@ extern "C" GET_BINDING_DATA(get_bindings){
bind(context, codes->down, MDFR_ALT, cmdid_stop_rewind_fastforward);
bind(context, 'h', MDFR_CTRL, cmdid_history_backward);
bind(context, 'H', MDFR_CTRL, cmdid_history_forward);
bind(context, 'd', MDFR_CTRL, cmdid_delete_chunk);
bind(context, 'd', MDFR_CTRL, cmdid_delete_range);
bind(context, 'l', MDFR_CTRL, cmdid_toggle_line_wrap);
bind(context, 'L', MDFR_CTRL, cmdid_toggle_endline_mode);
bind(context, 'u', MDFR_CTRL, cmdid_to_uppercase);

View File

@ -69,7 +69,7 @@ enum Command_ID{
cmdid_cut,
cmdid_paste,
cmdid_paste_next,
cmdid_delete_chunk,
cmdid_delete_range,
cmdid_timeline_scrub,
cmdid_undo,
cmdid_redo,

155
4ed.cpp
View File

@ -135,6 +135,8 @@ 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_OPEN_FILE_VIEW(n) File_View *n = view_to_file_view(command->view); if (!n || n->locked) return
#define REQ_FILE_HISTORY(n,v) Editing_File *n = (v)->file; if (!n || !buffer_good(&n->buffer) || n->is_dummy || !n->undo.undo.edits) 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
@ -206,7 +208,7 @@ COMMAND_DECL(null){
COMMAND_DECL(write_character){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_OPEN_FILE_VIEW(view);
REQ_FILE(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
@ -223,7 +225,7 @@ COMMAND_DECL(write_character){
view_replace_range(mem, view, layout, pos, pos, (u8*)string.str, string.size, next_cursor_pos);
view_cursor_move(view, next_cursor_pos);
if (view->mark >= pos) view->mark += string.size;
view->file->cursor_pos = view->cursor.pos;
file->cursor_pos = view->cursor.pos;
}
COMMAND_DECL(seek_whitespace_right){
@ -233,7 +235,6 @@ COMMAND_DECL(seek_whitespace_right){
REQ_FILE(file, view);
i32 pos = buffer_seek_whitespace_right(&file->buffer, view->cursor.pos);
view_cursor_move(view, pos);
#endif
}
@ -245,7 +246,6 @@ COMMAND_DECL(seek_whitespace_left){
REQ_FILE(file, view);
i32 pos = buffer_seek_whitespace_left(&file->buffer, view->cursor.pos);
view_cursor_move(view, pos);
#endif
}
@ -356,7 +356,7 @@ COMMAND_DECL(seek_white_or_token_left){
}
COMMAND_DECL(seek_alphanumeric_right){
#if BUFFER_EXPERIMENT_SCALPEL <= 1
#if BUFFER_EXPERIMENT_SCALPEL <= 2
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -367,7 +367,7 @@ COMMAND_DECL(seek_alphanumeric_right){
}
COMMAND_DECL(seek_alphanumeric_left){
#if BUFFER_EXPERIMENT_SCALPEL <= 1
#if BUFFER_EXPERIMENT_SCALPEL <= 2
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -378,7 +378,7 @@ COMMAND_DECL(seek_alphanumeric_left){
}
COMMAND_DECL(seek_alphanumeric_or_camel_right){
#if BUFFER_EXPERIMENT_SCALPEL <= 1
#if BUFFER_EXPERIMENT_SCALPEL <= 2
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -390,7 +390,7 @@ COMMAND_DECL(seek_alphanumeric_or_camel_right){
}
COMMAND_DECL(seek_alphanumeric_or_camel_left){
#if BUFFER_EXPERIMENT_SCALPEL <= 1
#if BUFFER_EXPERIMENT_SCALPEL <= 2
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -404,7 +404,7 @@ COMMAND_DECL(seek_alphanumeric_or_camel_left){
COMMAND_DECL(search){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
REQ_FILE(fixed, view);
USE_VARS(vars);
view_set_widget(view, FWIDG_SEARCH);
@ -416,7 +416,7 @@ COMMAND_DECL(search){
COMMAND_DECL(rsearch){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
REQ_FILE(fixed, view);
USE_VARS(vars);
view_set_widget(view, FWIDG_SEARCH);
@ -428,7 +428,7 @@ COMMAND_DECL(rsearch){
COMMAND_DECL(goto_line){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
REQ_FILE(fixed, view);
USE_VARS(vars);
view_set_widget(view, FWIDG_GOTO_LINE);
@ -460,7 +460,7 @@ COMMAND_DECL(copy){
COMMAND_DECL(cut){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_OPEN_FILE_VIEW(view);
REQ_FILE(file, view);
USE_WORKING_SET(working_set);
USE_LAYOUT(layout);
@ -481,7 +481,7 @@ COMMAND_DECL(cut){
COMMAND_DECL(paste){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_OPEN_FILE_VIEW(view);
REQ_FILE(file, view);
USE_WORKING_SET(working_set);
USE_LAYOUT(layout);
@ -516,7 +516,7 @@ COMMAND_DECL(paste){
COMMAND_DECL(paste_next){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_OPEN_FILE_VIEW(view);
REQ_FILE(file, view);
USE_WORKING_SET(working_set);
USE_LAYOUT(layout);
@ -552,9 +552,9 @@ COMMAND_DECL(paste_next){
}
}
COMMAND_DECL(delete_chunk){
COMMAND_DECL(delete_range){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_OPEN_FILE_VIEW(view);
REQ_FILE(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
@ -572,7 +572,7 @@ COMMAND_DECL(delete_chunk){
COMMAND_DECL(timeline_scrub){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
REQ_FILE_HISTORY(file, view);
view_set_widget(view, FWIDG_TIMELINES);
view->widget.timeline.undo_line = 1;
@ -582,6 +582,7 @@ COMMAND_DECL(timeline_scrub){
COMMAND_DECL(undo){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE_HISTORY(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
@ -591,6 +592,7 @@ COMMAND_DECL(undo){
COMMAND_DECL(redo){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE_HISTORY(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
@ -600,6 +602,7 @@ COMMAND_DECL(redo){
COMMAND_DECL(increase_rewind_speed){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE_HISTORY(file, view);
i32 rewind_speed = ROUND32(view->rewind_speed * 4.f);
if (rewind_speed > 1) rewind_speed >>= 1;
@ -613,6 +616,7 @@ COMMAND_DECL(increase_rewind_speed){
COMMAND_DECL(increase_fastforward_speed){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE_HISTORY(file, view);
i32 neg_rewind_speed = -ROUND32(view->rewind_speed * 4.f);
if (neg_rewind_speed > 1) neg_rewind_speed >>= 1;
@ -626,6 +630,7 @@ COMMAND_DECL(increase_fastforward_speed){
COMMAND_DECL(stop_rewind_fastforward){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE_HISTORY(file, view);
view->rewind_speed = 0;
}
@ -633,7 +638,7 @@ COMMAND_DECL(stop_rewind_fastforward){
COMMAND_DECL(history_backward){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
REQ_FILE_HISTORY(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
@ -643,7 +648,7 @@ COMMAND_DECL(history_backward){
COMMAND_DECL(history_forward){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
REQ_FILE_HISTORY(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
@ -698,7 +703,7 @@ app_open_file(App_Vars *vars, General_Memory *general, Panel *panel,
view_replace_major(new_view, panel, live_set);
File_View *file_view = file_view_init(new_view, &vars->delay, &vars->layout);
File_View *file_view = file_view_init(new_view, &vars->layout);
result = file_view;
View *old_view = command_data->view;
@ -830,7 +835,7 @@ COMMAND_DECL(save){
String *file_path = &file->source_path;
if (file_path->size > 0){
file_save(&mem->part, file, (u8*)file_path->str);
file_save(&mem->part, file, file_path->str);
}
}
@ -1219,7 +1224,6 @@ COMMAND_DECL(move_left){
i32 pos = view->cursor.pos;
if (pos > 0) --pos;
view_cursor_move(view, pos);
}
@ -1231,13 +1235,12 @@ COMMAND_DECL(move_right){
i32 size = buffer_size(&file->buffer);
i32 pos = view->cursor.pos;
if (pos < size) ++pos;
view_cursor_move(view, pos);
}
COMMAND_DECL(delete){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_OPEN_FILE_VIEW(view);
REQ_FILE(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
@ -1261,7 +1264,7 @@ COMMAND_DECL(delete){
COMMAND_DECL(backspace){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_OPEN_FILE_VIEW(view);
REQ_FILE(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
@ -1292,7 +1295,7 @@ COMMAND_DECL(move_up){
real32 px = view->preferred_x;
if (cy >= 0){
view->cursor = view_compute_cursor_from_xy(view, px, cy);
view->file->cursor_pos = view->cursor.pos;
file->cursor_pos = view->cursor.pos;
}
}
@ -1304,7 +1307,7 @@ COMMAND_DECL(move_down){
real32 cy = view_get_cursor_y(view)+view->style->font->height;
real32 px = view->preferred_x;
view->cursor = view_compute_cursor_from_xy(view, px, cy);
view->file->cursor_pos = view->cursor.pos;
file->cursor_pos = view->cursor.pos;
}
COMMAND_DECL(seek_end_of_line){
@ -1539,27 +1542,47 @@ COMMAND_DECL(build){
USE_LIVE_SET(live_set);
USE_PANEL(panel);
char *buffer_name = "*cli process*";
char *path = "..\\misc";
char *script = "test";
if (vars->cli_processes.count < vars->cli_processes.max){
Get_File_Result file = working_set_get_available_file(working_set);
if (file.file){
file_create_empty(&mem->general, file.file, (u8*)"*cli process*", style->font);
table_add(&working_set->table, file.file->source_path, file.index);
Editing_File *file = working_set_contains(working_set, make_string_slowly(buffer_name));
i32 index;
if (!file){
Get_File_Result get_file = working_set_get_available_file(working_set);
file = get_file.file;
index = get_file.index;
}
else{
i32 proc_count = vars->cli_processes.count;
for (i32 i = 0; i < proc_count; ++i){
if (vars->cli_processes.procs[i].out_file == file){
vars->cli_processes.procs[i].out_file = 0;
}
}
index = (int)(file - vars->working_set.files);
}
if (file){
file_create_super_locked(&mem->general, file, (u8*)buffer_name, style->font);
table_add(&working_set->table, file->live_name, index);
View *new_view = live_set_alloc_view(live_set, mem);
view_replace_major(new_view, panel, live_set);
File_View *file_view = file_view_init(new_view, &vars->delay, &vars->layout);
view_set_file(file_view, file.file, style,
File_View *file_view = file_view_init(new_view, &vars->layout);
view_set_file(file_view, file, style,
vars->hooks[hook_open_file], command, app_links);
file.file->tokens_exist = 0;
new_view->map = app_get_map(vars, file.file->base_map_id);
new_view->map = app_get_map(vars, file->base_map_id);
i32 i = vars->cli_processes.count++;
CLI_Process *proc = vars->cli_processes.procs + i;
if (!system_cli_call("..\\misc", "build_all_test", &proc->cli)){
if (!system_cli_call(path, script, &proc->cli)){
--vars->cli_processes.count;
}
proc->out_file = file.file;
proc->out_file = file;
}
else{
// TODO(allen): feedback message - no available file
@ -1608,25 +1631,6 @@ extern "C"{
if (function) function(cmd, binding);
update_command_data(cmd->vars, cmd);
#if 0
App_Vars *vars = cmd->vars;
Command_Data command_data;
command_data.vars = vars;
command_data.mem = &vars->mem;
command_data.working_set = &vars->working_set;
command_data.layout = &vars->layout;
command_data.panel = command_data.layout->panels + command_data.layout->active_panel;
command_data.view = command_data.panel->view;
command_data.live_set = &vars->live_set;
command_data.style = &vars->style;
command_data.delay = &vars->delay;
command_data.screen_width = cmd->screen_width;
command_data.screen_height = cmd->screen_height;
command_data.key = cmd->key;
command_data.part = cmd->part;
*cmd = command_data;
#endif
}
PUSH_PARAMETER_SIG(external_push_parameter){
@ -1755,7 +1759,7 @@ setup_file_commands(Command_Map *commands, Partition *part, Key_Codes *codes, Co
map_add(commands, codes->down, MDFR_ALT, command_stop_rewind_fastforward);
map_add(commands, 'h', MDFR_CTRL, command_history_backward);
map_add(commands, 'H', MDFR_CTRL, command_history_forward);
map_add(commands, 'd', MDFR_CTRL, command_delete_chunk);
map_add(commands, 'd', MDFR_CTRL, command_delete_range);
map_add(commands, 'l', MDFR_CTRL, command_toggle_line_wrap);
map_add(commands, '?', MDFR_CTRL, command_toggle_show_whitespace);
map_add(commands, '|', MDFR_CTRL, command_toggle_tokens);
@ -1830,7 +1834,7 @@ setup_command_table(){
SET(cut);
SET(paste);
SET(paste_next);
SET(delete_chunk);
SET(delete_range);
SET(timeline_scrub);
SET(undo);
SET(redo);
@ -1998,7 +2002,6 @@ app_hardcode_styles(App_Vars *vars){
style->main.paste_color = 0xFFDDEE00;
style->main.undo_color = 0xFF00DDEE;
style->main.next_undo_color = 0xFF006E77;
style->main.highlight_junk_color = 0xff3a0000;
style->main.highlight_white_color = 0xff003a3a;
@ -2086,7 +2089,6 @@ app_hardcode_styles(App_Vars *vars){
style->main.paste_color = 0xFFDDEE00;
style->main.undo_color = 0xFF00DDEE;
style->main.next_undo_color = 0xFF006E77;
style->main.highlight_junk_color = 0xff3a0000;
style->main.highlight_white_color = 0xFF151F2A;
@ -2127,7 +2129,6 @@ app_hardcode_styles(App_Vars *vars){
style->main.paste_color = 0xFF900090;
style->main.undo_color = 0xFF606090;
style->main.next_undo_color = 0xFF404070;
style->main.highlight_junk_color = 0xff3a0000;
style->main.highlight_white_color = 0xff003a3a;
@ -2168,7 +2169,6 @@ app_hardcode_styles(App_Vars *vars){
style->main.paste_color = 0xFF00B8B8;
style->main.undo_color = 0xFFB800B8;
style->main.next_undo_color = 0xFF5C005C;
style->main.highlight_junk_color = 0xFFFF7878;
style->main.highlight_white_color = 0xFFBCBCBC;
@ -2592,7 +2592,7 @@ app_step(Thread_Context *thread, Key_Codes *codes,
}
// NOTE(allen): update child processes
{
if (time_step){
Temp_Memory temp = begin_temp_memory(&vars->mem.part);
u32 max = Kbytes(32);
char *dest = push_array(&vars->mem.part, char, max);
@ -2627,6 +2627,17 @@ app_step(Thread_Context *thread, Key_Codes *codes,
*proc = vars->cli_processes.procs[--count];
--i;
}
Panel *panel = vars->layout.panels;
i32 panel_count = vars->layout.panel_count;
for (i32 i = 0; i < panel_count; ++i, ++panel){
View *view = panel->view;
if (view && view->is_minor) view = view->major;
File_View *fview = view_to_file_view(view);
if (fview){
view_cursor_move(fview, new_cursor);
}
}
}
vars->cli_processes.count = count;
@ -3043,7 +3054,7 @@ app_step(Thread_Context *thread, Key_Codes *codes,
if (fview){
Editing_File *file = fview->file;
if (file && !file->is_dummy){
file_save_and_set_names(&vars->mem.part, file, (u8*)string->str);
file_save_and_set_names(&vars->mem.part, file, string->str);
}
}
}break;
@ -3051,8 +3062,8 @@ app_step(Thread_Context *thread, Key_Codes *codes,
case DACT_SAVE:
{
Editing_File *file = working_set_lookup_file(working_set, *string);
if (file && !file->is_dummy){
file_save(&vars->mem.part, file, (u8*)file->source_path.str);
if (!file->is_dummy){
file_save(&vars->mem.part, file, file->source_path.str);
}
}break;
@ -3065,7 +3076,7 @@ app_step(Thread_Context *thread, Key_Codes *codes,
View *new_view = live_set_alloc_view(live_set, mem);
view_replace_major(new_view, panel, live_set);
File_View *file_view = file_view_init(new_view, &vars->delay, &vars->layout);
File_View *file_view = file_view_init(new_view, &vars->layout);
command_data.view = (View*)file_view;
view_set_file(file_view, file.file, style,
vars->hooks[hook_open_file], &command_data, app_links);
@ -3082,10 +3093,12 @@ app_step(Thread_Context *thread, Key_Codes *codes,
View *new_view = live_set_alloc_view(live_set, mem);
view_replace_major(new_view, panel, live_set);
File_View *file_view = file_view_init(new_view, &vars->delay, &vars->layout);
File_View *file_view = file_view_init(new_view, &vars->layout);
command_data.view = (View*)file_view;
view_set_file(file_view, file, style,
vars->hooks[hook_open_file], &command_data, app_links);
new_view->map = app_get_map(vars, file->base_map_id);
}
}break;
@ -3095,7 +3108,7 @@ app_step(Thread_Context *thread, Key_Codes *codes,
Editing_File *file = working_set_lookup_file(working_set, *string);
if (file){
table_remove(&working_set->table, file->source_path);
kill_buffer(general, file, live_set, &vars->layout);
kill_file(general, file, live_set, &vars->layout);
}
}break;
@ -3108,7 +3121,7 @@ app_step(Thread_Context *thread, Key_Codes *codes,
case SYNC_GOOD:
{
table_remove(&working_set->table, file->source_path);
kill_buffer(general, file, live_set, &vars->layout);
kill_file(general, file, live_set, &vars->layout);
view_remove_minor(panel, live_set);
}break;
@ -3186,7 +3199,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 (buffer_good(&file->buffer) && !file->is_dummy){
file_measure_widths(&vars->mem.general, file, vars->style.font);
file_measure_widths(&vars->mem.general, &file->buffer, vars->style.font);
}
}

View File

@ -84,28 +84,28 @@ struct Undo_Data{
struct Editing_File{
Buffer_Type buffer;
Undo_Data undo;
Font *font;
i32 cursor_pos;
b32 is_dummy;
char live_name_[256];
String live_name;
i32 base_map_id;
char source_path_[256];
char live_name_[256];
char extension_[16];
String source_path;
String live_name;
String extension;
Undo_Data undo;
b32 super_locked;
Cpp_Token_Stack token_stack;
b32 tokens_complete;
b32 tokens_exist;
b32 still_lexing;
u32 lex_job;
i32 base_map_id;
i32 dos_write_mode;
u64 last_4ed_write_time;
@ -116,7 +116,7 @@ struct Editing_File{
struct File_Table_Entry{
String name;
u32 hash;
i32 index;
i32 id;
};
struct File_Table{
@ -136,15 +136,15 @@ get_file_hash(String name){
return x;
}
internal bool32
table_add(File_Table *table, String name, i32 index){
internal b32
table_add(File_Table *table, String name, i32 id){
Assert(table->count * 3 < table->max * 2);
File_Table_Entry entry, e;
i32 i;
entry.name = name;
entry.index = index;
entry.id = id;
entry.hash = get_file_hash(name);
i = entry.hash % table->max;
while ((e = table->table[i]).name.str){
@ -178,18 +178,18 @@ table_find_pos(File_Table *table, String name, i32 *index){
return 0;
}
inline bool32
table_find(File_Table *table, String name, i32 *index){
inline b32
table_find(File_Table *table, String name, i32 *id){
i32 pos;
bool32 r = table_find_pos(table, name, &pos);
if (r) *index = table->table[pos].index;
b32 r = table_find_pos(table, name, &pos);
if (r) *id = table->table[pos].id;
return r;
}
inline bool32
inline b32
table_remove(File_Table *table, String name){
i32 pos;
bool32 r = table_find_pos(table, name, &pos);
b32 r = table_find_pos(table, name, &pos);
if (r){
table->table[pos].name.str = 0;
--table->count;
@ -1021,23 +1021,37 @@ struct File_View_Widget{
} timeline;
};
enum Link_Type{
link_result,
link_related,
link_error,
link_warning,
// never below this
link_type_count
};
struct Hyper_Link{
char *file_name;
i32 line_number;
i32 start, end;
Link_Type link_type;
};
struct File_View{
View view_base;
Delay *delay;
Editing_Layout *layout;
Editing_File *file;
Style *style;
Editing_Layout *layout;
i32 font_advance;
i32 font_height;
Full_Cursor cursor;
i32 mark;
real32 scroll_y, target_y, vel_y;
real32 scroll_x, target_x, vel_x;
real32 preferred_x;
f32 scroll_y, target_y, vel_y;
f32 scroll_x, target_x, vel_x;
f32 preferred_x;
Full_Cursor scroll_y_cursor;
union{
Incremental_Search isearch;
@ -1048,19 +1062,23 @@ struct File_View{
Full_Cursor temp_highlight;
i32 temp_highlight_end_pos;
bool32 show_temp_highlight;
b32 show_temp_highlight;
File_View_Mode mode, next_mode;
File_View_Widget widget;
real32 rewind_amount, rewind_speed;
f32 rewind_amount, rewind_speed;
i32 rewind_max, scrub_max;
bool32 unwrapped_lines;
bool32 show_whitespace;
b32 unwrapped_lines;
b32 show_whitespace;
b32 locked;
i32 line_count, line_max;
real32 *line_wrap_y;
f32 *line_wrap_y;
Text_Effect paste_effect;
Hyper_Link *links;
i32 link_count, link_max;
};
inline File_View*
@ -1099,15 +1117,20 @@ file_init_strings(Editing_File *file){
}
inline void
file_set_name(Editing_File *file, u8 *filename){
String f, ext;
f = make_string_slowly((char*)filename);
copy_checked(&file->source_path, f);
file_set_name(Editing_File *file, char *filename){
file->live_name = make_fixed_width_string(file->live_name_);
if (filename[0] == '*'){
copy(&file->live_name, filename);
}
else{
String f, ext;
f = make_string_slowly(filename);
copy_checked(&file->source_path, f);
get_front_of_directory(&file->live_name, f);
ext = file_extension(f);
copy(&file->extension, ext);
}
}
inline void
file_synchronize_times(Editing_File *file, u8 *filename){
@ -1119,32 +1142,32 @@ 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
internal b32
file_save(Partition *part, Editing_File *file, char *filename){
b32 result = 0;
#if BUFFER_EXPERIMENT_SCALPEL <= 2
Temp_Memory temp = begin_temp_memory(part);
i32 max = partition_remaining(part);
if (file->dos_write_mode){
char *data = push_array(part, char, max);
i32 size = buffer_convert_out(&file->buffer, data, max);
result = system_save_file(filename, data, size);
result = system_save_file((u8*)filename, data, size);
}
else{
char *data = push_array(part, char, max);
i32 size = buffer_size(&file->buffer);
Assert(size <= max);
buffer_stringify(&file->buffer, 0, size, data);
result = system_save_file(filename, data, size);
result = system_save_file((u8*)filename, data, size);
}
end_temp_memory(temp);
file_synchronize_times(file, filename);
file_synchronize_times(file, (u8*)filename);
#endif
return result;
}
inline bool32
file_save_and_set_names(Partition *part, Editing_File *file, u8 *filename){
file_save_and_set_names(Partition *part, Editing_File *file, char *filename){
bool32 result = 0;
if (file_save(part, file, filename)){
result = 1;
@ -1153,16 +1176,6 @@ file_save_and_set_names(Partition *part, Editing_File *file, u8 *filename){
return result;
}
inline i32
file_count_newlines(Editing_File *file, i32 start, i32 end){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
i32 count = buffer_count_newlines(&file->buffer, start, end);
#else
i32 count = 0;
#endif
return count;
}
enum File_Bubble_Type{
BUBBLE_BUFFER = 1,
BUBBLE_STARTS,
@ -1181,20 +1194,20 @@ enum File_Bubble_Type{
#define GROW_SUCCESS 2
internal i32
file_grow_starts_as_needed(General_Memory *general, Editing_File *file, i32 additional_lines){
file_grow_starts_as_needed(General_Memory *general, Buffer_Type *buffer, i32 additional_lines){
bool32 result = GROW_NOT_NEEDED;
#if BUFFER_EXPERIMENT_SCALPEL <= 2
i32 max = file->buffer.line_max;
i32 count = file->buffer.line_count;
i32 max = buffer->line_max;
i32 count = buffer->line_count;
i32 target_lines = count + additional_lines;
if (target_lines > max || max == 0){
max = LargeRoundUp(target_lines + max, Kbytes(1));
i32 *new_lines = (i32*)
general_memory_reallocate(general, file->buffer.line_starts,
general_memory_reallocate(general, buffer->line_starts,
sizeof(i32)*count, sizeof(i32)*max, BUBBLE_STARTS);
if (new_lines){
file->buffer.line_starts = new_lines;
file->buffer.line_max = max;
buffer->line_starts = new_lines;
buffer->line_max = max;
result = GROW_SUCCESS;
}
else{
@ -1206,47 +1219,45 @@ file_grow_starts_as_needed(General_Memory *general, Editing_File *file, i32 addi
}
internal void
file_measure_starts(General_Memory *general, Editing_File *file){
file_measure_starts(General_Memory *general, Buffer_Type *buffer){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
ProfileMomentFunction();
if (!file->buffer.line_starts){
i32 max = file->buffer.line_max = Kbytes(1);
file->buffer.line_starts = (i32*)general_memory_allocate(general, max*sizeof(i32), BUBBLE_STARTS);
TentativeAssert(file->buffer.line_starts);
if (!buffer->line_starts){
i32 max = buffer->line_max = Kbytes(1);
buffer->line_starts = (i32*)general_memory_allocate(general, max*sizeof(i32), BUBBLE_STARTS);
TentativeAssert(buffer->line_starts);
// TODO(allen): when unable to allocate?
}
Buffer_Measure_Starts state = {};
while (buffer_measure_starts(&state, &file->buffer)){
i32 max = file->buffer.line_max;
while (buffer_measure_starts(&state, buffer)){
i32 max = buffer->line_max;
i32 count = state.count;
i32 target_lines = count + 1;
max = (target_lines << 1);
i32 *new_lines = (i32*)
general_memory_reallocate(general, file->buffer.line_starts,
general_memory_reallocate(general, buffer->line_starts,
sizeof(i32)*count, sizeof(i32)*max, BUBBLE_STARTS);
// TODO(allen): when unable to grow?
TentativeAssert(new_lines);
file->buffer.line_starts = new_lines;
file->buffer.line_max = max;
buffer->line_starts = new_lines;
buffer->line_max = max;
}
file->buffer.line_count = state.count;
buffer->line_count = state.count;
#endif
}
internal void
file_remeasure_starts(General_Memory *general, Editing_File *file,
file_remeasure_starts(General_Memory *general, Buffer_Type *buffer,
i32 line_start, i32 line_end, i32 line_shift,
i32 character_shift){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
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);
Assert(buffer->line_starts);
file_grow_starts_as_needed(general, buffer, line_shift);
buffer_remeasure_starts(buffer, line_start, line_end, line_shift, character_shift);
#endif
}
@ -1264,47 +1275,44 @@ get_opaque_font_advance(Font *font){
}
internal void
file_grow_widths_as_needed(General_Memory *general, Editing_File *file){
file_grow_widths_as_needed(General_Memory *general, Buffer_Type *buffer){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
i32 line_count = file->buffer.line_count;
if (line_count > file->buffer.widths_max || file->buffer.widths_max == 0){
i32 line_count = buffer->line_count;
if (line_count > buffer->widths_max || buffer->widths_max == 0){
i32 new_max = LargeRoundUp(line_count, Kbytes(1));
if (new_max < Kbytes(1)) new_max = Kbytes(1);
if (file->buffer.line_widths){
file->buffer.line_widths = (f32*)
general_memory_reallocate(general, file->buffer.line_widths,
sizeof(f32)*file->buffer.widths_count, sizeof(f32)*new_max, BUBBLE_WIDTHS);
if (buffer->line_widths){
buffer->line_widths = (f32*)
general_memory_reallocate(general, buffer->line_widths,
sizeof(f32)*buffer->widths_count, sizeof(f32)*new_max, BUBBLE_WIDTHS);
}
else{
file->buffer.line_widths = (f32*)
buffer->line_widths = (f32*)
general_memory_allocate(general, sizeof(f32)*new_max, BUBBLE_WIDTHS);
}
file->buffer.widths_max = new_max;
buffer->widths_max = new_max;
}
#endif
}
internal void
file_measure_widths(General_Memory *general, Editing_File *file, Font *font){
file_measure_widths(General_Memory *general, Buffer_Type *buffer, Font *font){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
ProfileMomentFunction();
file_grow_widths_as_needed(general, file);
file_grow_widths_as_needed(general, buffer);
Opaque_Font_Advance opad = get_opaque_font_advance(font);
buffer_measure_widths(&file->buffer, opad.data, opad.stride);
buffer_measure_widths(buffer, opad.data, opad.stride);
#endif
}
internal void
file_remeasure_widths(General_Memory *general, Editing_File *file, Font *font,
file_remeasure_widths(General_Memory *general, Buffer_Type *buffer, Font *font,
i32 line_start, i32 line_end, i32 line_shift){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
ProfileMomentFunction();
file_grow_widths_as_needed(general, file);
file_grow_widths_as_needed(general, buffer);
Opaque_Font_Advance opad = get_opaque_font_advance(font);
buffer_remeasure_widths(&file->buffer, opad.data, opad.stride,
line_start, line_end, line_shift);
buffer_remeasure_widths(buffer, opad.data, opad.stride, line_start, line_end, line_shift);
#endif
}
@ -1325,15 +1333,15 @@ view_compute_lowest_line(File_View *view){
lowest_line = last_line;
}
else{
real32 wrap_y = view->line_wrap_y[last_line];
Editing_File *file = view->file;
Assert(!file->is_dummy);
Style *style = view->style;
Font *font = style->font;
real32 wrap_y = view->line_wrap_y[last_line];
lowest_line = FLOOR32(wrap_y / font->height);
f32 max_width = view_compute_width(view);
real32 width = file->buffer.line_widths[last_line];
real32 max_width = view_compute_width(view);
Editing_File *file = view->file;
Assert(!file->is_dummy);
f32 width = file->buffer.line_widths[last_line];
i32 line_span = view_wrapped_line_span(width, max_width);
lowest_line += line_span - 1;
}
@ -1346,8 +1354,10 @@ internal void
view_measure_wraps(General_Memory *general, File_View *view){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
ProfileMomentFunction();
Editing_File *file = view->file;
i32 line_count = file->buffer.line_count;
Buffer_Type *buffer;
buffer = &view->file->buffer;
i32 line_count = buffer->line_count;
if (view->line_max < line_count){
i32 max = view->line_max = LargeRoundUp(line_count, Kbytes(1));
@ -1364,7 +1374,7 @@ view_measure_wraps(General_Memory *general, File_View *view){
Font *font = view->style->font;
real32 line_height = (real32)font->height;
real32 max_width = view_compute_width(view);
buffer_measure_wrap_y(&file->buffer, view->line_wrap_y, line_height, max_width);
buffer_measure_wrap_y(buffer, view->line_wrap_y, line_height, max_width);
view->line_count = line_count;
#endif
@ -1378,7 +1388,7 @@ alloc_for_buffer(void *context, int *size){
}
internal void
file_create_from_string(General_Memory *general, Editing_File *file, u8 *filename, Font *font, String val){
file_create_from_string(General_Memory *general, Editing_File *file, u8 *filename, Font *font, String val, b32 super_locked = 0){
*file = {};
#if BUFFER_EXPERIMENT_SCALPEL <= 2
Buffer_Init_Type init = buffer_begin_init(&file->buffer, val.str, val.size);
@ -1393,16 +1403,19 @@ file_create_from_string(General_Memory *general, Editing_File *file, u8 *filenam
Assert(init_success);
#endif
file_synchronize_times(file, filename);
file_init_strings(file);
file_set_name(file, filename);
file_set_name(file, (char*)filename);
file->base_map_id = mapid_file;
file_measure_starts(general, file);
file_measure_widths(general, file, font);
file->font = font;
file_synchronize_times(file, filename);
file_measure_starts(general, &file->buffer);
file_measure_widths(general, &file->buffer, font);
file->super_locked = super_locked;
if (!super_locked){
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);
@ -1428,6 +1441,7 @@ file_create_from_string(General_Memory *general, Editing_File *file, u8 *filenam
file->undo.history_head_block = 0;
file->undo.current_block_normal = 1;
}
}
internal bool32
file_create(General_Memory *general, Editing_File *file, u8 *filename, Font *font){
@ -1444,13 +1458,19 @@ file_create(General_Memory *general, Editing_File *file, u8 *filename, Font *fon
return result;
}
internal bool32
internal b32
file_create_empty(General_Memory *general, Editing_File *file, u8 *filename, Font *font){
bool32 result = 1;
b32 result = 1;
String empty_str = {};
file_create_from_string(general, file, filename, font, empty_str);
return result;
}
internal b32
file_create_super_locked(General_Memory *general, Editing_File *file, u8 *filename, Font *font){
b32 result = 1;
String empty_str = {};
file_create_from_string(general, file, filename, font, empty_str, 1);
return result;
}
@ -1487,14 +1507,19 @@ 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);
Buffer_Type *buffer = &file->buffer;
if (buffer->data){
general_memory_free(general, buffer->data);
general_memory_free(general, buffer->line_starts);
general_memory_free(general, buffer->line_widths);
}
#elif BUFFER_EXPERIMENT_SCALPEL == 2
// TODO
#endif
if (file->undo.undo.edits){
general_memory_free(general, file->undo.undo.strings);
general_memory_free(general, file->undo.undo.edits);
@ -1504,8 +1529,9 @@ file_close(General_Memory *general, Editing_File *file){
general_memory_free(general, file->undo.history.strings);
general_memory_free(general, file->undo.history.edits);
}
}
internal void
inline void
file_get_dummy(Editing_File *file){
*file = {};
file->is_dummy = 1;
@ -2101,9 +2127,9 @@ view_set_file(File_View *view, Editing_File *file, Style *style,
Custom_Command_Function *open_hook, void *cmd_context, Application_Links app){
Panel *panel = view->view_base.panel;
view->file = file;
view->locked = file->super_locked;
General_Memory *general = &view->view_base.mem->general;
AllowLocal(general);
Font *font = style->font;
view->style = style;
view->font_advance = font->advance;
@ -2114,25 +2140,25 @@ view_set_file(File_View *view, Editing_File *file, Style *style,
view->cursor = {};
view->cursor = view_compute_cursor_from_pos(view, file->cursor_pos);
real32 cursor_x, cursor_y;
real32 w, h;
real32 target_x, target_y;
f32 cursor_x, cursor_y;
f32 w, h;
f32 target_x, target_y;
cursor_x = view_get_cursor_x(view);
cursor_y = view_get_cursor_y(view);
w = (real32)(panel->inner.x1 - panel->inner.x0);
h = (real32)(panel->inner.y1 - panel->inner.y0);
w = (f32)(panel->inner.x1 - panel->inner.x0);
h = (f32)(panel->inner.y1 - panel->inner.y0);
target_x = 0;
if (cursor_x < target_x){
target_x = (real32)Max(0, cursor_x - w*.5f);
target_x = (f32)Max(0, cursor_x - w*.5f);
}
else if (cursor_x >= target_x + w){
target_x = (real32)(cursor_x - w*.5f);
target_x = (f32)(cursor_x - w*.5f);
}
target_y = (real32)FLOOR32(cursor_y - h*.5f);
target_y = (f32)FLOOR32(cursor_y - h*.5f);
if (target_y < 0) target_y = 0;
view->target_x = target_x;
@ -2257,6 +2283,7 @@ enum History_Mode{
internal void
file_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step step, u8 *str,
History_Mode history_mode){
if (!file->undo.undo.edits) return;
#if BUFFER_EXPERIMENT_SCALPEL <= 1
General_Memory *general = &mem->general;
@ -2443,30 +2470,28 @@ inline void
file_pre_edit_maintenance(Editing_File *file){
if (file->still_lexing)
system_cancel_job(BACKGROUND_THREADS, file->lex_job);
file->last_4ed_edit_time = system_get_now();
}
internal void
file_do_single_edit(Mem_Options *mem, Editing_File *file,
Editing_Layout *layout, Edit_Spec spec, History_Mode history_mode){
Assert(file);
ProfileMomentFunction();
// NOTE(allen): fixing stuff beforewards????
file_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
#if BUFFER_EXPERIMENT_SCALPEL <= 2
i32 shift_amount = 0;
General_Memory *general = &mem->general;
char *str = (char*)spec.str;
i32 start = spec.step.edit.start;
i32 end = spec.step.edit.end;
char *str = (char*)spec.str;
i32 str_len = spec.step.edit.len;
i32 shift_amount = 0;
i32 request_amount = 0;
while (buffer_replace_range(&file->buffer, start, end, str, str_len, &shift_amount, &request_amount)){
void *new_data = 0;
@ -2477,20 +2502,18 @@ file_do_single_edit(Mem_Options *mem, Editing_File *file,
if (old_data) general_memory_free(general, old_data);
}
#if BUFFER_EXPERIMENT_SCALPEL <= 0
// NOTE(allen): fixing stuff afterwards
if (file->tokens_exist)
file_relex_parallel(mem, file, start, end, shift_amount);
#if BUFFER_EXPERIMENT_SCALPEL == 2
buffer_mugab_check(&file->buffer);
#endif
i32 line_start = buffer_get_line_index(&file->buffer, start);
i32 line_end = buffer_get_line_index(&file->buffer, end);
i32 replaced_line_count = line_end - line_start;
i32 new_line_count = file_count_newlines(file, start, start+str_len);
i32 new_line_count = buffer_count_newlines(&file->buffer, start, start+str_len);
i32 line_shift = new_line_count - replaced_line_count;
file_remeasure_starts(general, file, line_start, line_end, line_shift, shift_amount);
file_remeasure_widths(general, file, file->font, line_start, line_end, line_shift);
file_remeasure_starts(general, &file->buffer, line_start, line_end, line_shift, shift_amount);
file_remeasure_widths(general, &file->buffer, file->font, line_start, line_end, line_shift);
i32 panel_count = layout->panel_count;
Panel *current_panel = layout->panels;
@ -2500,7 +2523,15 @@ file_do_single_edit(Mem_Options *mem, Editing_File *file,
view_measure_wraps(general, current_view);
}
}
#endif
#if BUFFER_EXPERIMENT_SCALPEL <= 0
// NOTE(allen): fixing stuff afterwards
if (file->tokens_exist)
file_relex_parallel(mem, file, start, end, shift_amount);
#endif
#if BUFFER_EXPERIMENT_SCALPEL <= 1
Temp_Memory cursor_temp = begin_temp_memory(&mem->part);
i32 cursor_max = layout->panel_max_count * 2;
Cursor_With_Index *cursors = push_array(&mem->part, Cursor_With_Index, cursor_max);
@ -2541,6 +2572,7 @@ file_do_single_edit(Mem_Options *mem, Editing_File *file,
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 (view->locked) return;
#if BUFFER_EXPERIMENT_SCALPEL <= 1
Assert(file);
ProfileMomentFunction();
@ -2652,6 +2684,7 @@ view_do_white_batch_edit(Mem_Options *mem, File_View *view, Editing_File *file,
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){
if (view->locked) return;
Edit_Spec spec = {};
spec.step.type = ED_NORMAL;
spec.step.edit.start = start;
@ -2663,7 +2696,7 @@ view_replace_range(Mem_Options *mem, File_View *view, Editing_Layout *layout,
file_do_single_edit(mem, view->file, layout, spec, hist_normal);
}
internal void
inline void
view_post_paste_effect(File_View *view, i32 ticks, i32 start, i32 size, u32 color){
view->paste_effect.start = start;
view->paste_effect.end = start + size;
@ -2675,6 +2708,7 @@ view_post_paste_effect(File_View *view, i32 ticks, i32 start, i32 size, u32 colo
internal void
view_undo_redo(Mem_Options *mem, Editing_Layout *layout, File_View *view, Editing_File *file,
Edit_Stack *stack, Edit_Type expected_type){
if (view->locked) return;
if (file && stack->edit_count > 0){
Edit_Step step = stack->edits[stack->edit_count-1];
@ -2717,9 +2751,11 @@ view_redo(Mem_Options *mem, Editing_Layout *layout, File_View *view){
internal void
view_history_step(Mem_Options *mem, Editing_Layout *layout, File_View *view, History_Mode history_mode){
if (view->locked) return;
Assert(history_mode != hist_normal);
Editing_File *file = view->file;
bool32 do_history_step = 0;
Edit_Step step = {};
if (history_mode == hist_backward){
@ -2768,7 +2804,7 @@ view_history_step(Mem_Options *mem, Editing_Layout *layout, File_View *view, His
}
}
// TODO(allen): should these still be view operations?
// TODO(allen): write these as streamed operations
internal i32
view_find_end_of_line(File_View *view, i32 pos){
#if BUFFER_EXPERIMENT_SCALPEL <= 0
@ -2871,9 +2907,11 @@ working_set_clipboard_roll_down(Working_Set *working){
inline Editing_File*
working_set_contains(Working_Set *working, String filename){
Editing_File *result = 0;
i32 index;
if (table_find(&working->table, filename, &index)){
result = working->files + index;
i32 id;
if (table_find(&working->table, filename, &id)){
if (id < working->file_max_count){
result = working->files + id;
}
}
return result;
}
@ -3194,6 +3232,44 @@ view_auto_tab_tokens(Mem_Options *mem, File_View *view, Editing_Layout *layout,
#endif
}
struct Get_Link_Result{
b32 in_link;
i32 index;
};
internal Get_Link_Result
get_link(Hyper_Link *links, i32 link_count, i32 pos){
Get_Link_Result result = {};
// TODO TODO TODO TODO TODO TODO TODO TODO
return result;
}
internal u32*
style_get_link_color(Style *style, Link_Type type){
u32 *result;
switch (type){
case link_result:
result = &style->main.result_link_color;
break;
case link_related:
result = &style->main.related_link_color;
break;
case link_error:
result = &style->main.error_link_color;
break;
case link_warning:
result = &style->main.warning_link_color;
break;
default:
result = &style->main.default_color;
}
return result;
}
internal u32*
style_get_color(Style *style, Cpp_Token token){
u32 *result;
@ -3503,16 +3579,16 @@ step_file_view(Thread_Context *thread, View *view_, i32_Rect rect,
Style *style = view->style;
Font *font = style->font;
real32 line_height = (real32)font->height;
real32 cursor_y = view_get_cursor_y(view);
real32 target_y = view->target_y;
real32 max_y = view_compute_height(view) - line_height*2;
f32 line_height = (f32)font->height;
f32 cursor_y = view_get_cursor_y(view);
f32 target_y = view->target_y;
f32 max_y = view_compute_height(view) - line_height*2;
i32 lowest_line = view_compute_lowest_line(view);
real32 max_target_y = view_compute_max_target_y(lowest_line, font->height, max_y);
real32 delta_y = 3.f*line_height;
real32 extra_top = 0.f;
f32 max_target_y = view_compute_max_target_y(lowest_line, font->height, max_y);
f32 delta_y = 3.f*line_height;
f32 extra_top = 0.f;
extra_top += view_widget_height(view, font);
real32 taken_top_space = line_height + extra_top;
f32 taken_top_space = line_height + extra_top;
if (user_input->mouse.my < rect.y0 + taken_top_space){
view_->mouse_cursor_type = APP_MOUSE_CURSOR_ARROW;
@ -3595,7 +3671,7 @@ step_file_view(Thread_Context *thread, View *view_, i32_Rect rect,
if (!is_active) view_set_widget(view, FWIDG_NONE);
// NOTE(allen): framely undo stuff
{
if (file){
i32 scrub_max = view->scrub_max;
i32 undo_count, redo_count, total_count;
undo_count = file->undo.undo.edit_count;
@ -3740,11 +3816,26 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
i32 max_x = rect.x1 - rect.x0;
i32 max_y = rect.y1 - rect.y0 + font->height;
Assert(file && buffer_good(&file->buffer) && !file->is_dummy);
Assert(file && !file->is_dummy && buffer_good(&file->buffer));
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;
b32 tokens_use = 0;
Cpp_Token_Stack token_stack = {};
if (file){
tokens_use = file->tokens_complete && (file->token_stack.count > 0);
token_stack = file->token_stack;
}
b32 links_use = 0;
Hyper_Link *links = 0;
i32 link_count = 0;
if (view->links){
if (view->link_count > 0){
links_use = 1;
links = view->links;
link_count = view->link_count;
}
}
Partition *part = &view_->mem->part;
Temp_Memory temp = begin_temp_memory(part);
@ -3775,17 +3866,38 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
}
i32 token_i = 0;
i32 link_i = 0;
u32 main_color = style->main.default_color;
u32 link_color = 0;
if (tokens_use){
Cpp_Get_Token_Result result = cpp_get_token(&token_stack, items->index);
main_color = *style_get_color(style, token_stack.tokens[result.token_index]);
token_i = result.token_index + 1;
}
if (links_use){
Get_Link_Result result = get_link(links, link_count, items->index);
if (result.in_link){
link_color = *style_get_link_color(style, links[result.index].link_type);
}
link_i = result.index;
}
u32 mark_color = style->main.mark_color;
Buffer_Render_Item *item = items;
i32 prev_ind = -1;
u32 highlight_color = 0; AllowLocal(highlight_color);
u32 highlight_color = 0;
u32 chunk_highlights[] = {
0x22FF0000,
0x22FFFF00,
0x2200FF00,
0x2200FFFF,
0x220000FF,
0x22FF00FF
};
i32 current_chunk = item->chunk_i;
u32 chunk_highlight = chunk_highlights[current_chunk % ArrayCount(chunk_highlights)];
for (i32 i = 0; i < count; ++i, ++item){
i32 ind = item->index;
if (tokens_use && ind != prev_ind){
@ -3810,11 +3922,22 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
}
u32 char_color = main_color;
if (item->chunk_i > current_chunk){
current_chunk = item->chunk_i;
chunk_highlight = chunk_highlights[current_chunk % ArrayCount(chunk_highlights)];
}
if (cursor_begin <= ind && ind < cursor_end && (ind != prev_ind || cursor_begin < ind)){
if (is_active) draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), cursor_color);
else draw_rectangle_outline(target, f32R(item->x0, item->y0, item->x1, item->y1), cursor_color);
char_color = at_cursor_color;
}
else if (highlight_color){
draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), highlight_color);
}
else if (chunk_highlight){
draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), chunk_highlight);
}
u32 fade_color = 0xFFFF00FF;
f32 fade_amount = 0.f;
@ -3859,6 +3982,7 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
switch (view->widget.type){
case FWIDG_TIMELINES:
{
Assert(file);
if (view->widget.timeline.undo_line){
do_button(1, &state, &layout, "- Undo", 1);
@ -3925,6 +4049,7 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
intbar_draw_string(target, &bar, line_number, base_color);
if (file){
switch (buffer_get_sync(file)){
case SYNC_BEHIND_OS:
{
@ -3939,12 +4064,13 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
}break;
}
}
}
return 0;
}
internal void
kill_buffer(General_Memory *general, Editing_File *file, Live_Views *live_set, Editing_Layout *layout){
kill_file(General_Memory *general, Editing_File *file, Live_Views *live_set, Editing_Layout *layout){
i32 panel_count = layout->panel_count;
Panel *panels = layout->panels, *panel;
panel = panels;
@ -3963,7 +4089,6 @@ kill_buffer(General_Memory *general, Editing_File *file, Live_Views *live_set, E
}
++panel;
}
file_close(general, file);
file_get_dummy(file);
}
@ -4098,9 +4223,11 @@ HANDLE_COMMAND_SIG(handle_command_file_view){
}
inline void
free_file_view(View *view_){
File_View *view = (File_View*)view_;
general_memory_free(&view_->mem->general, view->line_wrap_y);
free_file_view(View *view){
File_View *fview = (File_View*)view;
general_memory_free(&view->mem->general, fview->line_wrap_y);
if (fview->links)
general_memory_free(&view->mem->general, fview->links);
}
internal
@ -4129,13 +4256,12 @@ DO_VIEW_SIG(do_file_view){
}
internal File_View*
file_view_init(View *view, Delay *delay, Editing_Layout *layout){
file_view_init(View *view, Editing_Layout *layout){
view->type = VIEW_TYPE_FILE;
view->do_view = do_file_view;
view->handle_command = handle_command_file_view;
File_View *result = (File_View*)view;
result->delay = delay;
result->layout = layout;
result->rewind_max = 4;
result->scrub_max = 1;

View File

@ -143,7 +143,10 @@ struct Style_Main_Data{
u32 highlight_white_color;
u32 paste_color;
u32 undo_color;
u32 next_undo_color;
u32 result_link_color;
u32 related_link_color;
u32 error_link_color;
u32 warning_link_color;
Interactive_Style file_info_style;
};
@ -186,6 +189,10 @@ enum Style_Color_Tag{
STAG_PASTE_COLOR,
STAG_UNDO_COLOR,
STAG_NEXT_UNDO_COLOR,
STAG_RESULT_LINK_COLOR,
STAG_RELATED_LINK_COLOR,
STAG_ERROR_LINK_COLOR,
STAG_WARNING_LINK_COLOR,
// never below this
STAG_COUNT
};
@ -350,7 +357,6 @@ style_form_convert(Style_File_Format_v4 *o, Style_File_Format_v3 *i){
o->main.highlight_white_color = i->main.highlight_white_color;
o->main.paste_color = i->main.paste_color;
o->main.undo_color = i->main.paste_color ^ 0x00FFFFFF;
o->main.next_undo_color = i->main.paste_color ^ 0x00FFFFFF;
o->main.file_info_style = i->main.file_info_style;
o->main.file_info_style.bar_active_color = i->main.file_info_style.bar_color;
}
@ -395,7 +401,11 @@ style_index_by_tag(Style *s, u32 tag){
case STAG_PASTE_COLOR: result = &s->main.paste_color; break;
case STAG_UNDO_COLOR: result = &s->main.undo_color; break;
case STAG_NEXT_UNDO_COLOR: result = &s->main.next_undo_color; break;
case STAG_RESULT_LINK_COLOR: result = &s->main.result_link_color; break;
case STAG_RELATED_LINK_COLOR: result = &s->main.related_link_color; break;
case STAG_ERROR_LINK_COLOR: result = &s->main.error_link_color; break;
case STAG_WARNING_LINK_COLOR: result = &s->main.warning_link_color; break;
}
return result;
}

View File

@ -131,7 +131,7 @@ buffer_seek_whitespace_up(Buffer_Type *buffer, int pos){
int no_hard;
size = buffer_size(buffer);
loop = buffer_backify_loop(buffer, pos, 1);
loop = buffer_backify_loop(buffer, pos-1, 1);
for (;buffer_backify_good(&loop);
buffer_backify_next(&loop)){
@ -245,18 +245,22 @@ buffer_seek_alphanumeric_right(Buffer_Type *buffer, int pos){
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos < end && is_alphanumeric_true(data[pos]); ++pos);
if (!is_alphanumeric_true(data[pos])) break;
for (; pos < end; ++pos){
if (!is_alphanumeric_true(data[pos])) goto buffer_seek_alphanumeric_right_mid;
}
}
buffer_seek_alphanumeric_right_mid:
for (;buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos < end && !is_alphanumeric_true(data[pos]); ++pos);
if (is_alphanumeric_true(data[pos])) break;
for (; pos < end; ++pos){
if (is_alphanumeric_true(data[pos])) goto buffer_seek_alphanumeric_right_end;
}
}
buffer_seek_alphanumeric_right_end:
return(pos);
}
@ -276,16 +280,19 @@ buffer_seek_alphanumeric_left(Buffer_Type *buffer, int pos){
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - end;
for (; pos >= end && !is_alphanumeric_true(data[pos]); --pos);
if (is_alphanumeric_true(data[pos])) break;
for (; pos >= end; --pos){
if (is_alphanumeric_true(data[pos])) goto buffer_seek_alphanumeric_left_mid;
}
}
buffer_seek_alphanumeric_left_mid:
for (;buffer_backify_good(&loop);
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - end;
for (; pos >= end && is_alphanumeric_true(data[pos]); --pos);
if (!is_alphanumeric_true(data[pos])) break;
for (; pos >= end; --pos){
if (!is_alphanumeric_true(data[pos])) goto buffer_seek_alphanumeric_left_end;
}
}
++pos;
@ -294,6 +301,7 @@ buffer_seek_alphanumeric_left(Buffer_Type *buffer, int pos){
pos = 0;
}
buffer_seek_alphanumeric_left_end:
return(pos);
}
@ -1069,6 +1077,9 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
switch (ch){
case '\n':
write_render_item_inline(item, i, ' ', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
@ -1078,11 +1089,17 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
case 0:
ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
ch_width = write_render_item_inline(item, i, '0', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
@ -1090,11 +1107,17 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
case '\r':
ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
ch_width = write_render_item_inline(item, i, 'r', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
@ -1102,10 +1125,16 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
case '\t':
ch_width_sub = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
write_render_item_inline(item, i, 't', x + ch_width_sub, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
@ -1113,9 +1142,13 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
default:
write_render_item(item, i, ch, x, y, ch_width, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
break;
}
if (y > height + shift_y) goto buffer_get_render_data_end;
@ -1127,6 +1160,9 @@ buffer_get_render_data_end:
ch = 0;
ch_width = measure_character(advance_data, stride, ' ');
write_render_item(item, size, ch, x, y, ch_width, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = -1;
#endif
++item_i;
++item;
x += ch_width;

View File

@ -110,25 +110,6 @@ buffer_end_init(Gap_Buffer_Init *init){
return(result);
}
internal_4tech void*
buffer_edit_provide_memory(Gap_Buffer *buffer, void *new_data, int new_max){
void *result;
int new_gap_size;
assert_4tech(new_max >= buffer_size(buffer));
result = buffer->data;
new_gap_size = new_max - buffer_size(buffer);
memcpy_4tech(new_data, buffer->data, buffer->size1);
memcpy_4tech((char*)new_data + buffer->size1 + new_gap_size, buffer->data + buffer->size1 + buffer->gap_size, buffer->size2);
buffer->data = (char*)new_data;
buffer->gap_size = new_gap_size;
buffer->max = new_max;
return(result);
}
typedef struct{
Gap_Buffer *buffer;
char *data, *base;
@ -334,5 +315,24 @@ buffer_batch_edit_step(Buffer_Batch_State *state, Gap_Buffer *buffer, Buffer_Edi
return(result);
}
internal_4tech void*
buffer_edit_provide_memory(Gap_Buffer *buffer, void *new_data, int new_max){
void *result;
int new_gap_size;
assert_4tech(new_max >= buffer_size(buffer));
result = buffer->data;
new_gap_size = new_max - buffer_size(buffer);
memcpy_4tech(new_data, buffer->data, buffer->size1);
memcpy_4tech((char*)new_data + buffer->size1 + new_gap_size, buffer->data + buffer->size1 + buffer->gap_size, buffer->size2);
buffer->data = (char*)new_data;
buffer->gap_size = new_gap_size;
buffer->max = new_max;
return(result);
}
// BOTTOM

View File

@ -92,20 +92,6 @@ buffer_end_init(Buffer_Init *init){
return(result);
}
internal_4tech void*
buffer_edit_provide_memory(Buffer *buffer, void *new_data, int new_max){
void *result;
assert_4tech(new_max >= buffer->size);
result = buffer->data;
memcpy_4tech(new_data, buffer->data, buffer->size);
buffer->data = (char*)new_data;
buffer->max = new_max;
return(result);
}
typedef struct{
Buffer *buffer;
char *data, *end;
@ -226,5 +212,19 @@ buffer_batch_edit_step(Buffer_Batch_State *state, Buffer *buffer, Buffer_Edit *s
return(result);
}
internal_4tech void*
buffer_edit_provide_memory(Buffer *buffer, void *new_data, int new_max){
void *result;
assert_4tech(new_max >= buffer->size);
result = buffer->data;
memcpy_4tech(new_data, buffer->data, buffer->size);
buffer->data = (char*)new_data;
buffer->max = new_max;
return(result);
}
// BOTTOM

View File

@ -28,6 +28,7 @@ typedef struct{
typedef struct{
Fixed_Width_Gap_Buffer *gaps;
int chunk_count;
int chunk_alloced;
int chunk_max;
int size;
@ -37,6 +38,9 @@ typedef struct{
int widths_count;
int line_max;
int widths_max;
int grow_gaps;
int edit_stage;
} Multi_Gap_Buffer;
inline_4tech int
@ -59,9 +63,9 @@ typedef struct{
int size;
int chunk_i;
int chunk_count;
int chunk_alloc;
} 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;
@ -69,7 +73,9 @@ buffer_begin_init(Multi_Gap_Buffer *buffer, char *data, int size){
init.data = data;
init.size = size;
init.chunk_i = 0;
init.chunk_count = div_ceil_4tech(size, fixed_width_buffer_half_size);
init.chunk_alloc = div_ceil_4tech(size, fixed_width_buffer_half_size);
init.chunk_count = init.chunk_alloc;
if (init.chunk_alloc < 4) init.chunk_alloc = 4;
return(init);
}
@ -77,7 +83,7 @@ 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)
if (init->buffer->gaps && init->chunk_i == init->chunk_alloc)
result = 0;
return(result);
}
@ -88,7 +94,7 @@ buffer_init_page_size(Multi_Gap_Buffer_Init *init){
int result;
buffer = init->buffer;
if (buffer->gaps) result = fixed_width_buffer_size;
else result = init->chunk_count * 2 * sizeof(*buffer->gaps);
else result = init->chunk_alloc * 2 * sizeof(*buffer->gaps);
return(result);
}
@ -123,12 +129,14 @@ buffer_end_init(Multi_Gap_Buffer_Init *init){
if (buffer->gaps){
if (buffer->chunk_max >= div_ceil_4tech(init->size, fixed_width_buffer_half_size)){
buffer->chunk_count = init->chunk_count;
if (buffer->chunk_count == 0) buffer->chunk_count = 1;
buffer->chunk_alloced = init->chunk_alloc;
result = 1;
data = init->data;
total_size = init->size;
gap = buffer->gaps;
count = init->chunk_count;
count = buffer->chunk_count;
size = fixed_width_buffer_half_size;
pos = 0;
start_pos = 0;
@ -172,10 +180,6 @@ buffer_find_chunk(Multi_Gap_Buffer *buffer, int pos){
Fixed_Width_Gap_Buffer *gaps;
int start, end, m, this_pos;
if (pos == buffer_size(buffer)){
m = buffer->chunk_count;
}
else{
gaps = buffer->gaps;
start = 0;
end = buffer->chunk_count;
@ -184,13 +188,16 @@ buffer_find_chunk(Multi_Gap_Buffer *buffer, int pos){
this_pos = gaps[m].start_pos;
if (this_pos < pos) start = m;
else if (this_pos > pos) end = m;
else break;
else{
--m;
if (m < 0) m = 0;
break;
}
if (start+1 == end){
m = start; break;
}
assert_4tech(start < end);
}
}
return(m);
}
@ -222,7 +229,7 @@ buffer_stringify_loop(Multi_Gap_Buffer *buffer, int start, int end){
gap = result.gaps + result.chunk_end;
end -= gap->start_pos;
if (end < gap->size1) result.end = end;
if (end <= gap->size1) result.end = end;
else result.end = end + gap->gap_size;
gap = result.gaps + result.chunk_i;
@ -272,6 +279,10 @@ buffer_stringify_next(Multi_Gap_Buffer_Stringify_Loop *loop){
loop->pos = 0;
loop->absolute_pos = gap->start_pos;
temp_end = gap->size1;
if (gap->size1 == 0){
loop->pos = gap->gap_size;
temp_end = fixed_width_buffer_size;
}
}
if (loop->chunk_i == loop->chunk_end && temp_end > loop->end) temp_end = loop->end;
loop->size = temp_end - loop->pos;
@ -301,7 +312,7 @@ buffer_backify_loop(Multi_Gap_Buffer *buffer, int start, int end){
result.buffer = buffer;
result.gaps = buffer->gaps;
result.chunk_i = buffer_find_chunk(buffer, start);
result.chunk_i = buffer_find_chunk(buffer, start-1);
result.chunk_end = buffer_find_chunk(buffer, end);
gap = result.gaps + result.chunk_end;
@ -369,12 +380,20 @@ buffer_backify_next(Multi_Gap_Buffer_Backify_Loop *loop){
internal_4tech int
buffer_replace_range(Multi_Gap_Buffer *buffer, int start, int end, char *str, int len, int *shift_amount_out, int *request_amount){
Fixed_Width_Gap_Buffer *gaps, *gap;
Fixed_Width_Gap_Buffer *gaps, *gap, *dgap;
char *data;
int move_size;
int gap_start, gap_end;
int result;
int size;
int local_end;
int shift_amount;
int required_empty_buffers;
int supplanted_gaps;
int dpos;
int head_size, middle_size, tail_size;
int mem_pos, local_start_pos;
debug_4tech(int osize);
size = buffer_size(buffer);
assert_4tech(0 <= start);
@ -387,11 +406,25 @@ buffer_replace_range(Multi_Gap_Buffer *buffer, int start, int end, char *str, in
gap_start = buffer_find_chunk(buffer, start);
gap_end = buffer_find_chunk(buffer, end);
if (buffer->edit_stage == 0){
buffer->size += *shift_amount_out;
for (gap = gaps + gap_end + 1;
gap < gaps + buffer->chunk_count;
++gap){
gap->start_pos += *shift_amount_out;
}
buffer->edit_stage = 1;
}
gap = gaps + gap_start;
if (gap_start < gap_end){
memmove_4tech(gap + 1, gaps + gap_end, sizeof(*gaps)*(buffer->chunk_count - gap_end));
buffer->chunk_count -= (gap_end - gap_start + 1);
if (buffer->edit_stage == 1){
if (gap_start < gap_end && gap_start+1 < buffer->chunk_count){
supplanted_gaps = gap_end - gap_start + 1;
if (buffer->chunk_max - buffer->chunk_alloced >= supplanted_gaps){
++gap;
memcpy_4tech(gaps + buffer->chunk_alloced, gap, sizeof(*gaps)*supplanted_gaps);
memmove_4tech(gap, gaps + gap_end, sizeof(*gaps)*(buffer->chunk_alloced - gap_start - 1));
buffer->chunk_count -= (gap_end - gap_start + 1);
local_end = end - gap->start_pos;
@ -406,15 +439,24 @@ buffer_replace_range(Multi_Gap_Buffer *buffer, int start, int end, char *str, in
--gap;
}
if (end > gap->size1 + gap->size2) end = gap->size1 + gap->size2;
else{
buffer->grow_gaps = 1;
*request_amount = round_up_4tech(sizeof(*gaps)*(supplanted_gaps+buffer->chunk_max*2), 4<<10);
result = 1;
goto mugab_replace_range_end;
}
}
buffer->edit_stage = 2;
}
shift_amount = (len - (end - start));
if (shift_amount + gap->size1 + gap->size2 <= fixed_width_buffer_size){
start -= gap->start_pos;
end -= gap->start_pos;
if (end > gap->size1 + gap->size2) end = gap->size1 + gap->size2;
if (shift_amount + gap->size1 + gap->size2 <= fixed_width_buffer_size){
data = gap->data;
debug_4tech(osize = gap->size1 + gap->size2);
if (end < gap->size1){
move_size = gap->size1 - end;
memmove_4tech(data + gap->size1 + gap->gap_size - move_size, data + end, move_size);
@ -429,20 +471,206 @@ buffer_replace_range(Multi_Gap_Buffer *buffer, int start, int end, char *str, in
}
memcpy_4tech(data + start, str, len);
gap->size2 = size - end;
gap->size2 = fixed_width_buffer_size - (end + gap->gap_size);
gap->size1 = start + len;
gap->gap_size -= shift_amount;
assert_4tech(gap->size1 + gap->size2 == size + shift_amount);
assert_4tech(gap->size1 + gap->gap_size + gap->size2 == gap->max);
assert_4tech(gap->size1 + gap->size2 == osize + shift_amount);
assert_4tech(gap->size1 + gap->gap_size + gap->size2 == fixed_width_buffer_size);
result = 0;
buffer->edit_stage = 0;
if (gap_start < gap_end){
++gap;
gap->start_pos += shift_amount;
}
}
else{
div_ceil_4tech(shift_amount, fixed_width_buffer_half_size);
result = 1;
required_empty_buffers = div_ceil_4tech(shift_amount, fixed_width_buffer_half_size);
if (buffer->chunk_alloced - buffer->chunk_count >= required_empty_buffers){
if (buffer->chunk_max - buffer->chunk_alloced >= required_empty_buffers){
memcpy_4tech(gaps + buffer->chunk_alloced, gaps + buffer->chunk_count, sizeof(*gaps)*required_empty_buffers);
memmove_4tech(gap + required_empty_buffers + 1, gap + 1, sizeof(*gaps)*(buffer->chunk_count - gap_start - 1));
memcpy_4tech(gap + 1, gaps + buffer->chunk_alloced, sizeof(*gaps)*required_empty_buffers);
data = gap->data;
if (end < gap->size1){
move_size = gap->size1 - end;
memmove_4tech(data + gap->size1 + gap->gap_size - move_size, data + end, move_size);
gap->size1 -= move_size + (end - start);
gap->size2 += move_size;
}
else if (start > gap->size1){
move_size = start - gap->size1;
memmove_4tech(data + gap->size1, data + gap->size1 + gap->gap_size, move_size);
gap->size1 += move_size;
gap->size2 -= move_size + (end - start);
}
else{
if (end > gap->size1){
gap->size2 -= (end - gap->size1);
}
gap->size1 = start;
}
if (gap->size1 > fixed_width_buffer_half_size){
move_size = gap->size1 - fixed_width_buffer_half_size;
memmove_4tech(data + gap->size1 + gap->gap_size - move_size, data + end, move_size);
gap->size1 -= move_size + (end - start);
gap->size2 += move_size;
}
else if (gap->size2 > fixed_width_buffer_half_size){
move_size = gap->size2 - fixed_width_buffer_half_size;
memmove_4tech(data + gap->size1, data + gap->size1 + gap->gap_size, move_size);
gap->size1 += move_size;
gap->size2 -= move_size + (end - start);
}
dgap = gap + required_empty_buffers;
dpos = gap->size1 + gap->gap_size;
memcpy_4tech(dgap->data + dpos, data + dpos, gap->size2);
dgap->size2 = gap->size2;
gap->size2 = 0;
middle_size = div_ceil_4tech(len, (required_empty_buffers * 2));
head_size = middle_size;
tail_size = middle_size;
if (head_size + gap->size1 + 256 > fixed_width_buffer_size){
head_size = fixed_width_buffer_size - gap->size1 - 256;
if (head_size < 0) head_size = 0;
}
if (tail_size + dgap->size2 + 256 > fixed_width_buffer_size){
tail_size = fixed_width_buffer_size - dgap->size2 - 256;
if (tail_size < 0) tail_size = 0;
}
if (required_empty_buffers-1 > 0)
middle_size = div_ceil_4tech(len - head_size - tail_size, (required_empty_buffers-1)*2);
else
middle_size = 0;
mem_pos = 0;
if (head_size > len - mem_pos) head_size = len - mem_pos;
gap->size2 = head_size;
gap->gap_size = fixed_width_buffer_size - gap->size1 - gap->size2;
memcpy_4tech(gap->data + fixed_width_buffer_size - head_size, str + mem_pos, head_size);
mem_pos += head_size;
local_start_pos = gap->start_pos + gap->size1 + gap->size2;
++gap;
for (;gap < dgap; ++gap){
gap->start_pos = local_start_pos;
if (middle_size > len - mem_pos) middle_size = len - mem_pos;
gap->size1 = middle_size;
memcpy_4tech(gap->data, str + mem_pos, middle_size);
mem_pos += middle_size;
if (middle_size > len - mem_pos) middle_size = len - mem_pos;
gap->size2 = middle_size;
memcpy_4tech(gap->data + fixed_width_buffer_size - middle_size, str + mem_pos, middle_size);
mem_pos += middle_size;
gap->gap_size = fixed_width_buffer_size - (gap->size1 + gap->size2);
local_start_pos += gap->size1 + gap->size2;
++gap;
}
if (tail_size > len - mem_pos) tail_size = len - mem_pos;
gap->start_pos = local_start_pos;
gap->size1 = tail_size;
gap->gap_size = fixed_width_buffer_size - gap->size1 - gap->size2;
memcpy_4tech(gap->data, str + mem_pos, tail_size);
mem_pos += tail_size;
assert_4tech(mem_pos == len);
buffer->chunk_count += required_empty_buffers;
result = 0;
buffer->edit_stage = 0;
}
else{
buffer->grow_gaps = 1;
*request_amount = round_up_4tech(sizeof(*gaps)*(required_empty_buffers+buffer->chunk_max*2), 4<<10);
result = 1;
goto mugab_replace_range_end;
}
}
else{
if (buffer->chunk_alloced < buffer->chunk_max){
*request_amount = fixed_width_buffer_size;
result = 1;
}
else{
buffer->grow_gaps = 1;
*request_amount = round_up_4tech(sizeof(*gaps)*(1+buffer->chunk_max*2), 4<<10);
result = 1;
}
}
}
mugab_replace_range_end:
return(result);
}
internal_4tech void*
buffer_edit_provide_memory(Multi_Gap_Buffer *buffer, void *new_data, int size){
void *result;
Fixed_Width_Gap_Buffer *gap;
if (buffer->grow_gaps){
assert_4tech(size >= buffer->chunk_max*sizeof(*buffer->gaps));
result = buffer->gaps;
memcpy_4tech(new_data, buffer->gaps, buffer->chunk_alloced*sizeof(*buffer->gaps));
buffer->gaps = (Fixed_Width_Gap_Buffer*)new_data;
buffer->chunk_max = size / sizeof(*buffer->gaps);
buffer->grow_gaps = 0;
}
else{
assert_4tech(buffer->chunk_max > buffer->chunk_alloced);
assert_4tech(size >= fixed_width_buffer_size);
gap = &buffer->gaps[buffer->chunk_alloced++];
*gap = {};
gap->data = (char*)new_data;
result = 0;
}
return(result);
}
internal_4tech int
buffer_mugab_check(Multi_Gap_Buffer *buffer){
Fixed_Width_Gap_Buffer *gap;
int result;
int total_size;
int i, count;
assert_4tech(buffer->chunk_count <= buffer->chunk_alloced);
assert_4tech(buffer->chunk_alloced <= buffer->chunk_max);
count = buffer->chunk_count;
total_size = 0;
gap = buffer->gaps;
for (i = 0; i < count; ++i, ++gap){
assert_4tech(gap->size1 + gap->size2 + gap->gap_size == fixed_width_buffer_size);
assert_4tech(gap->start_pos == total_size);
total_size += gap->size1 + gap->size2;
}
assert_4tech(total_size == buffer->size);
assert_4tech(buffer->edit_stage == 0);
assert_4tech(buffer->grow_gaps == 0);
result = 1;
return(result);
}

View File

@ -157,6 +157,8 @@ typedef struct{
int glyphid;
float x0, y0;
float x1, y1;
int chunk_i;
} Buffer_Render_Item;
inline_4tech void

View File

@ -58,7 +58,7 @@
#define FPS 30
#define FRAME_TIME (1000000 / FPS)
#define BUFFER_EXPERIMENT_SCALPEL 0
#define BUFFER_EXPERIMENT_SCALPEL 1
#include "4ed_meta.h"