Undo fade out

master
Allen Webster 2020-05-03 08:00:28 -07:00
parent 33933da218
commit c4e47935d4
15 changed files with 175 additions and 35 deletions

View File

@ -13,6 +13,7 @@ function void
output_file_append(Thread_Context *tctx, Models *models, Editing_File *file, String_Const_u8 value){ output_file_append(Thread_Context *tctx, Models *models, Editing_File *file, String_Const_u8 value){
i64 end = buffer_size(&file->state.buffer); i64 end = buffer_size(&file->state.buffer);
Edit_Behaviors behaviors = {}; Edit_Behaviors behaviors = {};
behaviors.pos_before_edit = end;
edit_single(tctx, models, file, Ii64(end), value, behaviors); edit_single(tctx, models, file, Ii64(end), value, behaviors);
} }
@ -237,6 +238,22 @@ buffer_read_range(Application_Links *app, Buffer_ID buffer_id, Range_i64 range,
return(result); return(result);
} }
function Edit_Behaviors
get_active_edit_behaviors(Models *models, Editing_File *file){
Panel *panel = layout_get_active_panel(&models->layout);
Assert(panel != 0);
View *view = panel->view;
Assert(view != 0);
Edit_Behaviors behaviors = {};
if (view->file == file){
behaviors.pos_before_edit = view->edit_pos_.cursor_pos;
}
else{
behaviors.pos_before_edit = -1;
}
return(behaviors);
}
api(custom) function b32 api(custom) function b32
buffer_replace_range(Application_Links *app, Buffer_ID buffer_id, Range_i64 range, String_Const_u8 string) buffer_replace_range(Application_Links *app, Buffer_ID buffer_id, Range_i64 range, String_Const_u8 string)
{ {
@ -246,7 +263,7 @@ buffer_replace_range(Application_Links *app, Buffer_ID buffer_id, Range_i64 rang
if (api_check_buffer(file)){ if (api_check_buffer(file)){
i64 size = buffer_size(&file->state.buffer); i64 size = buffer_size(&file->state.buffer);
if (0 <= range.first && range.first <= range.one_past_last && range.one_past_last <= size){ if (0 <= range.first && range.first <= range.one_past_last && range.one_past_last <= size){
Edit_Behaviors behaviors = {}; Edit_Behaviors behaviors = get_active_edit_behaviors(models, file);
edit_single(app->tctx, models, file, range, string, behaviors); edit_single(app->tctx, models, file, range, string, behaviors);
result = true; result = true;
} }
@ -261,7 +278,7 @@ buffer_batch_edit(Application_Links *app, Buffer_ID buffer_id, Batch_Edit *batch
Editing_File *file = imp_get_file(models, buffer_id); Editing_File *file = imp_get_file(models, buffer_id);
b32 result = false; b32 result = false;
if (api_check_buffer(file)){ if (api_check_buffer(file)){
Edit_Behaviors behaviors = {}; Edit_Behaviors behaviors = get_active_edit_behaviors(models, file);
result = edit_batch(app->tctx, models, file, batch, behaviors); result = edit_batch(app->tctx, models, file, batch, behaviors);
} }
return(result); return(result);
@ -2422,6 +2439,7 @@ buffer_history_get_max_record_index(Application_Links *app, Buffer_ID buffer_id)
function void function void
buffer_history__fill_record_info(Record *record, Record_Info *out){ buffer_history__fill_record_info(Record *record, Record_Info *out){
out->kind = record->kind; out->kind = record->kind;
out->pos_before_edit = record->pos_before_edit;
out->edit_number = record->edit_number; out->edit_number = record->edit_number;
switch (out->kind){ switch (out->kind){
case RecordKind_Single: case RecordKind_Single:

View File

@ -239,7 +239,7 @@ edit__apply(Thread_Context *tctx, Models *models, Editing_File *file, Range_i64
if (!behaviors.do_not_post_to_history){ if (!behaviors.do_not_post_to_history){
ProfileTLBlock(tctx, &models->profile_list, "edit apply history"); ProfileTLBlock(tctx, &models->profile_list, "edit apply history");
history_record_edit(&models->global_history, &file->state.history, buffer, history_record_edit(&models->global_history, &file->state.history, buffer,
edit); behaviors.pos_before_edit, edit);
file->state.current_record_index = file->state.current_record_index =
history_get_record_count(&file->state.history); history_get_record_count(&file->state.history);
} }
@ -348,6 +348,7 @@ edit_change_current_history_state(Thread_Context *tctx, Models *models, Editing_
Edit_Behaviors behaviors_prototype = {}; Edit_Behaviors behaviors_prototype = {};
behaviors_prototype.do_not_post_to_history = true; behaviors_prototype.do_not_post_to_history = true;
behaviors_prototype.pos_before_edit = -1;
if (current < target_index){ if (current < target_index){
do{ do{

View File

@ -14,6 +14,7 @@
struct Edit_Behaviors{ struct Edit_Behaviors{
b32 do_not_post_to_history; b32 do_not_post_to_history;
i64 pos_before_edit;
}; };
#endif #endif

View File

@ -241,7 +241,8 @@ history__free_nodes(History *history, i32 first_index, Node *first_node, Node *l
} }
internal void internal void
history_record_edit(Global_History *global_history, History *history, Gap_Buffer *buffer, Edit edit){ history_record_edit(Global_History *global_history, History *history, Gap_Buffer *buffer,
i64 pos_before_edit, Edit edit){
if (history->activated){ if (history->activated){
Assert(history->record_lookup.count == history->record_count); Assert(history->record_lookup.count == history->record_count);
@ -249,6 +250,13 @@ history_record_edit(Global_History *global_history, History *history, Gap_Buffer
history__stash_record(history, new_record); history__stash_record(history, new_record);
new_record->restore_point = begin_temp(&history->arena); new_record->restore_point = begin_temp(&history->arena);
if (pos_before_edit >= 0){
new_record->pos_before_edit = pos_before_edit;
}
else{
new_record->pos_before_edit = edit.range.min;
}
new_record->edit_number = global_history_get_edit_number(global_history); new_record->edit_number = global_history_get_edit_number(global_history);
new_record->kind = RecordKind_Single; new_record->kind = RecordKind_Single;
@ -294,6 +302,7 @@ history__optimize_group(Arena *scratch, History *history, Record *record){
if (record->group.count == 1){ if (record->group.count == 1){
Record *child = right; Record *child = right;
record->restore_point = child->restore_point; record->restore_point = child->restore_point;
record->pos_before_edit = child->pos_before_edit;
record->edit_number = child->edit_number; record->edit_number = child->edit_number;
record->kind = RecordKind_Single; record->kind = RecordKind_Single;
record->single = child->single; record->single = child->single;
@ -383,6 +392,7 @@ history_merge_records(Arena *scratch, History *history, i32 first_index, i32 las
Record *last_record = CastFromMember(Record, node, last_node); Record *last_record = CastFromMember(Record, node, last_node);
new_record->restore_point = first_record->restore_point; new_record->restore_point = first_record->restore_point;
new_record->pos_before_edit = first_record->pos_before_edit;
new_record->edit_number = last_record->edit_number; new_record->edit_number = last_record->edit_number;
new_record->kind = RecordKind_Group; new_record->kind = RecordKind_Group;

View File

@ -21,6 +21,7 @@ struct Record_Batch_Slot{
struct Record{ struct Record{
Node node; Node node;
Temp_Memory restore_point; Temp_Memory restore_point;
i64 pos_before_edit;
i32 edit_number; i32 edit_number;
Record_Kind kind; Record_Kind kind;
union{ union{

View File

@ -79,6 +79,9 @@ struct View{
f32 preferred_x; f32 preferred_x;
b8 new_scroll_target; b8 new_scroll_target;
b8 hide_scrollbar;
b8 hide_file_bar;
b8 show_whitespace;
Coroutine *co; Coroutine *co;
Co_Out co_out; Co_Out co_out;
@ -86,10 +89,6 @@ struct View{
Arena node_arena; Arena node_arena;
View_Context_Node *ctx; View_Context_Node *ctx;
b8 hide_scrollbar;
b8 hide_file_bar;
b8 show_whitespace;
Query_Set query_set; Query_Set query_set;
}; };

View File

@ -1700,9 +1700,10 @@ CUSTOM_DOC("Reopen the current buffer from the hard drive.")
//////////////////////////////// ////////////////////////////////
internal i32 internal i64
record_get_new_cursor_position_undo(Application_Links *app, Buffer_ID buffer_id, History_Record_Index index, Record_Info record){ record_get_new_cursor_position_undo(Application_Links *app, Buffer_ID buffer_id, History_Record_Index index, Record_Info record){
i32 new_edit_position = 0; i64 new_edit_position = record.pos_before_edit;
#if 0
switch (record.kind){ switch (record.kind){
default: default:
case RecordKind_Single: case RecordKind_Single:
@ -1715,16 +1716,17 @@ record_get_new_cursor_position_undo(Application_Links *app, Buffer_ID buffer_id,
new_edit_position = (i32)(sub_record.single_first + sub_record.single_string_backward.size); new_edit_position = (i32)(sub_record.single_first + sub_record.single_string_backward.size);
}break; }break;
} }
#endif
return(new_edit_position); return(new_edit_position);
} }
internal i32 internal i64
record_get_new_cursor_position_undo(Application_Links *app, Buffer_ID buffer_id, History_Record_Index index){ record_get_new_cursor_position_undo(Application_Links *app, Buffer_ID buffer_id, History_Record_Index index){
Record_Info record = buffer_history_get_record_info(app, buffer_id, index); Record_Info record = buffer_history_get_record_info(app, buffer_id, index);
return(record_get_new_cursor_position_undo(app, buffer_id, index, record)); return(record_get_new_cursor_position_undo(app, buffer_id, index, record));
} }
internal i32 internal i64
record_get_new_cursor_position_redo(Application_Links *app, Buffer_ID buffer_id, History_Record_Index index, Record_Info record){ record_get_new_cursor_position_redo(Application_Links *app, Buffer_ID buffer_id, History_Record_Index index, Record_Info record){
i64 new_edit_position = 0; i64 new_edit_position = 0;
switch (record.kind){ switch (record.kind){
@ -1742,21 +1744,80 @@ record_get_new_cursor_position_redo(Application_Links *app, Buffer_ID buffer_id,
return((i32)(new_edit_position)); return((i32)(new_edit_position));
} }
internal i32 internal i64
record_get_new_cursor_position_redo(Application_Links *app, Buffer_ID buffer_id, History_Record_Index index){ record_get_new_cursor_position_redo(Application_Links *app, Buffer_ID buffer_id, History_Record_Index index){
Record_Info record = buffer_history_get_record_info(app, buffer_id, index); Record_Info record = buffer_history_get_record_info(app, buffer_id, index);
return(record_get_new_cursor_position_redo(app, buffer_id, index, record)); return(record_get_new_cursor_position_redo(app, buffer_id, index, record));
} }
function void
undo__fade_finish(Application_Links *app, Fade_Range *range){
Buffer_ID buffer = range->buffer_id;
History_Record_Index current = buffer_history_get_current_state_index(app, buffer);
if (current > 0){
buffer_history_set_current_state_index(app, buffer, current - 1);
}
}
function void
undo__flush_fades(Application_Links *app, Buffer_ID buffer){
Fade_Range **prev_next = &buffer_fade_ranges.first;
for (Fade_Range *node = buffer_fade_ranges.first, *next = 0;
node != 0;
node = next){
next = node->next;
if (node->buffer_id == buffer &&
node->finish_call == undo__fade_finish){
undo__fade_finish(app, node);
*prev_next = next;
free_fade_range(node);
buffer_fade_ranges.count -= 1;
}
else{
prev_next = &node->next;
buffer_fade_ranges.last = node;
}
}
}
CUSTOM_COMMAND_SIG(undo) CUSTOM_COMMAND_SIG(undo)
CUSTOM_DOC("Advances backwards through the undo history of the current buffer.") CUSTOM_DOC("Advances backwards through the undo history of the current buffer.")
{ {
View_ID view = get_active_view(app, Access_ReadWriteVisible); View_ID view = get_active_view(app, Access_ReadWriteVisible);
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
undo__flush_fades(app, buffer);
History_Record_Index current = buffer_history_get_current_state_index(app, buffer); History_Record_Index current = buffer_history_get_current_state_index(app, buffer);
if (current > 0){ if (current > 0){
i32 new_position = record_get_new_cursor_position_undo(app, buffer, current); Record_Info record = buffer_history_get_record_info(app, buffer, current);
b32 do_immedite_undo = true;
f32 undo_fade_time = 0.33f;
if (undo_fade_time > 0.f &&
record.kind == RecordKind_Single &&
record.single_string_backward.size == 0){
b32 has_hard_character = false;
for (u64 i = 0; i < record.single_string_forward.size; i += 1){
if (!character_is_whitespace(record.single_string_forward.str[i])){
has_hard_character = true;
break;
}
}
if (has_hard_character){
Range_i64 range = Ii64_size(record.single_first, record.single_string_forward.size);
ARGB_Color color = fcolor_resolve(fcolor_id(defcolor_undo)) & 0xFFFFFF;
Fade_Range *fade = buffer_post_fade(app, buffer, undo_fade_time, range, color);
fade->negate_fade_direction = true;
fade->finish_call = undo__fade_finish;
do_immedite_undo = false;
}
}
if (do_immedite_undo){
buffer_history_set_current_state_index(app, buffer, current - 1); buffer_history_set_current_state_index(app, buffer, current - 1);
}
i64 new_position = record_get_new_cursor_position_undo(app, buffer, current, record);
view_set_cursor_and_preferred_x(app, view, seek_pos(new_position)); view_set_cursor_and_preferred_x(app, view, seek_pos(new_position));
} }
} }
@ -1769,7 +1830,7 @@ CUSTOM_DOC("Advances forwards through the undo history of the current buffer.")
History_Record_Index current = buffer_history_get_current_state_index(app, buffer); History_Record_Index current = buffer_history_get_current_state_index(app, buffer);
History_Record_Index max_index = buffer_history_get_max_record_index(app, buffer); History_Record_Index max_index = buffer_history_get_max_record_index(app, buffer);
if (current < max_index){ if (current < max_index){
i32 new_position = record_get_new_cursor_position_redo(app, buffer, current + 1); i64 new_position = record_get_new_cursor_position_redo(app, buffer, current + 1);
buffer_history_set_current_state_index(app, buffer, current + 1); buffer_history_set_current_state_index(app, buffer, current + 1);
view_set_cursor_and_preferred_x(app, view, seek_pos(new_position)); view_set_cursor_and_preferred_x(app, view, seek_pos(new_position));
} }
@ -1806,7 +1867,7 @@ CUSTOM_DOC("Advances backward through the undo history in the buffer containing
} }
Buffer_ID *match_buffers = push_array(scratch, Buffer_ID, match_count); Buffer_ID *match_buffers = push_array(scratch, Buffer_ID, match_count);
i32 *new_positions = push_array(scratch, i32, match_count); i64 *new_positions = push_array(scratch, i64, match_count);
match_count = 0; match_count = 0;
if (highest_edit_number != -1){ if (highest_edit_number != -1){
@ -1814,7 +1875,7 @@ CUSTOM_DOC("Advances backward through the undo history in the buffer containing
buffer != 0; buffer != 0;
buffer = get_buffer_next(app, buffer, Access_Always)){ buffer = get_buffer_next(app, buffer, Access_Always)){
b32 did_match = false; b32 did_match = false;
i32 new_edit_position = 0; i64 new_edit_position = 0;
for (;;){ for (;;){
History_Record_Index index = buffer_history_get_current_state_index(app, buffer); History_Record_Index index = buffer_history_get_current_state_index(app, buffer);
if (index > 0){ if (index > 0){
@ -1879,7 +1940,7 @@ CUSTOM_DOC("Advances forward through the undo history in the buffer containing t
} }
Buffer_ID *match_buffers = push_array(scratch, Buffer_ID, match_count); Buffer_ID *match_buffers = push_array(scratch, Buffer_ID, match_count);
i32 *new_positions = push_array(scratch, i32, match_count); i64 *new_positions = push_array(scratch, i64, match_count);
match_count = 0; match_count = 0;
if (lowest_edit_number != -1){ if (lowest_edit_number != -1){
@ -1887,7 +1948,7 @@ CUSTOM_DOC("Advances forward through the undo history in the buffer containing t
buffer != 0; buffer != 0;
buffer = get_buffer_next(app, buffer, Access_Always)){ buffer = get_buffer_next(app, buffer, Access_Always)){
b32 did_match = false; b32 did_match = false;
i32 new_edit_position = 0; i64 new_edit_position = 0;
History_Record_Index max_index = buffer_history_get_max_record_index(app, buffer); History_Record_Index max_index = buffer_history_get_max_record_index(app, buffer);
for (;;){ for (;;){
History_Record_Index index = buffer_history_get_current_state_index(app, buffer); History_Record_Index index = buffer_history_get_current_state_index(app, buffer);

View File

@ -2894,6 +2894,23 @@ SCu32(u32 *str){
return(string); return(string);
} }
function String_Const_char
SCchar(String_char string){
return(string.string);
}
function String_Const_u8
SCu8(String_u8 string){
return(string.string);
}
function String_Const_u16
SCu16(String_u16 string){
return(string.string);
}
function String_Const_u32
SCu32(String_u32 string){
return(string.string);
}
function String_Const_char function String_Const_char
SCchar(String_Const_u8 str){ SCchar(String_Const_u8 str){
return(SCchar((char*)str.str, str.size)); return(SCchar((char*)str.str, str.size));
@ -5332,6 +5349,11 @@ string_any_push(Arena *arena, u64 size, String_Encoding encoding){
return(string); return(string);
} }
#define push_string_u8 string_u8_push
#define push_string_u16 string_u16_push
#define push_string_u32 string_u32_push
#define push_string_u64 string_u64_push
function String_Const_char function String_Const_char
string_const_char_push(Arena *arena, u64 size){ string_const_char_push(Arena *arena, u64 size){
String_Const_char string = {}; String_Const_char string = {};
@ -5373,6 +5395,11 @@ string_const_any_push(Arena *arena, u64 size, String_Encoding encoding){
return(string); return(string);
} }
#define push_string_const_u8 string_const_u8_push
#define push_string_const_u16 string_const_u16_push
#define push_string_const_u32 string_const_u32_push
#define push_string_const_u64 string_const_u64_push
function String_Const_char function String_Const_char
push_string_copy(Arena *arena, String_Const_char src){ push_string_copy(Arena *arena, String_Const_char src){
String_Const_char string = {}; String_Const_char string = {};
@ -5641,6 +5668,11 @@ string_list_push_overlap(Arena *arena, List_String_Const_u32 *list, u32 overlap,
} }
} }
#define push_string_list string_list_push
#define push_string_list_lit(a,l,s) string_list_push_lit(a,l,s)
#define push_string_list_u8_lit(a,l,s) string_list_u8_push_lit(a,l,s)
#define push_string_list_overlap(a,l,o,s) string_list_push_overlap(a,l,o,s)
typedef String_Const_char String_char_Mod_Function_Type(String_Const_char string); typedef String_Const_char String_char_Mod_Function_Type(String_Const_char string);
typedef String_Const_u8 String_u8_Mod_Function_Type(String_Const_u8 string); typedef String_Const_u8 String_u8_Mod_Function_Type(String_Const_u8 string);
typedef String_Const_u16 String_u16_Mod_Function_Type(String_Const_u16 string); typedef String_Const_u16 String_u16_Mod_Function_Type(String_Const_u16 string);

View File

@ -219,7 +219,7 @@ ui_fallback_command_dispatch(Application_Links *app, View_ID view, User_Input *i
//////////////////////////////// ////////////////////////////////
function void function void
view_buffer_set(Application_Links *app, Buffer_ID *buffers, i32 *positions, i32 count){ view_buffer_set(Application_Links *app, Buffer_ID *buffers, i64 *positions, i32 count){
if (count > 0){ if (count > 0){
Scratch_Block scratch(app); Scratch_Block scratch(app);
@ -696,6 +696,7 @@ alloc_fade_range(void){
else{ else{
sll_stack_pop(free_fade_ranges); sll_stack_pop(free_fade_ranges);
} }
block_zero_struct(result);
return(result); return(result);
} }
@ -704,7 +705,7 @@ free_fade_range(Fade_Range *range){
sll_stack_push(free_fade_ranges, range); sll_stack_push(free_fade_ranges, range);
} }
function void function Fade_Range*
buffer_post_fade(Application_Links *app, Buffer_ID buffer_id, f32 seconds, Range_i64 range, ARGB_Color color){ buffer_post_fade(Application_Links *app, Buffer_ID buffer_id, f32 seconds, Range_i64 range, ARGB_Color color){
Fade_Range *fade_range = alloc_fade_range(); Fade_Range *fade_range = alloc_fade_range();
sll_queue_push(buffer_fade_ranges.first, buffer_fade_ranges.last, fade_range); sll_queue_push(buffer_fade_ranges.first, buffer_fade_ranges.last, fade_range);
@ -713,7 +714,8 @@ buffer_post_fade(Application_Links *app, Buffer_ID buffer_id, f32 seconds, Range
fade_range->t = seconds; fade_range->t = seconds;
fade_range->full_t = seconds; fade_range->full_t = seconds;
fade_range->range = range; fade_range->range = range;
fade_range->color= color; fade_range->color = color;
return(fade_range);
} }
function void function void
@ -734,7 +736,7 @@ buffer_shift_fade_ranges(Buffer_ID buffer_id, i64 shift_after_p, i64 shift_amoun
} }
function b32 function b32
tick_all_fade_ranges(f32 t){ tick_all_fade_ranges(Application_Links *app, f32 t){
Fade_Range **prev_next = &buffer_fade_ranges.first; Fade_Range **prev_next = &buffer_fade_ranges.first;
for (Fade_Range *node = buffer_fade_ranges.first, *next = 0; for (Fade_Range *node = buffer_fade_ranges.first, *next = 0;
node != 0; node != 0;
@ -742,7 +744,11 @@ tick_all_fade_ranges(f32 t){
next = node->next; next = node->next;
node->t -= t; node->t -= t;
if (node->t <= 0.f){ if (node->t <= 0.f){
if (node->finish_call != 0){
node->finish_call(app, node);
}
*prev_next = next; *prev_next = next;
free_fade_range(node);
buffer_fade_ranges.count -= 1; buffer_fade_ranges.count -= 1;
} }
else{ else{
@ -750,7 +756,7 @@ tick_all_fade_ranges(f32 t){
buffer_fade_ranges.last = node; buffer_fade_ranges.last = node;
} }
} }
return(buffer_fade_ranges.count > 0 || view_fade_ranges.count > 0); return(buffer_fade_ranges.count > 0);
} }
function void function void
@ -759,7 +765,11 @@ paint_fade_ranges(Application_Links *app, Text_Layout_ID layout, Buffer_ID buffe
node != 0; node != 0;
node = node->next){ node = node->next){
if (node->buffer_id == buffer){ if (node->buffer_id == buffer){
paint_text_color_blend(app, layout, node->range, node->color, node->t/node->full_t); f32 blend = node->t/node->full_t;
if (node->negate_fade_direction){
blend = 1.f - blend;
}
paint_text_color_blend(app, layout, node->range, node->color, blend);
} }
} }
} }

View File

@ -101,8 +101,12 @@ struct Fade_Range{
Buffer_ID buffer_id; Buffer_ID buffer_id;
f32 t; f32 t;
f32 full_t; f32 full_t;
Range_i64 range;
ARGB_Color color; ARGB_Color color;
b32 negate_fade_direction;
Range_i64 range;
void (*finish_call)(Application_Links *app, struct Fade_Range *range);
void *opaque[4];
}; };
struct Fade_Range_List{ struct Fade_Range_List{

View File

@ -96,7 +96,6 @@ global Range_i64 global_keyboard_macro_range = {};
//////////////////////////////// ////////////////////////////////
global Fade_Range_List buffer_fade_ranges = {}; global Fade_Range_List buffer_fade_ranges = {};
global Fade_Range_List view_fade_ranges = {};
global Arena fade_range_arena = {}; global Arena fade_range_arena = {};
global Fade_Range *free_fade_ranges = 0; global Fade_Range *free_fade_ranges = 0;

View File

@ -188,7 +188,7 @@ code_index_update_tick(Application_Links *app){
function void function void
default_tick(Application_Links *app, Frame_Info frame_info){ default_tick(Application_Links *app, Frame_Info frame_info){
code_index_update_tick(app); code_index_update_tick(app);
if (tick_all_fade_ranges(frame_info.animation_dt)){ if (tick_all_fade_ranges(app, frame_info.animation_dt)){
animate_in_n_milliseconds(app, 0); animate_in_n_milliseconds(app, 0);
} }
} }

View File

@ -598,6 +598,7 @@ api(custom)
struct Record_Info{ struct Record_Info{
Record_Error error; Record_Error error;
Record_Kind kind; Record_Kind kind;
i64 pos_before_edit;
i32 edit_number; i32 edit_number;
union{ union{
struct{ struct{

View File

@ -302,7 +302,7 @@ static Command_Metadata fcoder_metacmd_table[245] = {
{ PROC_LINKS(custom_api_documentation, 0), true, "custom_api_documentation", 24, "Prompts the user to select a Custom API item then loads a doc buffer for that item", 82, "w:\\4ed\\code\\custom\\4coder_docs.cpp", 34, 175 }, { PROC_LINKS(custom_api_documentation, 0), true, "custom_api_documentation", 24, "Prompts the user to select a Custom API item then loads a doc buffer for that item", 82, "w:\\4ed\\code\\custom\\4coder_docs.cpp", 34, 175 },
{ PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 116 }, { PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 116 },
{ PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 754 }, { PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 754 },
{ PROC_LINKS(default_file_externally_modified, 0), false, "default_file_externally_modified", 32, "Notes the external modification of attached files by printing a message.", 72, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1931 }, { PROC_LINKS(default_file_externally_modified, 0), false, "default_file_externally_modified", 32, "Notes the external modification of attached files by printing a message.", 72, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1992 },
{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 7 }, { PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 7 },
{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 23 }, { PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 23 },
{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 51 }, { PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 51 },
@ -407,7 +407,7 @@ static Command_Metadata fcoder_metacmd_table[245] = {
{ PROC_LINKS(open_all_code, 0), false, "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 850 }, { PROC_LINKS(open_all_code, 0), false, "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 850 },
{ PROC_LINKS(open_all_code_recursive, 0), false, "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 856 }, { PROC_LINKS(open_all_code_recursive, 0), false, "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 856 },
{ PROC_LINKS(open_file_in_quotes, 0), false, "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1576 }, { PROC_LINKS(open_file_in_quotes, 0), false, "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1576 },
{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1925 }, { PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1986 },
{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 46 }, { PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 46 },
{ PROC_LINKS(open_long_braces_break, 0), false, "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 62 }, { PROC_LINKS(open_long_braces_break, 0), false, "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 62 },
{ PROC_LINKS(open_long_braces_semicolon, 0), false, "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 54 }, { PROC_LINKS(open_long_braces_semicolon, 0), false, "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 54 },
@ -433,8 +433,8 @@ static Command_Metadata fcoder_metacmd_table[245] = {
{ PROC_LINKS(query_replace_identifier, 0), false, "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1288 }, { PROC_LINKS(query_replace_identifier, 0), false, "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1288 },
{ PROC_LINKS(query_replace_selection, 0), false, "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1304 }, { PROC_LINKS(query_replace_selection, 0), false, "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1304 },
{ PROC_LINKS(quick_swap_buffer, 0), false, "quick_swap_buffer", 17, "Change to the most recently used buffer in this view - or to the top of the buffer stack if the most recent doesn't exist anymore", 129, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1655 }, { PROC_LINKS(quick_swap_buffer, 0), false, "quick_swap_buffer", 17, "Change to the most recently used buffer in this view - or to the top of the buffer stack if the most recent doesn't exist anymore", 129, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1655 },
{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1764 }, { PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1825 },
{ PROC_LINKS(redo_all_buffers, 0), false, "redo_all_buffers", 16, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1849 }, { PROC_LINKS(redo_all_buffers, 0), false, "redo_all_buffers", 16, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1910 },
{ PROC_LINKS(rename_file_query, 0), false, "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1416 }, { PROC_LINKS(rename_file_query, 0), false, "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1416 },
{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1693 }, { PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1693 },
{ PROC_LINKS(replace_in_all_buffers, 0), false, "replace_in_all_buffers", 22, "Queries the user for a needle and string. Replaces all occurences of needle with string in all editable buffers.", 112, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1177 }, { PROC_LINKS(replace_in_all_buffers, 0), false, "replace_in_all_buffers", 22, "Queries the user for a needle and string. Replaces all occurences of needle with string in all editable buffers.", 112, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1177 },
@ -497,8 +497,8 @@ static Command_Metadata fcoder_metacmd_table[245] = {
{ PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 20 }, { PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 20 },
{ PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 34 }, { PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 34 },
{ PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 137 }, { PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 137 },
{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1751 }, { PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1783 },
{ PROC_LINKS(undo_all_buffers, 0), false, "undo_all_buffers", 16, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1778 }, { PROC_LINKS(undo_all_buffers, 0), false, "undo_all_buffers", 16, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1839 },
{ PROC_LINKS(view_buffer_other_panel, 0), false, "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1621 }, { PROC_LINKS(view_buffer_other_panel, 0), false, "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1621 },
{ PROC_LINKS(view_jump_list_with_lister, 0), false, "view_jump_list_with_lister", 26, "When executed on a buffer with jumps, creates a persistent lister for all the jumps", 83, "w:\\4ed\\code\\custom\\4coder_jump_lister.cpp", 41, 59 }, { PROC_LINKS(view_jump_list_with_lister, 0), false, "view_jump_list_with_lister", 26, "When executed on a buffer with jumps, creates a persistent lister for all the jumps", 83, "w:\\4ed\\code\\custom\\4coder_jump_lister.cpp", 41, 59 },
{ PROC_LINKS(word_complete, 0), false, "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 397 }, { PROC_LINKS(word_complete, 0), false, "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 397 },

View File

@ -11,6 +11,9 @@
+ The lister text field keeps the right hand side in view when the string gets too long to fit + The lister text field keeps the right hand side in view when the string gets too long to fit
+ Hook called whenever a view's buffer is changed + Hook called whenever a view's buffer is changed
+ 'quick_swap_buffer` command bound to [ Backslash Alt ] and on mac [ Backslash Command ] + 'quick_swap_buffer` command bound to [ Backslash Alt ] and on mac [ Backslash Command ]
+ Record_Info now reports a pos_before_edit member - which is not gauranteed to be accurate but is when it can be,
and when it can't be is based at the first character of the edit range
+ When undoing a string it briefly fades away if there is nothing to replace it
+ Fix: when generated/metadata* files are missing buildsuper still succeeds + Fix: when generated/metadata* files are missing buildsuper still succeeds
+ Fix: mac does not hang opening multiple files + Fix: mac does not hang opening multiple files
+ Fix: line number margin performance + Fix: line number margin performance