Undo/Redo cursor positioning fixed
This commit is contained in:
parent
3f3a31b114
commit
2c381917fd
|
@ -972,7 +972,6 @@ STRUCT Buffer_Batch_Edit{
|
|||
|
||||
ENUM(i32, Record_Kind){
|
||||
RecordKind_Single,
|
||||
RecordKind_Batch,
|
||||
RecordKind_Group,
|
||||
};
|
||||
|
||||
|
@ -1003,10 +1002,6 @@ STRUCT Record_Info{
|
|||
String string_backward;
|
||||
i32 first;
|
||||
} single;
|
||||
struct{
|
||||
Buffer_Batch_Edit_Type type;
|
||||
i32 count;
|
||||
} batch;
|
||||
struct{
|
||||
i32 count;
|
||||
} group;
|
||||
|
|
|
@ -1622,6 +1622,58 @@ CUSTOM_DOC("Reopen the current buffer from the hard drive.")
|
|||
|
||||
////////////////////////////////
|
||||
|
||||
static i32
|
||||
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;
|
||||
switch (record.kind){
|
||||
default:
|
||||
case RecordKind_Single:
|
||||
{
|
||||
new_edit_position = record.single.first + record.single.string_backward.size;
|
||||
}break;
|
||||
case RecordKind_Group:
|
||||
{
|
||||
Record_Info sub_record = {};
|
||||
buffer_history_get_group_sub_record(app, buffer_id, index, 0, &sub_record);
|
||||
new_edit_position = sub_record.single.first + sub_record.single.string_backward.size;
|
||||
}break;
|
||||
}
|
||||
return(new_edit_position);
|
||||
}
|
||||
|
||||
static i32
|
||||
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);
|
||||
return(record_get_new_cursor_position_undo(app, buffer_id, index, record));
|
||||
}
|
||||
|
||||
static i32
|
||||
record_get_new_cursor_position_redo(Application_Links *app, Buffer_ID buffer_id, History_Record_Index index, Record_Info record){
|
||||
i32 new_edit_position = 0;
|
||||
switch (record.kind){
|
||||
default:
|
||||
case RecordKind_Single:
|
||||
{
|
||||
new_edit_position = record.single.first + record.single.string_forward.size;
|
||||
}break;
|
||||
case RecordKind_Group:
|
||||
{
|
||||
Record_Info sub_record = {};
|
||||
buffer_history_get_group_sub_record(app, buffer_id, index, record.group.count - 1, &sub_record);
|
||||
new_edit_position = sub_record.single.first + sub_record.single.string_forward.size;
|
||||
}break;
|
||||
}
|
||||
return(new_edit_position);
|
||||
}
|
||||
|
||||
static i32
|
||||
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);
|
||||
return(record_get_new_cursor_position_redo(app, buffer_id, index, record));
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(undo_this_buffer)
|
||||
CUSTOM_DOC("Advances backwards through the undo history of the current buffer.")
|
||||
{
|
||||
|
@ -1630,7 +1682,9 @@ CUSTOM_DOC("Advances backwards through the undo history of the current buffer.")
|
|||
History_Record_Index current = 0;
|
||||
buffer_history_get_current_state_index(app, buffer_id, ¤t);
|
||||
if (current > 0){
|
||||
i32 new_position = record_get_new_cursor_position_undo(app, buffer_id, current);
|
||||
buffer_history_set_current_state_index(app, buffer_id, current - 1);
|
||||
view_set_cursor(app, view.view_id, seek_pos(new_position), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1644,7 +1698,9 @@ CUSTOM_DOC("Advances forwards through the undo history of the current buffer.")
|
|||
buffer_history_get_current_state_index(app, buffer_id, ¤t);
|
||||
buffer_history_get_max_record_index(app, buffer_id, &max_index);
|
||||
if (current < max_index){
|
||||
i32 new_position = record_get_new_cursor_position_redo(app, buffer_id, current + 1);
|
||||
buffer_history_set_current_state_index(app, buffer_id, current + 1);
|
||||
view_set_cursor(app, view.view_id, seek_pos(new_position), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1680,6 +1736,7 @@ CUSTOM_DOC("Advances backward through the undo history in the buffer containing
|
|||
|
||||
Temp_Memory temp = begin_temp_memory(scratch);
|
||||
Buffer_ID *match_buffers = push_array(scratch, Buffer_ID, match_count);
|
||||
i32 *new_positions = push_array(scratch, i32, match_count);
|
||||
match_count = 0;
|
||||
|
||||
if (highest_edit_number != -1){
|
||||
|
@ -1687,6 +1744,7 @@ CUSTOM_DOC("Advances backward through the undo history in the buffer containing
|
|||
buffer.exists;
|
||||
get_buffer_next(app, &buffer, AccessAll)){
|
||||
b32 did_match = false;
|
||||
i32 new_edit_position = 0;
|
||||
for (;;){
|
||||
History_Record_Index index = 0;
|
||||
buffer_history_get_current_state_index(app, buffer.buffer_id, &index);
|
||||
|
@ -1695,6 +1753,7 @@ CUSTOM_DOC("Advances backward through the undo history in the buffer containing
|
|||
buffer_history_get_record_info(app, buffer.buffer_id, index, &record);
|
||||
if (record.edit_number == highest_edit_number){
|
||||
did_match = true;
|
||||
new_edit_position = record_get_new_cursor_position_undo(app, buffer.buffer_id, index, record);
|
||||
buffer_history_set_current_state_index(app, buffer.buffer_id, index - 1);
|
||||
}
|
||||
else{
|
||||
|
@ -1707,6 +1766,7 @@ CUSTOM_DOC("Advances backward through the undo history in the buffer containing
|
|||
}
|
||||
if (did_match){
|
||||
match_buffers[match_count] = buffer.buffer_id;
|
||||
new_positions[match_count] = new_edit_position;
|
||||
match_count += 1;
|
||||
}
|
||||
if (buffer.buffer_id == last_buffer_match){
|
||||
|
@ -1715,7 +1775,7 @@ CUSTOM_DOC("Advances backward through the undo history in the buffer containing
|
|||
}
|
||||
}
|
||||
|
||||
view_buffer_set(app, match_buffers, match_count);
|
||||
view_buffer_set(app, match_buffers, new_positions, match_count);
|
||||
|
||||
end_temp_memory(temp);
|
||||
}
|
||||
|
@ -1754,6 +1814,7 @@ CUSTOM_DOC("Advances forward through the undo history in the buffer containing t
|
|||
|
||||
Temp_Memory temp = begin_temp_memory(scratch);
|
||||
Buffer_ID *match_buffers = push_array(scratch, Buffer_ID, match_count);
|
||||
i32 *new_positions = push_array(scratch, i32, match_count);
|
||||
match_count = 0;
|
||||
|
||||
if (lowest_edit_number != -1){
|
||||
|
@ -1761,6 +1822,7 @@ CUSTOM_DOC("Advances forward through the undo history in the buffer containing t
|
|||
buffer.exists;
|
||||
get_buffer_next(app, &buffer, AccessAll)){
|
||||
b32 did_match = false;
|
||||
i32 new_edit_position = 0;
|
||||
History_Record_Index max_index = 0;
|
||||
buffer_history_get_max_record_index(app, buffer.buffer_id, &max_index);
|
||||
for (;;){
|
||||
|
@ -1771,6 +1833,7 @@ CUSTOM_DOC("Advances forward through the undo history in the buffer containing t
|
|||
buffer_history_get_record_info(app, buffer.buffer_id, index + 1, &record);
|
||||
if (record.edit_number == lowest_edit_number){
|
||||
did_match = true;
|
||||
new_edit_position = record_get_new_cursor_position_redo(app, buffer.buffer_id, index + 1, record);
|
||||
buffer_history_set_current_state_index(app, buffer.buffer_id, index + 1);
|
||||
}
|
||||
else{
|
||||
|
@ -1783,6 +1846,7 @@ CUSTOM_DOC("Advances forward through the undo history in the buffer containing t
|
|||
}
|
||||
if (did_match){
|
||||
match_buffers[match_count] = buffer.buffer_id;
|
||||
new_positions[match_count] = new_edit_position;
|
||||
match_count += 1;
|
||||
}
|
||||
if (buffer.buffer_id == last_buffer_match){
|
||||
|
@ -1791,7 +1855,7 @@ CUSTOM_DOC("Advances forward through the undo history in the buffer containing t
|
|||
}
|
||||
}
|
||||
|
||||
view_buffer_set(app, match_buffers, match_count);
|
||||
view_buffer_set(app, match_buffers, new_positions, match_count);
|
||||
|
||||
end_temp_memory(temp);
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ typedef double f64;
|
|||
#define PtrDif(a,b) ((u8*)(a) - (u8*)(b))
|
||||
#define PtrAsInt(a) PtrDif(a,0)
|
||||
#define HandleAsU64(a) (uint64_t)(PtrAsInt(a))
|
||||
#define NullMember(S,m) (&Member(S,m))
|
||||
#define OffsetOfMember(S,m) PtrAsInt(&Member(S,m))
|
||||
#define CastFromMember(S,m,ptr) (S*)( (u8*)(ptr) - OffsetOfMember(S,m) )
|
||||
#define IntAsPtr(a) (void*)(((u8*)0) + a)
|
||||
|
@ -215,12 +216,13 @@ static const u64 bit_63 = (((u64)1) << (31 + 32));
|
|||
#define dll_remove(n) (n)->next->prev=(n)->prev,(n)->prev->next=(n)->next,(n)->next=(n)->prev=0
|
||||
|
||||
#define zdll_push_back_(f,l,n) if(f==0){n->next=n->prev=0;f=l=n;}else{n->prev=l;n->next=0;l->next=n;l=n;}
|
||||
#define zdll_push_back(f,l,n) Stmnt( zdll_push_back_((f),(l),(n)) )
|
||||
#define zdll_push_front_(f,l,n) if(f==0){n->prev=n->next=0;f=l=n;}else{n->next=l;n->prev=0;l->prev=n;l=n;}
|
||||
#define zdll_push_front(f,l,n) Stmnt( zdll_push_front_((f),(l),(n)) )
|
||||
#define zdll_remove_front_(f,l,n) if(f==l){f=l=0;}else{f=f->next;f->prev=0;}
|
||||
#define zdll_remove_back_(f,l,n) if(f==l){f=l=0;}else{l=l->prev;l->next=0;}
|
||||
#define zdll_remove_(f,l,n) if(f==n){zdll_remove_front_(f,l,n);}else if(l==n){zdll_remove_back_(f,l,n);}else{dll_remove(n);}
|
||||
|
||||
#define zdll_push_back(f,l,n) Stmnt( zdll_push_back_((f),(l),(n)) )
|
||||
#define zdll_push_front(f,l,n) Stmnt( zdll_push_front_((f),(l),(n)) )
|
||||
#define zdll_remove_back_(f,l,n) if(f==l){f=l=0;}else{l=l->prev;l->next=0;}
|
||||
#define zdll_remove(f,l,n) Stmnt( zdll_remove_((f),(l),(n)) )
|
||||
|
||||
#define sll_clear(f,l) (f)=(l)=0
|
||||
|
@ -231,17 +233,6 @@ static const u64 bit_63 = (((u64)1) << (31 + 32));
|
|||
#define sll_insert(p,v) Stmnt( (v)->next=(p)->next; (p)->next = (v); )
|
||||
#define sll_remove(p,v) Stmnt( Assert((p)->next == (v)); (p)->next = (v)->next; )
|
||||
|
||||
#if 0
|
||||
#define dll_remove(n) (n)->next->prev=(n)->prev,(n)->prev->next=(n)->next
|
||||
|
||||
#define zdll_push_back_(f,l,n) if(f==0){n->next=n->prev=0;f=l=n;}else{n->prev=l;n->next=0;l->next=n;l=n;}
|
||||
#define zdll_push_back(f,l,n) do{ zdll_push_back_((f),(l),(n)) }while(0)
|
||||
#define zdll_remove_front_(f,l,n) if(f==l){f=l=0;}else{f=f->next;f->prev=0;}
|
||||
#define zdll_remove_back_(f,l,n) if(f==l){f=l=0;}else{l=l->prev;l->next=0;}
|
||||
#define zdll_remove_(f,l,n) if(f==n){zdll_remove_front_(f,l,n);}else if(l==n){zdll_remove_back_(f,l,n);}else{dll_remove(n);}
|
||||
#define zdll_remove(f,l,n) do{ zdll_remove_((f),(l),(n)) }while(0)
|
||||
#endif
|
||||
|
||||
struct Node{
|
||||
Node *next;
|
||||
Node *prev;
|
||||
|
|
|
@ -60,14 +60,14 @@ new_view_settings(Application_Links *app, View_Summary *view){
|
|||
////////////////////////////////
|
||||
|
||||
static void
|
||||
view_set_passive(Application_Links *app, View_Summary *view, b32 value){
|
||||
Managed_Scope scope = view_get_managed_scope(app, view->view_id);
|
||||
view_set_passive(Application_Links *app, View_ID view_id, b32 value){
|
||||
Managed_Scope scope = view_get_managed_scope(app, view_id);
|
||||
managed_variable_set(app, scope, view_is_passive_loc, (u64)value);
|
||||
}
|
||||
|
||||
static b32
|
||||
view_get_is_passive(Application_Links *app, View_Summary *view){
|
||||
Managed_Scope scope = view_get_managed_scope(app, view->view_id);
|
||||
view_get_is_passive(Application_Links *app, View_ID view_id){
|
||||
Managed_Scope scope = view_get_managed_scope(app, view_id);
|
||||
u64 is_passive = 0;
|
||||
managed_variable_get(app, scope, view_is_passive_loc, &is_passive);
|
||||
return(is_passive != 0);
|
||||
|
@ -78,12 +78,10 @@ open_footer_panel(Application_Links *app, View_Summary *view){
|
|||
View_Summary special_view = open_view(app, view, ViewSplit_Bottom);
|
||||
new_view_settings(app, &special_view);
|
||||
view_set_split_pixel_size(app, &special_view, (i32)(special_view.line_height*20.f));
|
||||
view_set_passive(app, &special_view, true);
|
||||
view_set_passive(app, special_view.view_id, true);
|
||||
return(special_view);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
static void
|
||||
close_build_footer_panel(Application_Links *app){
|
||||
View_Summary special_view = get_view(app, build_footer_panel_view_id, AccessAll);
|
||||
|
@ -93,48 +91,78 @@ close_build_footer_panel(Application_Links *app){
|
|||
build_footer_panel_view_id = 0;
|
||||
}
|
||||
|
||||
static View_Summary
|
||||
open_build_footer_panel(Application_Links *app, b32 create_if_not_exist = true){
|
||||
View_Summary special_view = get_view(app, build_footer_panel_view_id, AccessAll);
|
||||
if (create_if_not_exist && !special_view.exists){
|
||||
static b32
|
||||
open_build_footer_panel(Application_Links *app, View_ID *view_id_out){
|
||||
View_Summary special_view = {};
|
||||
get_view_summary(app, build_footer_panel_view_id, AccessAll, &special_view);
|
||||
if (!special_view.exists){
|
||||
View_Summary view = get_active_view(app, AccessAll);
|
||||
special_view = open_footer_panel(app, &view);
|
||||
set_active_view(app, &view);
|
||||
build_footer_panel_view_id = special_view.view_id;
|
||||
}
|
||||
return(special_view);
|
||||
*view_id_out = build_footer_panel_view_id;
|
||||
return(true);
|
||||
}
|
||||
|
||||
static View_ID
|
||||
get_next_view_looped_primary_panels(Application_Links *app, View_ID start_view_id, Access_Flag access){
|
||||
View_ID view_id = start_view_id;
|
||||
do{
|
||||
view_id = get_next_view_looped_all_panels(app, view_id, access);
|
||||
if (!view_get_is_passive(app, view_id)){
|
||||
break;
|
||||
}
|
||||
}while(view_id != start_view_id);
|
||||
return(view_id);
|
||||
}
|
||||
|
||||
static View_ID
|
||||
get_prev_view_looped_primary_panels(Application_Links *app, View_ID start_view_id, Access_Flag access){
|
||||
View_ID view_id = start_view_id;
|
||||
do{
|
||||
view_id = get_prev_view_looped_all_panels(app, view_id, access);
|
||||
if (!view_get_is_passive(app, view_id)){
|
||||
break;
|
||||
}
|
||||
}while(view_id != start_view_id);
|
||||
return(view_id);
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
static void
|
||||
view_set_passive(Application_Links *app, View_Summary *view, b32 value){
|
||||
if (view != 0){
|
||||
view_set_passive(app, view->view_id, value);
|
||||
}
|
||||
}
|
||||
|
||||
static b32
|
||||
view_get_is_passive(Application_Links *app, View_Summary *view){
|
||||
return(view != 0 && view_get_is_passive(app, view->view_id));
|
||||
}
|
||||
|
||||
static View_Summary
|
||||
open_build_footer_panel(Application_Links *app){
|
||||
View_Summary summary = {};
|
||||
View_ID build_footer_id = 0;
|
||||
if (open_build_footer_panel(app, &build_footer_id)){
|
||||
get_view_summary(app, build_footer_id, AccessAll, &summary);
|
||||
}
|
||||
return(summary);
|
||||
}
|
||||
|
||||
static void
|
||||
get_next_view_looped_primary_panels(Application_Links *app, View_Summary *view_start, Access_Flag access){
|
||||
View_ID original_view_id = view_start->view_id;
|
||||
View_Summary view = *view_start;
|
||||
do{
|
||||
get_next_view_looped_all_panels(app, &view, access);
|
||||
if (!view_get_is_passive(app, &view)){
|
||||
break;
|
||||
}
|
||||
}while(view.view_id != original_view_id);
|
||||
if (!view.exists){
|
||||
memset(&view, 0, sizeof(view));
|
||||
}
|
||||
*view_start = view;
|
||||
View_ID new_id = get_next_view_looped_primary_panels(app, view_start->view_id, access);
|
||||
get_view_summary(app, new_id, AccessAll, view_start);
|
||||
}
|
||||
|
||||
static void
|
||||
get_prev_view_looped_primary_panels(Application_Links *app, View_Summary *view_start, Access_Flag access){
|
||||
View_ID original_view_id = view_start->view_id;
|
||||
View_Summary view = *view_start;
|
||||
do{
|
||||
get_prev_view_looped_all_panels(app, &view, access);
|
||||
if (!view_get_is_passive(app, &view)){
|
||||
break;
|
||||
}
|
||||
}while(view.view_id != original_view_id);
|
||||
if (!view.exists){
|
||||
memset(&view, 0, sizeof(view));
|
||||
}
|
||||
*view_start = view;
|
||||
View_ID new_id = get_prev_view_looped_primary_panels(app, view_start->view_id, access);
|
||||
get_view_summary(app, new_id, AccessAll, view_start);
|
||||
}
|
||||
|
||||
static View_Summary
|
||||
|
@ -146,6 +174,63 @@ get_next_view_after_active(Application_Links *app, u32 access){
|
|||
return(view);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
static void
|
||||
view_buffer_set(Application_Links *app, Buffer_ID *buffers, i32 *positions, i32 count){
|
||||
if (count > 0){
|
||||
// TODO(allen): replace with context supplied arena
|
||||
Arena arena = make_arena(app);
|
||||
|
||||
struct View_Node{
|
||||
View_Node *next;
|
||||
View_ID view_id;
|
||||
};
|
||||
|
||||
View_ID active_view_id = 0;
|
||||
get_active_view(app, AccessAll, &active_view_id);
|
||||
View_ID first_view_id = active_view_id;
|
||||
if (view_get_is_passive(app, active_view_id)){
|
||||
first_view_id = get_next_view_looped_primary_panels(app, active_view_id, AccessAll);
|
||||
}
|
||||
|
||||
View_ID view_id = first_view_id;
|
||||
|
||||
View_Node *primary_view_first = 0;
|
||||
View_Node *primary_view_last = 0;
|
||||
i32 available_view_count = 0;
|
||||
|
||||
primary_view_first = primary_view_last = push_array(&arena, View_Node, 1);
|
||||
primary_view_last->next = 0;
|
||||
primary_view_last->view_id = view_id;
|
||||
available_view_count += 1;
|
||||
for (;;){
|
||||
view_id = get_next_view_looped_primary_panels(app, view_id, AccessAll);
|
||||
if (view_id == first_view_id){
|
||||
break;
|
||||
}
|
||||
View_Node *node = push_array(&arena, View_Node, 1);
|
||||
primary_view_last->next = node;
|
||||
node->next = 0;
|
||||
node->view_id = view_id;
|
||||
primary_view_last = node;
|
||||
available_view_count += 1;
|
||||
}
|
||||
|
||||
i32 buffer_set_count = clamp_top(count, available_view_count);
|
||||
View_Node *node = primary_view_first;
|
||||
for (i32 i = 0; i < buffer_set_count; i += 1, node = node->next){
|
||||
if (view_set_buffer(app, node->view_id, buffers[i], 0)){
|
||||
view_set_cursor(app, node->view_id, seek_pos(positions[i]), true);
|
||||
}
|
||||
}
|
||||
|
||||
arena_release_all(&arena);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
CUSTOM_COMMAND_SIG(change_active_panel)
|
||||
CUSTOM_DOC("Change the currently active panel, moving to the panel with the next highest view_id.")
|
||||
{
|
||||
|
|
|
@ -1129,6 +1129,7 @@ OPEN_FILE_HOOK_SIG(default_file_save){
|
|||
}
|
||||
|
||||
FILE_EDIT_RANGE_SIG(default_file_edit_range){
|
||||
#if 0
|
||||
Buffer_Summary buffer_summary = {};
|
||||
if (get_buffer_summary(app, buffer_id, AccessAll, &buffer_summary)){
|
||||
if (!match(make_string(buffer_summary.buffer_name, buffer_summary.buffer_name_len), make_lit_string("*messages*"))){
|
||||
|
@ -1146,6 +1147,7 @@ FILE_EDIT_RANGE_SIG(default_file_edit_range){
|
|||
print_message(app, str.str, str.size);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// no meaning for return
|
||||
return(0);
|
||||
|
|
|
@ -36,6 +36,7 @@ struct Application_Links;
|
|||
#define BUFFER_GET_FILE_ATTRIBUTES_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id, File_Attributes *attributes_out)
|
||||
#define GET_VIEW_FIRST_SIG(n) b32 n(Application_Links *app, Access_Flag access, View_ID *view_id_out)
|
||||
#define GET_VIEW_NEXT_SIG(n) b32 n(Application_Links *app, View_ID view_id, Access_Flag access, View_ID *view_id_out)
|
||||
#define GET_VIEW_PREV_SIG(n) b32 n(Application_Links *app, View_ID view_id, Access_Flag access, View_ID *view_id_out)
|
||||
#define GET_VIEW_SUMMARY_SIG(n) b32 n(Application_Links *app, View_ID view_id, Access_Flag access, View_Summary *view_summary_out)
|
||||
#define GET_ACTIVE_VIEW_SIG(n) b32 n(Application_Links *app, Access_Flag access, View_ID *view_id_out)
|
||||
#define GET_ACTIVE_PANEL_SIG(n) b32 n(Application_Links *app, Panel_ID *panel_id_out)
|
||||
|
@ -191,6 +192,7 @@ typedef BUFFER_REOPEN_SIG(Buffer_Reopen_Function);
|
|||
typedef BUFFER_GET_FILE_ATTRIBUTES_SIG(Buffer_Get_File_Attributes_Function);
|
||||
typedef GET_VIEW_FIRST_SIG(Get_View_First_Function);
|
||||
typedef GET_VIEW_NEXT_SIG(Get_View_Next_Function);
|
||||
typedef GET_VIEW_PREV_SIG(Get_View_Prev_Function);
|
||||
typedef GET_VIEW_SUMMARY_SIG(Get_View_Summary_Function);
|
||||
typedef GET_ACTIVE_VIEW_SIG(Get_Active_View_Function);
|
||||
typedef GET_ACTIVE_PANEL_SIG(Get_Active_Panel_Function);
|
||||
|
@ -348,6 +350,7 @@ Buffer_Reopen_Function *buffer_reopen;
|
|||
Buffer_Get_File_Attributes_Function *buffer_get_file_attributes;
|
||||
Get_View_First_Function *get_view_first;
|
||||
Get_View_Next_Function *get_view_next;
|
||||
Get_View_Prev_Function *get_view_prev;
|
||||
Get_View_Summary_Function *get_view_summary;
|
||||
Get_Active_View_Function *get_active_view;
|
||||
Get_Active_Panel_Function *get_active_panel;
|
||||
|
@ -504,6 +507,7 @@ Buffer_Reopen_Function *buffer_reopen_;
|
|||
Buffer_Get_File_Attributes_Function *buffer_get_file_attributes_;
|
||||
Get_View_First_Function *get_view_first_;
|
||||
Get_View_Next_Function *get_view_next_;
|
||||
Get_View_Prev_Function *get_view_prev_;
|
||||
Get_View_Summary_Function *get_view_summary_;
|
||||
Get_Active_View_Function *get_active_view_;
|
||||
Get_Active_Panel_Function *get_active_panel_;
|
||||
|
@ -668,6 +672,7 @@ app_links->buffer_reopen_ = Buffer_Reopen;\
|
|||
app_links->buffer_get_file_attributes_ = Buffer_Get_File_Attributes;\
|
||||
app_links->get_view_first_ = Get_View_First;\
|
||||
app_links->get_view_next_ = Get_View_Next;\
|
||||
app_links->get_view_prev_ = Get_View_Prev;\
|
||||
app_links->get_view_summary_ = Get_View_Summary;\
|
||||
app_links->get_active_view_ = Get_Active_View;\
|
||||
app_links->get_active_panel_ = Get_Active_Panel;\
|
||||
|
@ -824,6 +829,7 @@ static b32 buffer_reopen(Application_Links *app, Buffer_ID buffer_id, Buffer_Reo
|
|||
static b32 buffer_get_file_attributes(Application_Links *app, Buffer_ID buffer_id, File_Attributes *attributes_out){return(app->buffer_get_file_attributes(app, buffer_id, attributes_out));}
|
||||
static b32 get_view_first(Application_Links *app, Access_Flag access, View_ID *view_id_out){return(app->get_view_first(app, access, view_id_out));}
|
||||
static b32 get_view_next(Application_Links *app, View_ID view_id, Access_Flag access, View_ID *view_id_out){return(app->get_view_next(app, view_id, access, view_id_out));}
|
||||
static b32 get_view_prev(Application_Links *app, View_ID view_id, Access_Flag access, View_ID *view_id_out){return(app->get_view_prev(app, view_id, access, view_id_out));}
|
||||
static b32 get_view_summary(Application_Links *app, View_ID view_id, Access_Flag access, View_Summary *view_summary_out){return(app->get_view_summary(app, view_id, access, view_summary_out));}
|
||||
static b32 get_active_view(Application_Links *app, Access_Flag access, View_ID *view_id_out){return(app->get_active_view(app, access, view_id_out));}
|
||||
static b32 get_active_panel(Application_Links *app, Panel_ID *panel_id_out){return(app->get_active_panel(app, panel_id_out));}
|
||||
|
@ -980,6 +986,7 @@ static b32 buffer_reopen(Application_Links *app, Buffer_ID buffer_id, Buffer_Reo
|
|||
static b32 buffer_get_file_attributes(Application_Links *app, Buffer_ID buffer_id, File_Attributes *attributes_out){return(app->buffer_get_file_attributes_(app, buffer_id, attributes_out));}
|
||||
static b32 get_view_first(Application_Links *app, Access_Flag access, View_ID *view_id_out){return(app->get_view_first_(app, access, view_id_out));}
|
||||
static b32 get_view_next(Application_Links *app, View_ID view_id, Access_Flag access, View_ID *view_id_out){return(app->get_view_next_(app, view_id, access, view_id_out));}
|
||||
static b32 get_view_prev(Application_Links *app, View_ID view_id, Access_Flag access, View_ID *view_id_out){return(app->get_view_prev_(app, view_id, access, view_id_out));}
|
||||
static b32 get_view_summary(Application_Links *app, View_ID view_id, Access_Flag access, View_Summary *view_summary_out){return(app->get_view_summary_(app, view_id, access, view_summary_out));}
|
||||
static b32 get_active_view(Application_Links *app, Access_Flag access, View_ID *view_id_out){return(app->get_active_view_(app, access, view_id_out));}
|
||||
static b32 get_active_panel(Application_Links *app, Panel_ID *panel_id_out){return(app->get_active_panel_(app, panel_id_out));}
|
||||
|
|
|
@ -255,7 +255,7 @@ int32_t source_name_len;
|
|||
int32_t line_number;
|
||||
};
|
||||
static Command_Metadata fcoder_metacmd_table[234] = {
|
||||
{ PROC_LINKS(allow_mouse, 0), "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 247 },
|
||||
{ PROC_LINKS(allow_mouse, 0), "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 332 },
|
||||
{ PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 629 },
|
||||
{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 640 },
|
||||
{ PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 619 },
|
||||
|
@ -265,8 +265,8 @@ static Command_Metadata fcoder_metacmd_table[234] = {
|
|||
{ PROC_LINKS(build_in_build_panel, 0), "build_in_build_panel", 20, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. Puts the *compilation* buffer in a panel at the footer of the current view.", 230, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 187 },
|
||||
{ PROC_LINKS(build_search, 0), "build_search", 12, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*.", 153, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 155 },
|
||||
{ PROC_LINKS(center_view, 0), "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 151 },
|
||||
{ PROC_LINKS(change_active_panel, 0), "change_active_panel", 19, "Change the currently active panel, moving to the panel with the next highest view_id.", 85, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 149 },
|
||||
{ PROC_LINKS(change_active_panel_backwards, 0), "change_active_panel_backwards", 29, "Change the currently active panel, moving to the panel with the next lowest view_id.", 84, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 159 },
|
||||
{ PROC_LINKS(change_active_panel, 0), "change_active_panel", 19, "Change the currently active panel, moving to the panel with the next highest view_id.", 85, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 234 },
|
||||
{ PROC_LINKS(change_active_panel_backwards, 0), "change_active_panel_backwards", 29, "Change the currently active panel, moving to the panel with the next lowest view_id.", 84, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 244 },
|
||||
{ PROC_LINKS(change_to_build_panel, 0), "change_to_build_panel", 21, "If the special build panel is open, makes the build panel the active panel.", 75, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 209 },
|
||||
{ PROC_LINKS(clean_all_lines, 0), "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 441 },
|
||||
{ PROC_LINKS(click_set_cursor, 0), "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 210 },
|
||||
|
@ -385,13 +385,13 @@ static Command_Metadata fcoder_metacmd_table[234] = {
|
|||
{ PROC_LINKS(open_all_code, 0), "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\\4coder_project_commands.cpp", 39, 1067 },
|
||||
{ PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1074 },
|
||||
{ PROC_LINKS(open_file_in_quotes, 0), "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1507 },
|
||||
{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1826 },
|
||||
{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1890 },
|
||||
{ PROC_LINKS(open_long_braces, 0), "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 55 },
|
||||
{ PROC_LINKS(open_long_braces_break, 0), "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 71 },
|
||||
{ PROC_LINKS(open_long_braces_semicolon, 0), "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 63 },
|
||||
{ PROC_LINKS(open_matching_file_cpp, 0), "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1543 },
|
||||
{ PROC_LINKS(open_panel_hsplit, 0), "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 178 },
|
||||
{ PROC_LINKS(open_panel_vsplit, 0), "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 169 },
|
||||
{ PROC_LINKS(open_panel_hsplit, 0), "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 263 },
|
||||
{ PROC_LINKS(open_panel_vsplit, 0), "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 254 },
|
||||
{ PROC_LINKS(page_down, 0), "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 358 },
|
||||
{ PROC_LINKS(page_up, 0), "page_up", 7, "Scrolls the view up one view height and moves the cursor up one view height.", 76, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 349 },
|
||||
{ PROC_LINKS(paste, 0), "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "w:\\4ed\\code\\4coder_clipboard.cpp", 32, 46 },
|
||||
|
@ -405,9 +405,9 @@ static Command_Metadata fcoder_metacmd_table[234] = {
|
|||
{ PROC_LINKS(query_replace, 0), "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1062 },
|
||||
{ PROC_LINKS(query_replace_identifier, 0), "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\\4coder_base_commands.cpp", 36, 1086 },
|
||||
{ PROC_LINKS(query_replace_selection, 0), "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\\4coder_base_commands.cpp", 36, 1104 },
|
||||
{ PROC_LINKS(redo, 0), "redo", 4, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1723 },
|
||||
{ PROC_LINKS(redo_this_buffer, 0), "redo_this_buffer", 16, "Advances forwards through the undo history of the current buffer.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1637 },
|
||||
{ PROC_LINKS(remap_interactive, 0), "remap_interactive", 17, "Switch to a named key binding map.", 34, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 297 },
|
||||
{ PROC_LINKS(redo, 0), "redo", 4, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1783 },
|
||||
{ PROC_LINKS(redo_this_buffer, 0), "redo_this_buffer", 16, "Advances forwards through the undo history of the current buffer.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1691 },
|
||||
{ PROC_LINKS(remap_interactive, 0), "remap_interactive", 17, "Switch to a named key binding map.", 34, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 382 },
|
||||
{ PROC_LINKS(rename_file_query, 0), "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\\4coder_base_commands.cpp", 36, 1244 },
|
||||
{ PROC_LINKS(rename_parameter, 0), "rename_parameter", 16, "If the cursor is found to be on the name of a function parameter in the signature of a function definition, all occurences within the scope of the function will be replaced with a new provided string.", 200, "w:\\4ed\\code\\4coder_experiments.cpp", 34, 383 },
|
||||
{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1615 },
|
||||
|
@ -447,8 +447,8 @@ static Command_Metadata fcoder_metacmd_table[234] = {
|
|||
{ PROC_LINKS(set_bindings_default, 0), "set_bindings_default", 20, "Remap keybindings using the 'default' mapping rule.", 51, "w:\\4ed\\code\\4coder_remapping_commands.cpp", 41, 61 },
|
||||
{ PROC_LINKS(set_bindings_mac_default, 0), "set_bindings_mac_default", 24, "Remap keybindings using the 'mac-default' mapping rule.", 55, "w:\\4ed\\code\\4coder_remapping_commands.cpp", 41, 75 },
|
||||
{ PROC_LINKS(set_mark, 0), "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 121 },
|
||||
{ PROC_LINKS(set_mode_to_notepad_like, 0), "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 265 },
|
||||
{ PROC_LINKS(set_mode_to_original, 0), "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 259 },
|
||||
{ PROC_LINKS(set_mode_to_notepad_like, 0), "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 350 },
|
||||
{ PROC_LINKS(set_mode_to_original, 0), "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 344 },
|
||||
{ PROC_LINKS(setup_build_bat, 0), "setup_build_bat", 15, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1498 },
|
||||
{ PROC_LINKS(setup_build_bat_and_sh, 0), "setup_build_bat_and_sh", 22, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1510 },
|
||||
{ PROC_LINKS(setup_build_sh, 0), "setup_build_sh", 14, "Queries the user for several configuration options and initializes a new build shell script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1504 },
|
||||
|
@ -458,24 +458,24 @@ static Command_Metadata fcoder_metacmd_table[234] = {
|
|||
{ PROC_LINKS(snipe_token_or_word, 0), "snipe_token_or_word", 19, "Delete a single, whole token on or to the left of the cursor and post it to the clipboard.", 90, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1269 },
|
||||
{ PROC_LINKS(snipe_token_or_word_right, 0), "snipe_token_or_word_right", 25, "Delete a single, whole token on or to the right of the cursor and post it to the clipboard.", 91, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1275 },
|
||||
{ PROC_LINKS(snippet_lister, 0), "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 248 },
|
||||
{ PROC_LINKS(suppress_mouse, 0), "suppress_mouse", 14, "Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.", 83, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 241 },
|
||||
{ PROC_LINKS(suppress_mouse, 0), "suppress_mouse", 14, "Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.", 83, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 326 },
|
||||
{ PROC_LINKS(swap_buffers_between_panels, 0), "swap_buffers_between_panels", 27, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1567 },
|
||||
{ PROC_LINKS(to_lowercase, 0), "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 421 },
|
||||
{ PROC_LINKS(to_uppercase, 0), "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 401 },
|
||||
{ PROC_LINKS(toggle_filebar, 0), "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 551 },
|
||||
{ PROC_LINKS(toggle_fps_meter, 0), "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 569 },
|
||||
{ PROC_LINKS(toggle_fullscreen, 0), "toggle_fullscreen", 17, "Toggle fullscreen mode on or off. The change(s) do not take effect until the next frame.", 89, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 289 },
|
||||
{ PROC_LINKS(toggle_highlight_enclosing_scopes, 0), "toggle_highlight_enclosing_scopes", 33, "In code files scopes surrounding the cursor are highlighted with distinguishing colors.", 87, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 277 },
|
||||
{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 271 },
|
||||
{ PROC_LINKS(toggle_fullscreen, 0), "toggle_fullscreen", 17, "Toggle fullscreen mode on or off. The change(s) do not take effect until the next frame.", 89, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 374 },
|
||||
{ PROC_LINKS(toggle_highlight_enclosing_scopes, 0), "toggle_highlight_enclosing_scopes", 33, "In code files scopes surrounding the cursor are highlighted with distinguishing colors.", 87, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 362 },
|
||||
{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 356 },
|
||||
{ PROC_LINKS(toggle_line_numbers, 0), "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 656 },
|
||||
{ PROC_LINKS(toggle_line_wrap, 0), "toggle_line_wrap", 16, "Toggles the current buffer's line wrapping status.", 50, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 560 },
|
||||
{ PROC_LINKS(toggle_mouse, 0), "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 253 },
|
||||
{ PROC_LINKS(toggle_paren_matching_helper, 0), "toggle_paren_matching_helper", 28, "In code files matching parentheses pairs are colored with distinguishing colors.", 80, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 283 },
|
||||
{ PROC_LINKS(toggle_mouse, 0), "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 338 },
|
||||
{ PROC_LINKS(toggle_paren_matching_helper, 0), "toggle_paren_matching_helper", 28, "In code files matching parentheses pairs are colored with distinguishing colors.", 80, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 368 },
|
||||
{ PROC_LINKS(toggle_show_whitespace, 0), "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 649 },
|
||||
{ PROC_LINKS(toggle_virtual_whitespace, 0), "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 638 },
|
||||
{ PROC_LINKS(uncomment_line, 0), "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 147 },
|
||||
{ PROC_LINKS(undo, 0), "undo", 4, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1651 },
|
||||
{ PROC_LINKS(undo_this_buffer, 0), "undo_this_buffer", 16, "Advances backwards through the undo history of the current buffer.", 66, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1625 },
|
||||
{ PROC_LINKS(undo, 0), "undo", 4, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1707 },
|
||||
{ PROC_LINKS(undo_this_buffer, 0), "undo_this_buffer", 16, "Advances backwards through the undo history of the current buffer.", 66, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1677 },
|
||||
{ PROC_LINKS(view_buffer_other_panel, 0), "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\\4coder_base_commands.cpp", 36, 1557 },
|
||||
{ PROC_LINKS(view_jump_list_with_lister, 0), "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\\4coder_jump_lister.cpp", 34, 108 },
|
||||
{ PROC_LINKS(word_complete, 0), "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\\4coder_search.cpp", 29, 958 },
|
||||
|
|
|
@ -608,10 +608,8 @@ buffer_identifier_to_buffer_summary(Application_Links *app, Buffer_Identifier id
|
|||
}
|
||||
|
||||
static b32
|
||||
view_open_file(Application_Links *app, View_Summary *view,
|
||||
char *filename, i32 filename_len, b32 never_new){
|
||||
view_open_file(Application_Links *app, View_Summary *view, char *filename, i32 filename_len, b32 never_new){
|
||||
b32 result = false;
|
||||
|
||||
if (view != 0){
|
||||
Buffer_Summary buffer = {};
|
||||
if (open_file(app, &buffer, filename, filename_len, false, never_new)){
|
||||
|
@ -619,37 +617,70 @@ view_open_file(Application_Links *app, View_Summary *view,
|
|||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
static void
|
||||
get_view_prev(Application_Links *app, View_Summary *view, u32 access){
|
||||
if (view->exists){
|
||||
View_ID original_id = view->view_id;
|
||||
View_ID check_id = original_id;
|
||||
|
||||
View_Summary new_view = {};
|
||||
|
||||
for (;;){
|
||||
--check_id;
|
||||
if (check_id <= 0){
|
||||
check_id = 16;
|
||||
}
|
||||
if (check_id == original_id){
|
||||
new_view = *view;
|
||||
break;
|
||||
}
|
||||
new_view = get_view(app, check_id, access);
|
||||
if (new_view.exists){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*view = new_view;
|
||||
}
|
||||
////////////////////////////////
|
||||
|
||||
// TODO(allen): replace this with get_view_prev(app, 0, access, view_id_out);
|
||||
static b32
|
||||
get_view_last(Application_Links *app, Access_Flag access, View_ID *view_id_out){
|
||||
return(get_view_prev(app, 0, access, view_id_out));
|
||||
}
|
||||
|
||||
static View_ID
|
||||
get_next_view_looped_all_panels(Application_Links *app, View_ID view_id, Access_Flag access){
|
||||
if (!get_view_next(app, view_id, access, &view_id)){
|
||||
if (!get_view_first(app, access, &view_id)){
|
||||
view_id = 0;
|
||||
}
|
||||
}
|
||||
return(view_id);
|
||||
}
|
||||
|
||||
static View_ID
|
||||
get_prev_view_looped_all_panels(Application_Links *app, View_ID view_id, Access_Flag access){
|
||||
if (!get_view_prev(app, view_id, access, &view_id)){
|
||||
if (!get_view_prev(app, 0, access, &view_id)){
|
||||
view_id = 0;
|
||||
}
|
||||
}
|
||||
return(view_id);
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
static void
|
||||
get_view_prev(Application_Links *app, View_Summary *view, Access_Flag access){
|
||||
View_ID new_id = 0;
|
||||
get_view_prev(app, view->view_id, access, &new_id);
|
||||
get_view_summary(app, new_id, access, view);
|
||||
}
|
||||
|
||||
static View_Summary
|
||||
get_view_last(Application_Links *app, Access_Flag access){
|
||||
View_Summary view = {};
|
||||
View_ID new_id = 0;
|
||||
if (get_view_last(app, access, &new_id)){
|
||||
get_view_summary(app, new_id, access, &view);
|
||||
}
|
||||
return(view);
|
||||
}
|
||||
|
||||
static void
|
||||
get_next_view_looped_all_panels(Application_Links *app, View_Summary *view, Access_Flag access){
|
||||
View_ID new_id = get_next_view_looped_all_panels(app, view->view_id, access);
|
||||
get_view_summary(app, new_id, access, view);
|
||||
}
|
||||
|
||||
static void
|
||||
get_prev_view_looped_all_panels(Application_Links *app, View_Summary *view, u32 access){
|
||||
View_ID new_id = get_prev_view_looped_all_panels(app, view->view_id, access);
|
||||
get_view_summary(app, new_id, access, view);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
static Buffer_Kill_Result
|
||||
kill_buffer(Application_Links *app, Buffer_Identifier identifier, View_ID gui_view_id, Buffer_Kill_Flag flags){
|
||||
Buffer_Kill_Result result = kill_buffer(app, identifier, flags);
|
||||
|
@ -661,33 +692,6 @@ kill_buffer(Application_Links *app, Buffer_Identifier identifier, View_ID gui_vi
|
|||
return(result);
|
||||
}
|
||||
|
||||
static View_Summary
|
||||
get_view_last(Application_Links *app, u32 access){
|
||||
View_Summary view = {};
|
||||
view.exists = true;
|
||||
get_view_prev(app, &view, access);
|
||||
if (view.view_id < 1 || view.view_id > 16){
|
||||
memset(&view, 0, sizeof(view));
|
||||
}
|
||||
return(view);
|
||||
}
|
||||
|
||||
static void
|
||||
get_next_view_looped_all_panels(Application_Links *app, View_Summary *view, u32 access){
|
||||
get_view_next(app, view, access);
|
||||
if (!view->exists){
|
||||
*view = get_view_first(app, access);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_prev_view_looped_all_panels(Application_Links *app, View_Summary *view, u32 access){
|
||||
get_view_prev(app, view, access);
|
||||
if (!view->exists){
|
||||
*view = get_view_last(app, access);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
refresh_buffer(Application_Links *app, Buffer_Summary *buffer){
|
||||
*buffer = get_buffer(app, buffer->buffer_id, AccessAll);
|
||||
|
@ -1659,33 +1663,21 @@ get_single_record(Application_Links *app, Buffer_ID buffer_id, History_Record_In
|
|||
|
||||
////////////////////////////////
|
||||
|
||||
static void
|
||||
view_buffer_set(Application_Links *app, Buffer_ID *buffers, i32 count){
|
||||
// TODO(allen): do(implement view_buffer_set)
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
static void
|
||||
condense_whitespace(String *a)
|
||||
{
|
||||
*a = skip_chop_whitespace(*a);
|
||||
|
||||
int size = a->size;
|
||||
a->size = 0;
|
||||
int i = 0;
|
||||
while(i < size)
|
||||
{
|
||||
if(char_is_whitespace(a->str[i]))
|
||||
{
|
||||
for (;i < size;){
|
||||
if (char_is_whitespace(a->str[i])){
|
||||
a->str[a->size++] = ' ';
|
||||
while((i < size) && char_is_whitespace(a->str[i]))
|
||||
{
|
||||
for (;(i < size) && char_is_whitespace(a->str[i]);){
|
||||
++i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else{
|
||||
a->str[a->size++] = a->str[i++];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1720,6 +1720,26 @@ get_view_next__inner(Layout *layout, View *view){
|
|||
return(view);
|
||||
}
|
||||
|
||||
internal View*
|
||||
get_view_prev__inner(Layout *layout, View *view){
|
||||
if (view != 0){
|
||||
Panel *panel = view->panel;
|
||||
panel = layout_get_prev_open_panel(layout, panel);
|
||||
if (panel != 0){
|
||||
view = panel->view;
|
||||
}
|
||||
else{
|
||||
view = 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
Panel *panel = layout_get_first_open_panel(layout);
|
||||
view = panel->view;
|
||||
}
|
||||
return(view);
|
||||
}
|
||||
|
||||
// TODO(allen): replace this with get_view_next(app, 0, access, view_id_out);
|
||||
// TODO(allen): redocument
|
||||
API_EXPORT b32
|
||||
Get_View_First(Application_Links *app, Access_Flag access, View_ID *view_id_out)
|
||||
|
@ -1780,6 +1800,24 @@ DOC_SEE(get_view_first)
|
|||
return(result);
|
||||
}
|
||||
|
||||
API_EXPORT b32
|
||||
Get_View_Prev(Application_Links *app, View_ID view_id, Access_Flag access, View_ID *view_id_out)
|
||||
{
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
Layout *layout = &models->layout;
|
||||
View *view = imp_get_view(models, view_id);
|
||||
view = get_view_prev__inner(layout, view);
|
||||
for (;view != 0 && !access_test(view_get_access_flags(view), access);){
|
||||
view = get_view_prev__inner(layout, view);
|
||||
}
|
||||
b32 result = false;
|
||||
if (view != 0){
|
||||
*view_id_out = view_get_id(&models->live_set, view);
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
// TODO(allen): redocument
|
||||
API_EXPORT b32
|
||||
Get_View_Summary(Application_Links *app, View_ID view_id, Access_Flag access, View_Summary *view_summary_out)
|
||||
|
@ -3622,11 +3660,6 @@ buffer_history__fill_record_info(Record *record, Record_Info *out){
|
|||
out->single.string_backward = make_string(record->single.str_backward, record->single.length_backward);
|
||||
out->single.first = record->single.first;
|
||||
}break;
|
||||
case RecordKind_Batch:
|
||||
{
|
||||
out->batch.type = record->batch.type;
|
||||
out->batch.count = record->batch.count;
|
||||
}break;
|
||||
case RecordKind_Group:
|
||||
{
|
||||
out->group.count = record->group.count;
|
||||
|
|
59
4ed_edit.cpp
59
4ed_edit.cpp
|
@ -348,34 +348,6 @@ edit__apply_record_forward(System_Functions *system, Models *models, Editing_Fil
|
|||
edit_single(system, models, file, edit, behaviors_prototype);
|
||||
}break;
|
||||
|
||||
case RecordKind_Batch:
|
||||
{
|
||||
Partition *scratch = &models->mem.part;
|
||||
Temp_Memory temp = begin_temp_memory(scratch);
|
||||
|
||||
i32 count = record->batch.count;
|
||||
Edit_Array edits = {};
|
||||
edits.vals = push_array(scratch, Edit, count);
|
||||
edits.count = count;
|
||||
|
||||
Edit *edit = edits.vals;
|
||||
Record_Batch_Slot *batch_slot = record->batch.batch_records;
|
||||
char *str_base_forward = record->batch.str_base_forward;
|
||||
for (i32 i = 0; i < count; i += 1, edit += 1, batch_slot += 1){
|
||||
edit->str = str_base_forward;
|
||||
edit->length = batch_slot->length_forward;
|
||||
edit->range.first = batch_slot->first;
|
||||
edit->range.one_past_last = edit->range.first + batch_slot->length_backward;
|
||||
str_base_forward += batch_slot->length_forward;
|
||||
}
|
||||
|
||||
Edit_Behaviors behaviors = behaviors_prototype;
|
||||
behaviors.batch_type = record->batch.type;
|
||||
edit_batch(system, models, file, edits, behaviors);
|
||||
|
||||
end_temp_memory(temp);
|
||||
}break;
|
||||
|
||||
case RecordKind_Group:
|
||||
{
|
||||
Node *sentinel = &record->group.children;
|
||||
|
@ -410,37 +382,6 @@ edit__apply_record_backward(System_Functions *system, Models *models, Editing_Fi
|
|||
edit_single(system, models, file, edit, behaviors_prototype);
|
||||
}break;
|
||||
|
||||
case RecordKind_Batch:
|
||||
{
|
||||
Partition *scratch = &models->mem.part;
|
||||
Temp_Memory temp = begin_temp_memory(scratch);
|
||||
|
||||
i32 count = record->batch.count;
|
||||
Edit_Array edits = {};
|
||||
edits.vals = push_array(scratch, Edit, count);
|
||||
edits.count = count;
|
||||
|
||||
i32 shift_amount = 0;
|
||||
|
||||
Edit *edit = edits.vals;
|
||||
Record_Batch_Slot *batch_slot = record->batch.batch_records;
|
||||
char *str_base_backward = record->batch.str_base_backward;
|
||||
for (i32 i = 0; i < count; i += 1, edit += 1, batch_slot += 1){
|
||||
edit->str = str_base_backward;
|
||||
edit->length = batch_slot->length_backward;
|
||||
edit->range.first = batch_slot->first + shift_amount;
|
||||
edit->range.one_past_last = edit->range.first + batch_slot->length_forward;
|
||||
str_base_backward += batch_slot->length_backward;
|
||||
shift_amount += batch_slot->length_forward - batch_slot->length_backward;
|
||||
}
|
||||
|
||||
Edit_Behaviors behaviors = behaviors_prototype;
|
||||
behaviors.batch_type = record->batch.type;
|
||||
edit_batch(system, models, file, edits, behaviors);
|
||||
|
||||
end_temp_memory(temp);
|
||||
}break;
|
||||
|
||||
case RecordKind_Group:
|
||||
{
|
||||
Node *sentinel = &record->group.children;
|
||||
|
|
298
4ed_history.cpp
298
4ed_history.cpp
|
@ -239,115 +239,56 @@ history__free_nodes(History *history, i32 first_index, Node *first_node, Node *l
|
|||
|
||||
internal void
|
||||
history_record_edit(Heap *heap, Global_History *global_history, History *history, Gap_Buffer *buffer, Edit edit){
|
||||
if (!history->activated){
|
||||
return;
|
||||
}
|
||||
|
||||
Assert(history->record_lookup.count == history->record_count);
|
||||
|
||||
Record *new_record = history__allocate_record(heap, history);
|
||||
history__stash_record(heap, history, new_record);
|
||||
|
||||
new_record->restore_point = temp_memory_light(begin_temp_memory(&history->arena));
|
||||
new_record->edit_number = global_history_get_edit_number(global_history);
|
||||
|
||||
new_record->kind = RecordKind_Single;
|
||||
|
||||
i32 length_forward = edit.length;
|
||||
i32 length_backward = edit.range.one_past_last - edit.range.first;
|
||||
|
||||
new_record->single.str_forward = push_array(&history->arena, char, length_forward);
|
||||
new_record->single.str_backward = push_array(&history->arena, char, length_backward);
|
||||
new_record->single.length_forward = length_forward;
|
||||
new_record->single.length_backward = length_backward;
|
||||
new_record->single.first = edit.range.first;
|
||||
|
||||
block_copy(new_record->single.str_forward, edit.str, length_forward);
|
||||
buffer_stringify_range(buffer, edit.range, new_record->single.str_backward);
|
||||
|
||||
Assert(history->record_lookup.count == history->record_count);
|
||||
}
|
||||
|
||||
internal void
|
||||
history_record_edit(Heap *heap, Global_History *global_history, History *history, Gap_Buffer *buffer, Edit_Array edits, Buffer_Batch_Edit_Type batch_type){
|
||||
if (!history->activated){
|
||||
return;
|
||||
}
|
||||
Assert(history->record_lookup.count == history->record_count);
|
||||
|
||||
Record *new_record = history__allocate_record(heap, history);
|
||||
history__stash_record(heap, history, new_record);
|
||||
|
||||
new_record->restore_point = temp_memory_light(begin_temp_memory(&history->arena));
|
||||
new_record->edit_number = global_history_get_edit_number(global_history);
|
||||
|
||||
new_record->kind = RecordKind_Batch;
|
||||
|
||||
i32 length_forward = 0;
|
||||
i32 length_backward = 0;
|
||||
|
||||
for (i32 i = 0; i < edits.count; i += 1){
|
||||
length_forward += edits.vals[i].length;
|
||||
length_backward += edits.vals[i].range.one_past_last - edits.vals[i].range.first;
|
||||
}
|
||||
|
||||
new_record->batch.type = batch_type;
|
||||
new_record->batch.count = edits.count;
|
||||
new_record->batch.str_base_forward = push_array(&history->arena, char, length_forward);
|
||||
new_record->batch.str_base_backward = push_array(&history->arena, char, length_backward);
|
||||
new_record->batch.batch_records = push_array(&history->arena, Record_Batch_Slot, edits.count);
|
||||
|
||||
char *str_base_forward = new_record->batch.str_base_forward;
|
||||
char *cursor_forward = str_base_forward;
|
||||
char *str_base_backward = new_record->batch.str_base_backward;
|
||||
char *cursor_backward = str_base_backward;
|
||||
|
||||
Record_Batch_Slot *batch_slot = new_record->batch.batch_records;
|
||||
Edit *edit = edits.vals;
|
||||
|
||||
for (i32 i = 0; i < edits.count; i += 1, batch_slot += 1, edit += 1){
|
||||
i32 edit_first = edit->range.first;
|
||||
i32 edit_length_forward = edit->length;
|
||||
i32 edit_length_backward = edit->range.one_past_last - edit_first;
|
||||
if (history->activated){
|
||||
Assert(history->record_lookup.count == history->record_count);
|
||||
|
||||
batch_slot->length_forward = edit_length_forward ;
|
||||
batch_slot->length_backward = edit_length_backward;
|
||||
batch_slot->first = edit_first;
|
||||
Record *new_record = history__allocate_record(heap, history);
|
||||
history__stash_record(heap, history, new_record);
|
||||
|
||||
block_copy(cursor_forward , edit->str, edit_length_forward);
|
||||
buffer_stringify_range(buffer, edit->range, cursor_backward);
|
||||
new_record->restore_point = temp_memory_light(begin_temp_memory(&history->arena));
|
||||
new_record->edit_number = global_history_get_edit_number(global_history);
|
||||
|
||||
cursor_forward += edit_length_forward ;
|
||||
cursor_backward += edit_length_backward;
|
||||
new_record->kind = RecordKind_Single;
|
||||
|
||||
i32 length_forward = edit.length;
|
||||
i32 length_backward = edit.range.one_past_last - edit.range.first;
|
||||
|
||||
new_record->single.str_forward = push_array(&history->arena, char, length_forward);
|
||||
new_record->single.str_backward = push_array(&history->arena, char, length_backward);
|
||||
new_record->single.length_forward = length_forward;
|
||||
new_record->single.length_backward = length_backward;
|
||||
new_record->single.first = edit.range.first;
|
||||
|
||||
block_copy(new_record->single.str_forward, edit.str, length_forward);
|
||||
buffer_stringify_range(buffer, edit.range, new_record->single.str_backward);
|
||||
|
||||
Assert(history->record_lookup.count == history->record_count);
|
||||
}
|
||||
|
||||
Assert(history->record_lookup.count == history->record_count);
|
||||
}
|
||||
|
||||
internal void
|
||||
history_dump_records_after_index(History *history, i32 index){
|
||||
if (!history->activated){
|
||||
return;
|
||||
if (history->activated){
|
||||
Assert(history->record_lookup.count == history->record_count);
|
||||
|
||||
Assert(0 <= index && index <= history->record_count);
|
||||
if (index < history->record_count){
|
||||
Node *node = history__to_node(history, index);
|
||||
Node *first_node_to_clear = node->next;
|
||||
|
||||
Node *sentinel = &history->records;
|
||||
Assert(first_node_to_clear != sentinel);
|
||||
|
||||
Record *first_record_to_clear = CastFromMember(Record, node, first_node_to_clear);
|
||||
end_temp_memory(&history->arena, first_record_to_clear->restore_point);
|
||||
|
||||
Node *last_node_to_clear = sentinel->prev;
|
||||
|
||||
history__free_nodes(history, index + 1, first_node_to_clear, last_node_to_clear);
|
||||
}
|
||||
|
||||
Assert(history->record_lookup.count == history->record_count);
|
||||
}
|
||||
Assert(history->record_lookup.count == history->record_count);
|
||||
|
||||
Assert(0 <= index && index <= history->record_count);
|
||||
if (index < history->record_count){
|
||||
Node *node = history__to_node(history, index);
|
||||
Node *first_node_to_clear = node->next;
|
||||
|
||||
Node *sentinel = &history->records;
|
||||
Assert(first_node_to_clear != sentinel);
|
||||
|
||||
Record *first_record_to_clear = CastFromMember(Record, node, first_node_to_clear);
|
||||
end_temp_memory(&history->arena, first_record_to_clear->restore_point);
|
||||
|
||||
Node *last_node_to_clear = sentinel->prev;
|
||||
|
||||
history__free_nodes(history, index + 1, first_node_to_clear, last_node_to_clear);
|
||||
}
|
||||
|
||||
Assert(history->record_lookup.count == history->record_count);
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -429,91 +370,82 @@ history__optimize_group(Partition *scratch, History *history, Record *record){
|
|||
|
||||
internal void
|
||||
history_merge_records(Partition *scratch, Heap *heap, History *history, i32 first_index, i32 last_index){
|
||||
if (!history->activated){
|
||||
return;
|
||||
}
|
||||
|
||||
Assert(history->record_lookup.count == history->record_count);
|
||||
|
||||
Assert(first_index < last_index);
|
||||
Node *first_node = history__to_node(history, first_index);
|
||||
Node *last_node = history__to_node(history, last_index );
|
||||
Assert(first_node != &history->records && first_node != 0);
|
||||
Assert(last_node != &history->records && last_node != 0);
|
||||
|
||||
Record *new_record = history__allocate_record(heap, history);
|
||||
|
||||
Node *left = first_node->prev;
|
||||
Node *right = last_node->next;
|
||||
left->next = &new_record->node;
|
||||
new_record->node.prev = left;
|
||||
right->prev = &new_record->node;
|
||||
new_record->node.next = right;
|
||||
|
||||
// NOTE(allen): here we remove (last_index - first_index + 1) nodes, and insert 1 node
|
||||
// which simplifies to this:
|
||||
history->record_count -= last_index - first_index;
|
||||
|
||||
Record *first_record = CastFromMember(Record, node, first_node);
|
||||
Record *last_record = CastFromMember(Record, node, last_node);
|
||||
|
||||
new_record->restore_point = first_record->restore_point;
|
||||
new_record->edit_number = last_record->edit_number;
|
||||
new_record->kind = RecordKind_Group;
|
||||
|
||||
Node *new_sentinel = &new_record->group.children;
|
||||
dll_init_sentinel(new_sentinel);
|
||||
|
||||
Node *one_past_last_node = last_node->next;
|
||||
i32 count = 0;
|
||||
for (Node *node = first_node, *next = 0;
|
||||
node != one_past_last_node;
|
||||
node = next){
|
||||
next = node->next;
|
||||
Record *record = CastFromMember(Record, node, node);
|
||||
switch (record->kind){
|
||||
case RecordKind_Single:
|
||||
{
|
||||
dll_insert_back(new_sentinel, &record->node);
|
||||
count += 1;
|
||||
}break;
|
||||
|
||||
case RecordKind_Batch:
|
||||
{
|
||||
dll_insert_back(new_sentinel, &record->node);
|
||||
count += 1;
|
||||
}break;
|
||||
|
||||
case RecordKind_Group:
|
||||
{
|
||||
Node *first = record->group.children.next;
|
||||
Node *last = record->group.children.prev;
|
||||
Assert(first != &record->group.children);
|
||||
Assert(last != &record->group.children);
|
||||
if (history->activated){
|
||||
Assert(history->record_lookup.count == history->record_count);
|
||||
Assert(first_index < last_index);
|
||||
Node *first_node = history__to_node(history, first_index);
|
||||
Node *last_node = history__to_node(history, last_index );
|
||||
Assert(first_node != &history->records && first_node != 0);
|
||||
Assert(last_node != &history->records && last_node != 0);
|
||||
|
||||
Record *new_record = history__allocate_record(heap, history);
|
||||
|
||||
Node *left = first_node->prev;
|
||||
Node *right = last_node->next;
|
||||
left->next = &new_record->node;
|
||||
new_record->node.prev = left;
|
||||
right->prev = &new_record->node;
|
||||
new_record->node.next = right;
|
||||
|
||||
// NOTE(allen): here we remove (last_index - first_index + 1) nodes, and insert 1 node
|
||||
// which simplifies to this:
|
||||
history->record_count -= last_index - first_index;
|
||||
|
||||
Record *first_record = CastFromMember(Record, node, first_node);
|
||||
Record *last_record = CastFromMember(Record, node, last_node);
|
||||
|
||||
new_record->restore_point = first_record->restore_point;
|
||||
new_record->edit_number = last_record->edit_number;
|
||||
new_record->kind = RecordKind_Group;
|
||||
|
||||
Node *new_sentinel = &new_record->group.children;
|
||||
dll_init_sentinel(new_sentinel);
|
||||
|
||||
Node *one_past_last_node = last_node->next;
|
||||
i32 count = 0;
|
||||
for (Node *node = first_node, *next = 0;
|
||||
node != one_past_last_node;
|
||||
node = next){
|
||||
next = node->next;
|
||||
Record *record = CastFromMember(Record, node, node);
|
||||
switch (record->kind){
|
||||
case RecordKind_Single:
|
||||
{
|
||||
dll_insert_back(new_sentinel, &record->node);
|
||||
count += 1;
|
||||
}break;
|
||||
|
||||
Node *sub_right = new_sentinel;
|
||||
Node *sub_left = new_sentinel->prev;
|
||||
sub_left->next = first;
|
||||
first->prev = sub_left;
|
||||
last->next = sub_right;
|
||||
sub_right->prev = last;
|
||||
count += record->group.count;
|
||||
}break;
|
||||
|
||||
default:
|
||||
{
|
||||
InvalidCodePath;
|
||||
}break;
|
||||
case RecordKind_Group:
|
||||
{
|
||||
Node *first = record->group.children.next;
|
||||
Node *last = record->group.children.prev;
|
||||
Assert(first != &record->group.children);
|
||||
Assert(last != &record->group.children);
|
||||
|
||||
Node *sub_right = new_sentinel;
|
||||
Node *sub_left = new_sentinel->prev;
|
||||
sub_left->next = first;
|
||||
first->prev = sub_left;
|
||||
last->next = sub_right;
|
||||
sub_right->prev = last;
|
||||
count += record->group.count;
|
||||
}break;
|
||||
|
||||
default:
|
||||
{
|
||||
InvalidCodePath;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
new_record->group.count = count;
|
||||
|
||||
history__merge_record_ptr_range_to_one_ptr(&history->record_lookup, first_index, last_index, new_record);
|
||||
Assert(history->record_lookup.count == history->record_count);
|
||||
|
||||
if (first_index == history->record_count){
|
||||
history__optimize_group(scratch, history, new_record);
|
||||
}
|
||||
}
|
||||
|
||||
new_record->group.count = count;
|
||||
|
||||
history__merge_record_ptr_range_to_one_ptr(&history->record_lookup, first_index, last_index, new_record);
|
||||
Assert(history->record_lookup.count == history->record_count);
|
||||
|
||||
if (first_index == history->record_count){
|
||||
history__optimize_group(scratch, history, new_record);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -133,6 +133,16 @@ layout_get_next_open_panel(Layout *layout, Panel *panel){
|
|||
return(panel);
|
||||
}
|
||||
|
||||
internal Panel*
|
||||
layout_get_prev_open_panel(Layout *layout, Panel *panel){
|
||||
panel = CastFromMember(Panel, node, panel->node.prev);
|
||||
if (&panel->node == &layout->open_panels){
|
||||
panel = 0;
|
||||
}
|
||||
AssertImplies(panel != 0, panel->kind == PanelKind_Final);
|
||||
return(panel);
|
||||
}
|
||||
|
||||
internal Panel*
|
||||
layout_get_active_panel(Layout *layout){
|
||||
return(layout->active_panel);
|
||||
|
|
Loading…
Reference in New Issue