work on mugab edits
This commit is contained in:
parent
a89b46fda7
commit
60dab2731c
|
@ -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);
|
||||
|
|
|
@ -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
155
4ed.cpp
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -157,6 +157,8 @@ typedef struct{
|
|||
int glyphid;
|
||||
float x0, y0;
|
||||
float x1, y1;
|
||||
|
||||
int chunk_i;
|
||||
} Buffer_Render_Item;
|
||||
|
||||
inline_4tech void
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
Loading…
Reference in New Issue