This commit is contained in:
Allen Webster 2015-10-27 21:45:03 -04:00
parent 67c15443e0
commit d3913c0c7a
10 changed files with 347 additions and 178 deletions

View File

@ -228,7 +228,8 @@ extern "C" GET_BINDING_DATA(get_bindings){
bind(context, '?', MDFR_CTRL, cmdid_toggle_show_whitespace); bind(context, '?', MDFR_CTRL, cmdid_toggle_show_whitespace);
bind(context, '~', MDFR_CTRL, cmdid_clean_all_lines); bind(context, '~', MDFR_CTRL, cmdid_clean_all_lines);
// NOTE(allen): These whitespace manipulators are not currently functional // NOTE(allen): These now only set the mode of the file for writing to disk
// they do no longer effect the internal representation.
bind(context, '1', MDFR_CTRL, cmdid_eol_dosify); bind(context, '1', MDFR_CTRL, cmdid_eol_dosify);
bind(context, '!', MDFR_CTRL, cmdid_eol_nixify); bind(context, '!', MDFR_CTRL, cmdid_eol_nixify);

View File

@ -96,6 +96,9 @@ enum Command_ID{
cmdid_eol_dosify, cmdid_eol_dosify,
cmdid_eol_nixify, cmdid_eol_nixify,
cmdid_auto_tab, cmdid_auto_tab,
cmdid_auto_tab_range,
cmdid_auto_tab_line_at_cursor,
cmdid_auto_tab_whole_file,
cmdid_open_panel_vsplit, cmdid_open_panel_vsplit,
cmdid_open_panel_hsplit, cmdid_open_panel_hsplit,
cmdid_close_panel, cmdid_close_panel,

122
4ed.cpp
View File

@ -128,6 +128,7 @@ globalvar Application_Links app_links;
#define REQ_DBG_VIEW(n) Debug_View *n = view_to_debug_view(command->view); if (!n) return #define REQ_DBG_VIEW(n) Debug_View *n = view_to_debug_view(command->view); if (!n) return
#define COMMAND_DECL(n) internal void command_##n(Command_Data *command, Command_Binding binding) #define COMMAND_DECL(n) internal void command_##n(Command_Data *command, Command_Binding binding)
#define COMPOSE_DECL(n) internal void n(Command_Data *command, Command_Binding binding)
struct Command_Data{ struct Command_Data{
Mem_Options *mem; Mem_Options *mem;
@ -249,40 +250,6 @@ COMMAND_DECL(seek_whitespace_down){
i32 pos = buffer_seek_whitespace_down(&file->buffer, view->cursor.pos); i32 pos = buffer_seek_whitespace_down(&file->buffer, view->cursor.pos);
view_cursor_move(view, pos); view_cursor_move(view, pos);
#if BUFFER_EXPERIMENT_SCALPEL
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
i32 size = file->buffer.size;
char* data = file->buffer.data;
i32 pos = view->cursor.pos;
while (pos < size && char_is_whitespace(data[pos])){
++pos;
}
bool32 no_hard_character = 0;
i32 prev_endline = -1;
while (pos < size){
if (starts_new_line(data[pos])){
if (no_hard_character) break;
else{
no_hard_character = 1;
prev_endline = pos;
}
}
else if (!char_is_whitespace(data[pos])){
no_hard_character = 0;
}
++pos;
}
if (prev_endline == -1 || prev_endline+1 >= size) pos = size;
else pos = prev_endline+1;
view_cursor_move(view, pos);
#endif
} }
internal i32 internal i32
@ -387,7 +354,7 @@ COMMAND_DECL(seek_alphanumeric_left){
} }
COMMAND_DECL(seek_alphanumeric_or_camel_right){ COMMAND_DECL(seek_alphanumeric_or_camel_right){
#if BUFFER_EXPERIMENT_SCALPEL #if 0
ProfileMomentFunction(); ProfileMomentFunction();
REQ_FILE_VIEW(view); REQ_FILE_VIEW(view);
REQ_FILE(file, view); REQ_FILE(file, view);
@ -413,7 +380,7 @@ COMMAND_DECL(seek_alphanumeric_or_camel_right){
} }
COMMAND_DECL(seek_alphanumeric_or_camel_left){ COMMAND_DECL(seek_alphanumeric_or_camel_left){
#if BUFFER_EXPERIMENT_SCALPEL #if 0
ProfileMomentFunction(); ProfileMomentFunction();
REQ_FILE_VIEW(view); REQ_FILE_VIEW(view);
REQ_FILE(file, view); REQ_FILE(file, view);
@ -1020,7 +987,7 @@ case_change_range(Mem_Options *mem, File_View *view, Editing_File *file,
if (file->still_lexing) if (file->still_lexing)
system_cancel_job(BACKGROUND_THREADS, file->lex_job); system_cancel_job(BACKGROUND_THREADS, file->lex_job);
view_update_history_before_edit(mem, file, step, 0, hist_normal, view->cursor.pos); view_update_history_before_edit(mem, file, step, 0, hist_normal);
u8 *data = (u8*)file->buffer.data; u8 *data = (u8*)file->buffer.data;
for (i32 i = range.start; i < range.end; ++i){ for (i32 i = range.start; i < range.end; ++i){
@ -1063,27 +1030,21 @@ COMMAND_DECL(clean_all_lines){
} }
COMMAND_DECL(eol_dosify){ COMMAND_DECL(eol_dosify){
#if 0
ProfileMomentFunction(); ProfileMomentFunction();
REQ_FILE_VIEW(view); REQ_FILE_VIEW(view);
REQ_FILE(file, view); REQ_FILE(file, view);
USE_MEM(mem);
view_endline_convert(mem, view, ENDLINE_RN, ENDLINE_ERASE, ENDLINE_RN); file->dos_write_mode = 1;
view_measure_wraps(&mem->general, view); file->last_4ed_edit_time = system_get_now();
#endif
} }
COMMAND_DECL(eol_nixify){ COMMAND_DECL(eol_nixify){
#if 0
ProfileMomentFunction(); ProfileMomentFunction();
REQ_FILE_VIEW(view); REQ_FILE_VIEW(view);
REQ_FILE(file, view); REQ_FILE(file, view);
USE_MEM(mem);
view_endline_convert(mem, view, ENDLINE_N, ENDLINE_ERASE, ENDLINE_N); file->dos_write_mode = 0;
view_measure_wraps(&mem->general, view); file->last_4ed_edit_time = system_get_now();
#endif
} }
COMMAND_DECL(auto_tab){ COMMAND_DECL(auto_tab){
@ -1091,13 +1052,54 @@ COMMAND_DECL(auto_tab){
ProfileMomentFunction(); ProfileMomentFunction();
REQ_FILE_VIEW(view); REQ_FILE_VIEW(view);
REQ_FILE(file, view); REQ_FILE(file, view);
USE_LAYOUT(layout);
USE_MEM(mem); USE_MEM(mem);
Range range = get_range(view->cursor.pos, view->mark);
view_auto_tab(mem, view, range.smaller, range.larger); if (file->token_stack.tokens && file->tokens_complete){
view_measure_wraps(&mem->general, view); Range range = get_range(view->cursor.pos, view->mark);
view_auto_tab_tokens(mem, view, layout, range.start, range.end);
}
#endif #endif
} }
COMMAND_DECL(auto_tab_range){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
if (file->token_stack.tokens && file->tokens_complete){
Range range = get_range(view->cursor.pos, view->mark);
view_auto_tab_tokens(mem, view, layout, range.start, range.end, 1);
}
}
COMMAND_DECL(auto_tab_line_at_cursor){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
if (file->token_stack.tokens && file->tokens_complete){
i32 pos = view->cursor.pos;
view_auto_tab_tokens(mem, view, layout, pos, pos, 0);
}
}
COMMAND_DECL(auto_tab_whole_file){
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
USE_LAYOUT(layout);
USE_MEM(mem);
if (file->token_stack.tokens && file->tokens_complete){
view_auto_tab_tokens(mem, view, layout, 0, buffer_size(&file->buffer), 1);
}
}
COMMAND_DECL(open_panel_vsplit){ COMMAND_DECL(open_panel_vsplit){
ProfileMomentFunction(); ProfileMomentFunction();
USE_LAYOUT(layout); USE_LAYOUT(layout);
@ -1542,6 +1544,11 @@ COMMAND_DECL(set_settings){
} }
} }
COMPOSE_DECL(compose_write_auto_tab_line){
command_write_character(command, binding);
command_auto_tab_line_at_cursor(command, binding);
}
globalvar Command_Function command_table[cmdid_count]; globalvar Command_Function command_table[cmdid_count];
extern "C"{ extern "C"{
@ -1704,13 +1711,19 @@ setup_file_commands(Command_Map *commands, Partition *part, Key_Codes *codes, Co
map_add(commands, 'u', MDFR_CTRL, command_to_uppercase); map_add(commands, 'u', MDFR_CTRL, command_to_uppercase);
map_add(commands, 'j', MDFR_CTRL, command_to_lowercase); map_add(commands, 'j', MDFR_CTRL, command_to_lowercase);
map_add(commands, '~', MDFR_CTRL, command_clean_all_lines); map_add(commands, '~', MDFR_CTRL, command_clean_all_lines);
map_add(commands, '1', MDFR_CTRL, command_eol_dosify);
map_add(commands, '!', MDFR_CTRL, command_eol_nixify);
map_add(commands, 'f', MDFR_CTRL, command_search); map_add(commands, 'f', MDFR_CTRL, command_search);
map_add(commands, 'r', MDFR_CTRL, command_rsearch); map_add(commands, 'r', MDFR_CTRL, command_rsearch);
map_add(commands, 'g', MDFR_CTRL, command_goto_line); map_add(commands, 'g', MDFR_CTRL, command_goto_line);
map_add(commands, '\t', MDFR_CTRL, command_auto_tab); map_add(commands, '\n', MDFR_NONE, compose_write_auto_tab_line);
map_add(commands, '}', MDFR_NONE, compose_write_auto_tab_line);
map_add(commands, ')', MDFR_NONE, compose_write_auto_tab_line);
map_add(commands, ']', MDFR_NONE, compose_write_auto_tab_line);
map_add(commands, ';', MDFR_NONE, compose_write_auto_tab_line);
map_add(commands, '\t', MDFR_NONE, command_auto_tab_line_at_cursor);
map_add(commands, '\t', MDFR_CTRL, command_auto_tab_range);
map_add(commands, '\t', MDFR_CTRL | MDFR_SHIFT, command_write_character);
map_add(commands, 'K', MDFR_CTRL, command_kill_buffer); map_add(commands, 'K', MDFR_CTRL, command_kill_buffer);
map_add(commands, 'O', MDFR_CTRL, command_reopen); map_add(commands, 'O', MDFR_CTRL, command_reopen);
@ -1807,6 +1820,9 @@ setup_command_table(){
SET(eol_dosify); SET(eol_dosify);
SET(eol_nixify); SET(eol_nixify);
SET(auto_tab); SET(auto_tab);
SET(auto_tab_range);
SET(auto_tab_line_at_cursor);
SET(auto_tab_whole_file);
SET(open_panel_vsplit); SET(open_panel_vsplit);
SET(open_panel_hsplit); SET(open_panel_hsplit);
SET(close_panel); SET(close_panel);

View File

@ -115,9 +115,9 @@ map_extract(Command_Map *map, Key_Single key){
Command_Binding bind = {}; Command_Binding bind = {};
u8 command = MDFR_NONE; u8 command = MDFR_NONE;
bool32 ctrl = key.modifiers[CONTROL_KEY_CONTROL]; b32 ctrl = key.modifiers[CONTROL_KEY_CONTROL];
bool32 alt = key.modifiers[CONTROL_KEY_ALT]; b32 alt = key.modifiers[CONTROL_KEY_ALT];
bool32 shift = key.modifiers[CONTROL_KEY_SHIFT] && key.key.loose_keycode; b32 shift = key.modifiers[CONTROL_KEY_SHIFT] && key.key.loose_keycode;
if (shift) command |= MDFR_SHIFT; if (shift) command |= MDFR_SHIFT;
if (ctrl) command |= MDFR_CTRL; if (ctrl) command |= MDFR_CTRL;

View File

@ -10,9 +10,14 @@
// TOP // TOP
#include "buffer/4coder_shared.cpp" #include "buffer/4coder_shared.cpp"
#include "buffer/4coder_gap_buffer.cpp"
#if BUFFER_EXPERIMENT_SCALPEL
#include "buffer/4coder_golden_array.cpp"
#define Buffer_Type Buffer
#else
#include "buffer/4coder_gap_buffer.cpp"
#define Buffer_Type Gap_Buffer #define Buffer_Type Gap_Buffer
#endif
#include "buffer/4coder_buffer_abstract.cpp" #include "buffer/4coder_buffer_abstract.cpp"
struct Range{ struct Range{
@ -74,7 +79,7 @@ struct Undo_Data{
}; };
struct Editing_File{ struct Editing_File{
Gap_Buffer buffer; Buffer_Type buffer;
Undo_Data undo; Undo_Data undo;
@ -95,7 +100,9 @@ struct Editing_File{
b32 tokens_exist; b32 tokens_exist;
b32 still_lexing; b32 still_lexing;
u32 lex_job; u32 lex_job;
i32 base_map_id; i32 base_map_id;
i32 dos_write_mode;
u64 last_4ed_write_time; u64 last_4ed_write_time;
u64 last_4ed_edit_time; u64 last_4ed_edit_time;
@ -1113,16 +1120,18 @@ file_save(Partition *part, Editing_File *file, u8 *filename){
bool32 result = 0; bool32 result = 0;
Temp_Memory temp = begin_temp_memory(part); Temp_Memory temp = begin_temp_memory(part);
i32 max = partition_remaining(part); i32 max = partition_remaining(part);
i32 size = 0; if (file->dos_write_mode){
char *data = push_array(part, char, max); char *data = push_array(part, char, max);
i32 data_size = buffer_size(&file->buffer); i32 size = buffer_convert_out(&file->buffer, data, max);
for (Gap_Buffer_Stringify_Loop loop = buffer_stringify_loop(&file->buffer, 0, data_size, data_size); result = system_save_file(filename, data, size);
buffer_stringify_good(&loop); }
buffer_stringify_next(&loop)){ else{
memcpy(data + size, loop.data, loop.size); char *data = push_array(part, char, max);
size += loop.size; 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(filename, data, size);
end_temp_memory(temp); end_temp_memory(temp);
file_synchronize_times(file, filename); file_synchronize_times(file, filename);
return result; return result;
@ -1459,7 +1468,6 @@ file_close(General_Memory *general, Editing_File *file){
internal void internal void
file_get_dummy(Editing_File *file){ file_get_dummy(Editing_File *file){
*file = {}; *file = {};
file->buffer.data = (char*)&file->buffer.size1;
file->is_dummy = 1; file->is_dummy = 1;
} }
@ -2209,7 +2217,7 @@ enum History_Mode{
internal void internal void
view_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step step, u8 *str, view_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step step, u8 *str,
History_Mode history_mode, i32 next_cursor){ History_Mode history_mode){
#if BUFFER_EXPERIMENT_SCALPEL #if BUFFER_EXPERIMENT_SCALPEL
General_Memory *general = &mem->general; General_Memory *general = &mem->general;
@ -2239,14 +2247,10 @@ view_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step
if (step.edit.len == 1 && str && char_is_alpha_numeric(*str)) can_merge = 1; if (step.edit.len == 1 && str && char_is_alpha_numeric(*str)) can_merge = 1;
if (step.edit.len == 1 && str && (can_merge || char_is_whitespace(*str))) do_merge = 1; if (step.edit.len == 1 && str && (can_merge || char_is_whitespace(*str))) do_merge = 1;
Edit_Step *new_step = 0; if (history_mode != hist_forward)
if (history_mode != hist_forward){ file_post_history(general, file, step, do_merge, can_merge);
new_step = file_post_history(general, file, step, do_merge, can_merge);
new_step->post_pos = next_cursor;
}
new_step = file_post_undo(general, file, step, do_merge, can_merge); file_post_undo(general, file, step, do_merge, can_merge);
new_step->post_pos = next_cursor;
}break; }break;
case ED_REVERSE_NORMAL: case ED_REVERSE_NORMAL:
@ -2396,7 +2400,6 @@ debug_step_match(Edit_Step a, Edit_Step b){
return 1; return 1;
} }
#if 1
inline void inline void
file_pre_edit_maintenance(Editing_File *file){ file_pre_edit_maintenance(Editing_File *file){
if (file->still_lexing) if (file->still_lexing)
@ -2407,12 +2410,12 @@ file_pre_edit_maintenance(Editing_File *file){
internal void internal void
view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file, view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file,
Editing_Layout *layout, Edit_Spec spec, History_Mode history_mode, i32 next_cursor){ Editing_Layout *layout, Edit_Spec spec, History_Mode history_mode){
Assert(file); Assert(file);
ProfileMomentFunction(); ProfileMomentFunction();
// NOTE(allen): fixing stuff beforewards???? // NOTE(allen): fixing stuff beforewards????
view_update_history_before_edit(mem, file, spec.step, spec.str, history_mode, next_cursor); view_update_history_before_edit(mem, file, spec.step, spec.str, history_mode);
file_pre_edit_maintenance(file); file_pre_edit_maintenance(file);
// NOTE(allen): actual text replacement // NOTE(allen): actual text replacement
@ -2425,7 +2428,7 @@ view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file,
i32 shift_amount = 0; i32 shift_amount = 0;
#if BUFFER_EXPERIMENT_SCALPEL #if BUFFER_EXPERIMENT_SCALPEL
while (gap_buffer_replace_range(&file->buffer, start, end, str, str_len, &shift_amount)) while (buffer_replace_range(&file->buffer, start, end, str, str_len, &shift_amount))
file_grow_as_needed(general, file, shift_amount); file_grow_as_needed(general, file, shift_amount);
// NOTE(allen): fixing stuff afterwards // NOTE(allen): fixing stuff afterwards
@ -2433,8 +2436,8 @@ view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file,
file_relex_parallel(mem, file, start, end, shift_amount); file_relex_parallel(mem, file, start, end, shift_amount);
#endif #endif
i32 line_start = buffer_get_line_index(&file->buffer, start, 0, file->buffer.line_count); i32 line_start = buffer_get_line_index(&file->buffer, start);
i32 line_end = buffer_get_line_index(&file->buffer, end, 0, file->buffer.line_count); i32 line_end = buffer_get_line_index(&file->buffer, end);
i32 replaced_line_count = line_end - line_start; i32 replaced_line_count = line_end - line_start;
i32 new_line_count = file_count_newlines(file, start, start+str_len); i32 new_line_count = file_count_newlines(file, start, start+str_len);
i32 line_shift = new_line_count - replaced_line_count; i32 line_shift = new_line_count - replaced_line_count;
@ -2452,13 +2455,12 @@ view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file,
} }
#if BUFFER_EXPERIMENT_SCALPEL #if BUFFER_EXPERIMENT_SCALPEL
i32 cursor_count = 0;
Temp_Memory cursor_temp = begin_temp_memory(&mem->part); Temp_Memory cursor_temp = begin_temp_memory(&mem->part);
i32 cursor_max = layout->panel_max_count * 2; i32 cursor_max = layout->panel_max_count * 2;
Cursor_With_Index *cursors = push_array(&mem->part, Cursor_With_Index, cursor_max); Cursor_With_Index *cursors = push_array(&mem->part, Cursor_With_Index, cursor_max);
i32 cursor_count = 0; i32 cursor_count = 0;
Panel *current_panel = layout->panels; current_panel = layout->panels;
for (i32 i = 0; i < panel_count; ++i, ++current_panel){ for (i32 i = 0; i < panel_count; ++i, ++current_panel){
File_View *current_view = view_to_file_view(current_panel->view); File_View *current_view = view_to_file_view(current_panel->view);
if (current_view && current_view->file == file){ if (current_view && current_view->file == file){
@ -2503,7 +2505,7 @@ view_do_white_batch_edit(Mem_Options *mem, File_View *view, Editing_File *file,
// NOTE(allen): fixing stuff beforewards???? // NOTE(allen): fixing stuff beforewards????
Assert(spec.str == 0); Assert(spec.str == 0);
view_update_history_before_edit(mem, file, spec.step, 0, history_mode, 0); view_update_history_before_edit(mem, file, spec.step, 0, history_mode);
file_pre_edit_maintenance(file); file_pre_edit_maintenance(file);
// NOTE(allen): actual text replacement // NOTE(allen): actual text replacement
@ -2600,8 +2602,10 @@ view_replace_range(Mem_Options *mem, File_View *view, Editing_Layout *layout,
spec.step.edit.start = start; spec.step.edit.start = start;
spec.step.edit.end = end; spec.step.edit.end = end;
spec.step.edit.len = len; spec.step.edit.len = len;
spec.step.pre_pos = view->cursor.pos;
spec.step.post_pos = next_cursor;
spec.str = str; spec.str = str;
view_do_single_edit(mem, view, view->file, layout, spec, hist_normal, next_cursor); view_do_single_edit(mem, view, view->file, layout, spec, hist_normal);
} }
internal void internal void
@ -2628,9 +2632,10 @@ view_undo_redo(Mem_Options *mem, Editing_Layout *layout, File_View *view, Editin
spec.step.edit.str_start = 0; spec.step.edit.str_start = 0;
spec.str = stack->strings + step.edit.str_start; spec.str = stack->strings + step.edit.str_start;
view_do_single_edit(mem, view, file, layout, spec, hist_normal, 0); view_do_single_edit(mem, view, file, layout, spec, hist_normal);
view_cursor_move(view, step.pre_pos); if (expected_type == ED_UNDO) view_cursor_move(view, step.pre_pos);
else view_cursor_move(view, step.post_pos);
view->mark = view->cursor.pos; view->mark = view->cursor.pos;
view_post_paste_effect(view, 10, step.edit.start, step.edit.len, view_post_paste_effect(view, 10, step.edit.start, step.edit.len,
@ -2686,7 +2691,7 @@ view_history_step(Mem_Options *mem, Editing_Layout *layout, File_View *view, His
spec.step.edit.str_start = 0; spec.step.edit.str_start = 0;
spec.str = file->undo.history.strings + step.edit.str_start; spec.str = file->undo.history.strings + step.edit.str_start;
view_do_single_edit(mem, view, file, layout, spec, history_mode, step.post_pos); view_do_single_edit(mem, view, file, layout, spec, history_mode);
switch (spec.step.type){ switch (spec.step.type){
case ED_NORMAL: case ED_NORMAL:
@ -2708,8 +2713,6 @@ view_history_step(Mem_Options *mem, Editing_Layout *layout, File_View *view, His
} }
} }
#endif
// TODO(allen): should these still be view operations? // TODO(allen): should these still be view operations?
internal i32 internal i32
view_find_end_of_line(File_View *view, i32 pos){ view_find_end_of_line(File_View *view, i32 pos){
@ -2848,12 +2851,36 @@ clipboard_copy(General_Memory *general, Working_Set *working, u8 *data, Range ra
system_post_clipboard(*dest); system_post_clipboard(*dest);
} }
enum Endline_Convert_Type{ internal Edit_Spec
ENDLINE_RN, view_compute_whitespace_edit(Mem_Options *mem, Editing_File *file,
ENDLINE_N, Buffer_Edit *edits, char *str_base, i32 str_size,
ENDLINE_R, Buffer_Edit *inverse_array, char *inv_str, i32 inv_max,
ENDLINE_ERASE, i32 edit_count){
}; General_Memory *general = &mem->general;
i32 inv_str_pos = 0;
Buffer_Invert_Batch state = {};
if (buffer_invert_batch(&state, &file->buffer, edits, edit_count,
inverse_array, inv_str, &inv_str_pos, inv_max))
Assert(0);
i32 first_child =
undo_children_push(general, &file->undo.children,
edits, edit_count, (u8*)(str_base), str_size);
i32 inverse_first_child =
undo_children_push(general, &file->undo.children,
inverse_array, edit_count, (u8*)(inv_str), inv_str_pos);
Edit_Spec spec = {};
spec.step.type = ED_NORMAL;
spec.step.first_child = first_child;
spec.step.inverse_first_child = inverse_first_child;
spec.step.special_type = 1;
spec.step.child_count = edit_count;
spec.step.inverse_child_count = edit_count;
return spec;
}
internal void internal void
view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout){ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout){
@ -2876,7 +2903,8 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout)
bool32 all_whitespace = 0; bool32 all_whitespace = 0;
bool32 all_space = 0; bool32 all_space = 0;
i32 hard_start = i32 hard_start =
buffer_find_hard_start(&file->buffer, start, &all_whitespace, &all_space, &preferred_indentation, 4); buffer_find_hard_start(&file->buffer, start, &all_whitespace, &all_space,
&preferred_indentation, 4);
if (all_whitespace) preferred_indentation = 0; if (all_whitespace) preferred_indentation = 0;
@ -2902,27 +2930,134 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout)
Assert(inverse_array); Assert(inverse_array);
char *inv_str = (char*)part->base + part->pos; char *inv_str = (char*)part->base + part->pos;
i32 inv_str_pos = 0; Edit_Spec spec =
Buffer_Invert_Batch state = {}; view_compute_whitespace_edit(mem, file, edits, str_base, str_size,
if (buffer_invert_batch(&state, &file->buffer, edits, edit_count, inverse_array, inv_str, part->max - part->pos, edit_count);
inverse_array, inv_str, &inv_str_pos, part->max - part->pos))
Assert(0);
General_Memory *general = &mem->general; view_do_white_batch_edit(mem, view, file, layout, spec, hist_normal);
i32 first_child = }
undo_children_push(general, &file->undo.children,
edits, edit_count, (u8*)(str_base), str_size);
i32 inverse_first_child =
undo_children_push(general, &file->undo.children,
inverse_array, edit_count, (u8*)(inv_str), inv_str_pos);
Edit_Spec spec = {}; end_temp_memory(temp);
spec.step.type = ED_NORMAL; #endif
spec.step.first_child = first_child; }
spec.step.inverse_first_child = inverse_first_child;
spec.step.special_type = 1; internal void
spec.step.child_count = edit_count; view_auto_tab_tokens(Mem_Options *mem, File_View *view, Editing_Layout *layout,
spec.step.inverse_child_count = edit_count; i32 start, i32 end, b32 empty_blank_lines){
#if BUFFER_EXPERIMENT_SCALPEL
Editing_File *file = view->file;
Assert(file && !file->is_dummy);
Partition *part = &mem->part;
Buffer *buffer = &file->buffer;
Cpp_Token_Stack tokens = file->token_stack;
Assert(tokens.tokens);
i32 line_start = buffer_get_line_index(buffer, start);
i32 line_end = buffer_get_line_index(buffer, end) + 1;
i32 edit_max = (line_end - line_start) * 2;
i32 edit_count = 0;
i32 indent_mark_count = line_end - line_start;
Temp_Memory temp = begin_temp_memory(part);
i32 *indent_marks = push_array(part, i32, indent_mark_count);
{
i32 current_indent = 0;
i32 line;
for (line = line_start - 1; line >= 0; --line){
i32 start = file->buffer.line_starts[line];
b32 all_whitespace = 0;
b32 all_space = 0;
buffer_find_hard_start(&file->buffer, start, &all_whitespace, &all_space, &current_indent, 4);
if (!all_whitespace) break;
}
if (line < 0) line = 0;
i32 start_pos = file->buffer.line_starts[line];
Cpp_Get_Token_Result result = cpp_get_token(&tokens, start_pos);
i32 start_token;
if (result.in_whitespace) start_token = result.token_index + 1;
else start_token = result.token_index;
indent_marks -= line_start;
i32 line_i = line_start;
i32 next_line_start = file->buffer.line_starts[line_i];
Cpp_Token *token = tokens.tokens + start_token;
switch (token->type){
case CPP_TOKEN_BRACKET_OPEN: current_indent += 4; break;
case CPP_TOKEN_PARENTHESE_OPEN: current_indent += 4; break;
case CPP_TOKEN_BRACE_OPEN: current_indent += 4; break;
}
++token;
for (i32 token_i = start_token + 1; line_i < line_end; ++token_i, ++token){
for (; token->start >= next_line_start && line_i < line_end;){
next_line_start = file->buffer.line_starts[line_i+1];
i32 this_indent = current_indent;
if (token->start < next_line_start){
switch (token->type){
case CPP_TOKEN_BRACKET_CLOSE: this_indent -= 4; break;
case CPP_TOKEN_PARENTHESE_CLOSE: this_indent -= 4; break;
case CPP_TOKEN_BRACE_CLOSE: this_indent -= 4; break;
}
}
if (this_indent < 0) this_indent = 0;
indent_marks[line_i] = this_indent;
++line_i;
}
switch (token->type){
case CPP_TOKEN_BRACKET_OPEN: current_indent += 4; break;
case CPP_TOKEN_BRACKET_CLOSE: current_indent -= 4; break;
case CPP_TOKEN_PARENTHESE_OPEN: current_indent += 4; break;
case CPP_TOKEN_PARENTHESE_CLOSE: current_indent -= 4; break;
case CPP_TOKEN_BRACE_OPEN: current_indent += 4; break;
case CPP_TOKEN_BRACE_CLOSE: current_indent -= 4; break;
}
}
}
Buffer_Edit *edits = push_array(part, Buffer_Edit, edit_max);
char *str_base = (char*)part->base + part->pos;
i32 str_size = 0;
for (i32 line_i = line_start; line_i < line_end; ++line_i){
i32 start = file->buffer.line_starts[line_i];
i32 preferred_indentation;
i32 correct_indentation;
bool32 all_whitespace = 0;
bool32 all_space = 0;
i32 hard_start =
buffer_find_hard_start(&file->buffer, start, &all_whitespace, &all_space,
&preferred_indentation, 4);
correct_indentation = indent_marks[line_i];
if (all_whitespace && empty_blank_lines) correct_indentation = 0;
if ((all_whitespace && hard_start > start) || !all_space || correct_indentation != preferred_indentation){
Buffer_Edit new_edit;
new_edit.str_start = str_size;
str_size += correct_indentation;
char *str = push_array(part, char, correct_indentation);
for (i32 j = 0; j < correct_indentation; ++j) str[j] = ' ';
new_edit.len = correct_indentation;
new_edit.start = start;
new_edit.end = hard_start;
edits[edit_count++] = new_edit;
}
Assert(edit_count <= edit_max);
}
if (edit_count > 0){
Assert(buffer_batch_debug_sort_check(edits, edit_count));
// NOTE(allen): computing edit spec, doing batch edit
Buffer_Edit *inverse_array = push_array(part, Buffer_Edit, edit_count);
Assert(inverse_array);
char *inv_str = (char*)part->base + part->pos;
Edit_Spec spec =
view_compute_whitespace_edit(mem, file, edits, str_base, str_size,
inverse_array, inv_str, part->max - part->pos, edit_count);
view_do_white_batch_edit(mem, view, file, layout, spec, hist_normal); view_do_white_batch_edit(mem, view, file, layout, spec, hist_normal);
} }
@ -3518,6 +3653,7 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
u32 mark_color = style->main.mark_color; u32 mark_color = style->main.mark_color;
Buffer_Render_Item *item = items; Buffer_Render_Item *item = items;
i32 prev_ind = -1; i32 prev_ind = -1;
u32 highlight_color = 0;
for (i32 i = 0; i < count; ++i, ++item){ for (i32 i = 0; i < count; ++i, ++item){
i32 ind = item->index; i32 ind = item->index;
if (tokens_use && ind != prev_ind){ if (tokens_use && ind != prev_ind){

View File

@ -1112,19 +1112,10 @@ internal bool32
file_save(Partition *part, Editing_File *file, u8 *filename){ file_save(Partition *part, Editing_File *file, u8 *filename){
bool32 result = 0; bool32 result = 0;
Temp_Memory temp = begin_temp_memory(part); Temp_Memory temp = begin_temp_memory(part);
Buffer temp_buffer; i32 max = partition_remaining(part);
temp_buffer.max = partition_remaining(part); char *data = push_array(part, char, max);
temp_buffer.size = 0; i32 size = buffer_convert_out(&file->buffer, data, max);
temp_buffer.data = push_array(part, char, temp_buffer.max); result = system_save_file(filename, data, size);
// TODO(allen): What about using this stringify loop to convert out?
for (Buffer_Stringify_Loop loop = buffer_stringify_loop(&file->buffer, 0, file->buffer.size, file->buffer.size);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
memcpy(temp_buffer.data, loop.data, loop.size);
temp_buffer.size += loop.size;
buffer_eol_convert_out(&temp_buffer);
result = system_save_file(filename, temp_buffer.data, temp_buffer.size);
}
end_temp_memory(temp); end_temp_memory(temp);
file_synchronize_times(file, filename); file_synchronize_times(file, filename);
return result; return result;
@ -1352,8 +1343,7 @@ file_create_from_string(General_Memory *general, Editing_File *file, u8 *filenam
file->buffer.max = request_size; file->buffer.max = request_size;
if (val.size > 0){ if (val.size > 0){
memcpy(data, val.str, val.size); buffer_initialize(&file->buffer, val.str, val.size);
buffer_eol_convert_in(&file->buffer);
} }
data[val.size] = 0; data[val.size] = 0;

View File

@ -47,7 +47,7 @@ keycode_init(Key_Codes *codes, Key_Codes *loose_codes){
u16 code, loose = 0; u16 code, loose = 0;
switch (i){ switch (i){
case VK_SPACE: code = ' '; break; case VK_SPACE: code = loose = ' '; break;
case VK_BACK: code = loose = codes->back; break; case VK_BACK: code = loose = codes->back; break;
case VK_OEM_MINUS: code = '-'; break; case VK_OEM_MINUS: code = '-'; break;
case VK_OEM_PLUS: code = '='; break; case VK_OEM_PLUS: code = '='; break;
@ -60,8 +60,8 @@ keycode_init(Key_Codes *codes, Key_Codes *loose_codes){
case VK_OEM_5: code = '\\'; break; case VK_OEM_5: code = '\\'; break;
case VK_OEM_4: code = '['; break; case VK_OEM_4: code = '['; break;
case VK_OEM_6: code = ']'; break; case VK_OEM_6: code = ']'; break;
case VK_TAB: code = '\t'; break; case VK_TAB: code = loose = '\t'; break;
case VK_RETURN: code = '\n'; break; case VK_RETURN: code = loose = '\n'; break;
case VK_OEM_7: code = '\''; break; case VK_OEM_7: code = '\''; break;
case VK_OEM_1: code = ';'; break; case VK_OEM_1: code = ';'; break;

View File

@ -16,6 +16,36 @@
#define Buffer_Stringify_Type cat_4tech(Buffer_Type, _Stringify_Loop) #define Buffer_Stringify_Type cat_4tech(Buffer_Type, _Stringify_Loop)
#define Buffer_Backify_Type cat_4tech(Buffer_Type, _Backify_Loop) #define Buffer_Backify_Type cat_4tech(Buffer_Type, _Backify_Loop)
inline_4tech void
buffer_stringify(Buffer_Type *buffer, int start, int end, char *out){
for (Buffer_Stringify_Loop loop = buffer_stringify_loop(buffer, start, end, end - start);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
memcpy_4tech(out, loop.data, loop.size);
out += loop.size;
}
}
internal_4tech int
buffer_convert_out(Buffer_Type *buffer, char *dest, int max){
Buffer_Stringify_Type loop;
int size, out_size, pos, result;
size = buffer_size(buffer);
assert_4tech(size + buffer->line_count < max);
pos = 0;
for (loop = buffer_stringify_loop(buffer, 0, size, size);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
result = eol_convert_out(dest + pos, max - pos, loop.data, loop.size, &out_size);
assert_4tech(result);
pos += out_size;
}
return(pos);
}
internal_4tech int internal_4tech int
buffer_count_newlines(Buffer_Type *buffer, int start, int end){ buffer_count_newlines(Buffer_Type *buffer, int start, int end){
Buffer_Stringify_Type loop; Buffer_Stringify_Type loop;
@ -167,23 +197,31 @@ buffer_seek_whitespace_left(Buffer_Type *buffer, int pos){
int end; int end;
int size; int size;
size = buffer_size(buffer); --pos;
loop = buffer_backify_loop(buffer, pos, 0, size); if (pos > 0){
size = buffer_size(buffer);
loop = buffer_backify_loop(buffer, pos, 0, size);
for (;buffer_backify_good(&loop); for (;buffer_backify_good(&loop);
buffer_backify_next(&loop)){ buffer_backify_next(&loop)){
end = loop.absolute_pos; end = loop.absolute_pos;
data = loop.data - loop.absolute_pos; data = loop.data - loop.absolute_pos;
for (; pos >= end && is_whitespace(data[pos]); --pos); for (; pos >= end && is_whitespace(data[pos]); --pos);
if (!is_whitespace(data[pos])) break; if (!is_whitespace(data[pos])) break;
}
for (;buffer_backify_good(&loop);
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos >= end && !is_whitespace(data[pos]); --pos);
if (is_whitespace(data[pos])) break;
}
if (pos != 0) ++pos;
} }
else{
for (;buffer_backify_good(&loop); pos = 0;
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos >= end && is_whitespace(data[pos]); --pos);
if (!is_whitespace(data[pos])) break;
} }
return(pos); return(pos);
@ -456,7 +494,7 @@ buffer_measure_wrap_y(Buffer_Type *buffer, float *wraps,
} }
internal_4tech int internal_4tech int
buffer_get_line_index(Buffer_Type *buffer, int pos, int l_bound, int u_bound){ buffer_get_line_index_range(Buffer_Type *buffer, int pos, int l_bound, int u_bound){
int *lines; int *lines;
int start, end; int start, end;
int i; int i;
@ -484,6 +522,13 @@ buffer_get_line_index(Buffer_Type *buffer, int pos, int l_bound, int u_bound){
return(start); return(start);
} }
inline_4tech int
buffer_get_line_index(Buffer_Type *buffer, int pos){
int result;
result = buffer_get_line_index_range(buffer, pos, 0, buffer->line_count);
return(result);
}
#ifndef NON_ABSTRACT_4TECH #ifndef NON_ABSTRACT_4TECH
internal_4tech int internal_4tech int
buffer_get_line_index_from_wrapped_y(float *wraps, float y, float font_height, int l_bound, int u_bound){ buffer_get_line_index_from_wrapped_y(float *wraps, float y, float font_height, int l_bound, int u_bound){
@ -666,7 +711,7 @@ buffer_cursor_from_pos(Buffer_Type *buffer, int pos, float *wraps,
Full_Cursor result; Full_Cursor result;
int line_index; int line_index;
line_index = buffer_get_line_index(buffer, pos, 0, buffer->line_count); line_index = buffer_get_line_index_range(buffer, pos, 0, buffer->line_count);
result = make_cursor_hint(line_index, buffer->line_starts, wraps, font_height); result = make_cursor_hint(line_index, buffer->line_starts, wraps, font_height);
result = buffer_cursor_seek(buffer, seek_pos(pos), max_width, font_height, result = buffer_cursor_seek(buffer, seek_pos(pos), max_width, font_height,
advance_data, stride, result); advance_data, stride, result);

View File

@ -124,16 +124,6 @@ buffer_backify_next(Buffer_Backify_Loop *loop){
} }
} }
inline_4tech void
buffer_stringify(Buffer *buffer, int start, int end, char *out){
for (Buffer_Stringify_Loop loop = buffer_stringify_loop(buffer, start, end, end - start);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
memcpy_4tech(out, loop.data, loop.size);
out += loop.size;
}
}
internal_4tech int internal_4tech int
buffer_replace_range(Buffer *buffer, int start, int end, char *str, int len, int *shift_amount){ buffer_replace_range(Buffer *buffer, int start, int end, char *str, int len, int *shift_amount){
char *data; char *data;
@ -289,13 +279,5 @@ buffer_find_hard_start(Buffer *buffer, int line_start, int *all_whitespace, int
return(result); return(result);
} }
internal_4tech void
buffer_eol_convert_out(Buffer *buffer){
int size;
assert_4tech(buffer_eol_convert_out_size(buffer) < buffer->max);
eol_convert_out(buffer->data, buffer->size, buffer->max, &size);
buffer->size = size;
}
// BOTTOM // BOTTOM

View File

@ -54,7 +54,7 @@
#define FPS 30 #define FPS 30
#define FRAME_TIME (1000000 / FPS) #define FRAME_TIME (1000000 / FPS)
#define BUFFER_EXPERIMENT_SCALPEL 0 #define BUFFER_EXPERIMENT_SCALPEL 1
#include "4ed_meta.h" #include "4ed_meta.h"
@ -93,11 +93,7 @@ struct Sys_Bubble : public Bubble{
#include "4ed_command.cpp" #include "4ed_command.cpp"
#include "4ed_layout.cpp" #include "4ed_layout.cpp"
#include "4ed_style.cpp" #include "4ed_style.cpp"
#if BUFFER_EXPERIMENT_SCALPEL
#include "4ed_file_view_golden_array.cpp"
#else
#include "4ed_file_view.cpp" #include "4ed_file_view.cpp"
#endif
#include "4ed_color_view.cpp" #include "4ed_color_view.cpp"
#include "4ed_interactive_view.cpp" #include "4ed_interactive_view.cpp"
#include "4ed_menu_view.cpp" #include "4ed_menu_view.cpp"