Merge branch 'master' of https://bitbucket.org/4coder/4coder
commit
df86363f81
|
@ -56,18 +56,6 @@ ENUM(uint32_t, Key_Modifier_Flag){
|
|||
MDFR_SHIFT = 0x8,
|
||||
};
|
||||
|
||||
/* DOC(A Command_ID is used as a name for commands implemented internally in 4coder.) */
|
||||
ENUM(uint64_t, Command_ID){
|
||||
/* DOC(cmdid_null is set aside to always be zero and is not associated with any command.) */
|
||||
cmdid_null,
|
||||
/* DOC(cmdid_undo performs a standard undo behavior.) */
|
||||
cmdid_undo,
|
||||
/* DOC(cmdid_redo reperforms an edit that was undone.) */
|
||||
cmdid_redo,
|
||||
// count
|
||||
cmdid_count
|
||||
};
|
||||
|
||||
/* DOC(Flags for describing the memory protection status of pages that come back from memory allocate. Some combinations may not be available on some platforms, but you are gauranteed to get back a page with at least the permissions you requested. For example if you request just write permission, you may get back a page with read and write permission, but you will never get back a page that doesn't have write permission.) */
|
||||
ENUM(uint32_t, Memory_Protect_Flags){
|
||||
/* DOC(Allows the page to be read.) */
|
||||
|
@ -139,6 +127,9 @@ ENUM(int32_t, Buffer_Setting_ID){
|
|||
|
||||
/* DOC(The BufferSetting_VirtualWhitespace setting enables virtual whitespace on a buffer. Text buffers with virtual whitespace will set the indentation of every line to zero. Buffers with lexing enabled will use virtual white space to present the code with appealing indentation.) */
|
||||
BufferSetting_VirtualWhitespace,
|
||||
|
||||
/* DOC(TODO) */
|
||||
BufferSetting_RecordsHistory,
|
||||
};
|
||||
|
||||
/* DOC(A View_Setting_ID names an adjustable setting in a view.) */
|
||||
|
@ -479,15 +470,10 @@ STRUCT GUI_Scroll_Vars{
|
|||
float scroll_y;
|
||||
/* DOC(The target y position to which the view is moving. If scroll_y is not the same value, then it is still sliding to the target by the smooth scroll rule.) */
|
||||
int32_t target_y;
|
||||
/* DOC(The previous value of target y. This value should be ignored as it is the "vestigial" remain of a system that will not be around much longer.) */
|
||||
int32_t prev_target_y;
|
||||
|
||||
/* DOC(The current actual x position of the view scroll.) */
|
||||
float scroll_x;
|
||||
/* DOC(The target x position to which the view is moving. If scroll_x is not the same value, then it is still sliding to the target by the smooth scroll rule.) */
|
||||
int32_t target_x;
|
||||
/* DOC(The previous value of target x. This value should be ignored as it is the "vestigial" remain of a system that will not be around much longer.) */
|
||||
int32_t prev_target_x;
|
||||
};
|
||||
|
||||
/* DOC(The Buffer_Seek_Type is is used in a Buffer_Seek to identify which coordinates are suppose to be used for the seek.)
|
||||
|
@ -573,17 +559,8 @@ STRUCT Partial_Cursor{
|
|||
int32_t character;
|
||||
};
|
||||
|
||||
/* DOC(Buffer_Edit describes a range of a buffer and string to replace that range. A Buffer_Edit has to be paired with a string that contains the actual text that will be replaced into the buffer.) */
|
||||
STRUCT Buffer_Edit{
|
||||
/* DOC(The str_start field specifies the first character in the accompanying string that corresponds with this edit.) */
|
||||
int32_t str_start;
|
||||
/* DOC(The len field specifies the length of the string being written into the buffer.) */
|
||||
int32_t len;
|
||||
/* DOC(The start field specifies the start of the range in the buffer to replace in absolute position.) */
|
||||
int32_t start;
|
||||
/* DOC(The end field specifies one past the end of the range in the buffer to replace in absolute position.) */
|
||||
int32_t end;
|
||||
};
|
||||
TYPEDEF_FUNC bool32 Buffer_Edit_Handler(struct Application_Links *app, Buffer_ID buffer_id, int32_t start, int32_t one_past_last, String str);
|
||||
// TODO(allen): what to do with batches???
|
||||
|
||||
/* DOC(Buffer_Summary acts as a handle to a buffer and describes the state of the buffer.)
|
||||
DOC_SEE(Access_Flag)
|
||||
|
@ -598,6 +575,9 @@ STRUCT Buffer_Summary{
|
|||
/* DOC(If this is not a null summary, this field contains flags describing the protection status of the buffer.) */
|
||||
Access_Flag lock_flags;
|
||||
|
||||
/* DOC(TODO) */
|
||||
Buffer_Edit_Handler *edit_handler;
|
||||
|
||||
/* DOC(If this is not a null summary, this field specifies the number of bytes in the buffer.) */
|
||||
int32_t size;
|
||||
/* DOC(If this is not a null summary, this field specifies the number of lines in the buffer.) */
|
||||
|
@ -993,8 +973,22 @@ ENUM(int32_t, Buffer_Batch_Edit_Type){
|
|||
BatchEdit_PreserveTokens
|
||||
};
|
||||
|
||||
/* DOC(Buffer_Edit describes a range of a buffer and string to replace that range. A Buffer_Edit has to be paired with a string that contains the actual
|
||||
text that will be replaced into the buffer.) */
|
||||
STRUCT Buffer_Edit{
|
||||
/* DOC(The str_start field specifies the first character in the accompanying string that corresponds with this edit.) */
|
||||
int32_t str_start;
|
||||
/* DOC(The len field specifies the length of the string being written into the buffer.) */
|
||||
int32_t len;
|
||||
/* DOC(The start field specifies the start of the range in the buffer to replace in absolute position.) */
|
||||
int32_t start;
|
||||
/* DOC(The end field specifies one past the end of the range in the buffer to replace in absolute position.) */
|
||||
int32_t end;
|
||||
};
|
||||
|
||||
/*
|
||||
DOC(This struct is used to bundle the parameters of the buffer_batch_edit function. It is convenient for a few functions that return a batch edit to the user.)
|
||||
DOC_SEE(Buffer_Edit)
|
||||
DOC_SEE(buffer_batch_edit)
|
||||
*/
|
||||
STRUCT Buffer_Batch_Edit{
|
||||
|
@ -1009,6 +1003,48 @@ STRUCT Buffer_Batch_Edit{
|
|||
int32_t edit_count;
|
||||
};
|
||||
|
||||
ENUM(int32_t, Record_Kind){
|
||||
RecordKind_Single,
|
||||
RecordKind_Batch,
|
||||
RecordKind_Group,
|
||||
};
|
||||
|
||||
ENUM(int32_t, Record_Error){
|
||||
RecordError_NoError,
|
||||
RecordError_InvalidBuffer,
|
||||
RecordError_NoHistoryAttached,
|
||||
RecordError_IndexOutOfBounds,
|
||||
RecordError_InitialStateDummyRecord,
|
||||
RecordError_WrongRecordTypeAtIndex,
|
||||
};
|
||||
|
||||
ENUM(uint32_t, Record_Merge_Flag){
|
||||
RecordMergeFlag_StateInRange_MoveStateForward = 0x0,
|
||||
RecordMergeFlag_StateInRange_MoveStateBackward = 0x1,
|
||||
RecordMergeFlag_StateInRange_ErrorOut = 0x2,
|
||||
};
|
||||
|
||||
TYPEDEF int32_t History_Record_Index;
|
||||
|
||||
STRUCT Record_Info{
|
||||
Record_Error error;
|
||||
Record_Kind kind;
|
||||
int32_t edit_number;
|
||||
union{
|
||||
struct{
|
||||
String string_forward;
|
||||
String string_backward;
|
||||
int32_t first;
|
||||
} single;
|
||||
struct{
|
||||
Buffer_Batch_Edit_Type type;
|
||||
int32_t count;
|
||||
} batch;
|
||||
struct{
|
||||
int32_t count;
|
||||
} group;
|
||||
};
|
||||
};
|
||||
|
||||
/* DOC(Custom_Command_Function is a function type which matches the signature used for commands. To declare a command use CUSTOM_COMMAND_SIG.) DOC_SEE(CUSTOM_COMMAND_SIG) */
|
||||
TYPEDEF void Custom_Command_Function(struct Application_Links *app);
|
||||
|
@ -1029,10 +1065,7 @@ TYPEDEF void Custom_Command_Function(struct Application_Links *app);
|
|||
|
||||
/* DOC(Generic_Command acts as a name for a command, and can name an internal command or a custom command.) */
|
||||
UNION Generic_Command{
|
||||
/* DOC(If this Generic_Command represents an internal command the cmdid field will have a value less than cmdid_count, and this field is the command id for the command.) */
|
||||
Command_ID cmdid;
|
||||
/* DOC(If this Generic_Command does not represent an internal command the command
|
||||
field is the pointer to the custom command..) */
|
||||
/* DOC(If this Generic_Command does not represent an internal command the command field is the pointer to the custom command..) */
|
||||
Custom_Command_Function *command;
|
||||
};
|
||||
|
||||
|
@ -1159,7 +1192,6 @@ DOC_SEE(Binding_Unit)
|
|||
ENUM(int32_t, Binding_Unit_Type){
|
||||
unit_header,
|
||||
unit_map_begin,
|
||||
unit_binding,
|
||||
unit_callback,
|
||||
unit_inherit,
|
||||
unit_hook
|
||||
|
@ -1185,7 +1217,6 @@ STRUCT Binding_Unit{
|
|||
STRUCT{ int32_t total_size; int32_t user_map_count; int32_t error; } header;
|
||||
STRUCT{ int32_t mapid; int32_t replace; int32_t bind_count; } map_begin;
|
||||
STRUCT{ int32_t mapid; } map_inherit;
|
||||
STRUCT{ Key_Code code; uint8_t modifiers; Command_ID command_id; } binding;
|
||||
STRUCT{ Key_Code code; uint8_t modifiers; Custom_Command_Function *func; } callback;
|
||||
STRUCT{ int32_t hook_id; void *func; } hook;
|
||||
};
|
||||
|
|
|
@ -9,7 +9,7 @@ buffer_find_hard_start(Application_Links *app, Buffer_Summary *buffer, int32_t l
|
|||
tab_width -= 1;
|
||||
|
||||
Hard_Start_Result result = {};
|
||||
result.all_space = 1;
|
||||
result.all_space = true;
|
||||
result.indent_pos = 0;
|
||||
result.char_pos = line_start;
|
||||
|
||||
|
@ -17,7 +17,7 @@ buffer_find_hard_start(Application_Links *app, Buffer_Summary *buffer, int32_t l
|
|||
Stream_Chunk stream = {};
|
||||
stream.add_null = true;
|
||||
if (init_stream_chunk(&stream, app, buffer, line_start, data_chunk, sizeof(data_chunk))){
|
||||
int32_t still_looping = 1;
|
||||
bool32 still_looping = true;
|
||||
do{
|
||||
for (; result.char_pos < stream.end; ++result.char_pos){
|
||||
char c = stream.data[result.char_pos];
|
||||
|
@ -36,7 +36,7 @@ buffer_find_hard_start(Application_Links *app, Buffer_Summary *buffer, int32_t l
|
|||
}
|
||||
|
||||
if (c != ' '){
|
||||
result.all_space = 0;
|
||||
result.all_space = false;
|
||||
}
|
||||
|
||||
result.indent_pos += 1;
|
||||
|
@ -51,8 +51,7 @@ buffer_find_hard_start(Application_Links *app, Buffer_Summary *buffer, int32_t l
|
|||
|
||||
static Buffer_Batch_Edit
|
||||
make_batch_from_indent_marks(Application_Links *app, Partition *arena, Buffer_Summary *buffer,
|
||||
int32_t first_line, int32_t one_past_last_line,
|
||||
int32_t *indent_marks, Indent_Options opts){
|
||||
int32_t first_line, int32_t one_past_last_line, int32_t *indent_marks, Indent_Options opts){
|
||||
int32_t *shifted_indent_marks = indent_marks - first_line;
|
||||
|
||||
int32_t edit_count = 0;
|
||||
|
|
|
@ -8,26 +8,54 @@ moving the cursor, which work even without the default 4coder framework.
|
|||
static void
|
||||
write_character_parameter(Application_Links *app, uint8_t *character, uint32_t length){
|
||||
if (length != 0){
|
||||
uint32_t access = AccessOpen;
|
||||
View_Summary view = get_active_view(app, access);
|
||||
View_Summary view = get_active_view(app, AccessOpen);
|
||||
if_view_has_highlighted_range_delete_range(app, view.view_id);
|
||||
view = get_view(app, view.view_id, AccessAll);
|
||||
|
||||
Buffer_Summary buffer = get_buffer(app, view.buffer_id, access);
|
||||
Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen);
|
||||
int32_t pos = view.cursor.pos;
|
||||
|
||||
// NOTE(allen): setup markers to figure out the new position of cursor after the insert
|
||||
Marker next_cursor_marker = {};
|
||||
next_cursor_marker.pos = character_pos_to_pos(app, &view, &buffer, view.cursor.character_pos);
|
||||
next_cursor_marker.lean_right = true;
|
||||
|
||||
Managed_Object handle = alloc_buffer_markers_on_buffer(app, buffer.buffer_id, 1, 0);
|
||||
managed_object_store_data(app, handle, 0, 1, &next_cursor_marker);
|
||||
|
||||
// NOTE(allen): consecutive inserts merge logic
|
||||
History_Record_Index first_index = buffer_history_get_current_state_index(app, &buffer);
|
||||
bool32 do_merge = false;
|
||||
if (character[0] != '\n'){
|
||||
Record_Info record = get_single_record(app, buffer.buffer_id, first_index);
|
||||
if (record.error == RecordError_NoError && record.kind == RecordKind_Single){
|
||||
String string = record.single.string_forward;
|
||||
int32_t last_end = record.single.first + string.size;
|
||||
if (last_end == pos && string.size > 0){
|
||||
char c = string.str[string.size - 1];
|
||||
if (c != '\n'){
|
||||
if (char_is_whitespace(character[0]) && char_is_whitespace(c)){
|
||||
do_merge = true;
|
||||
}
|
||||
else if (char_is_alpha_numeric(character[0]) && char_is_alpha_numeric(c)){
|
||||
do_merge = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(allen): perform the edit
|
||||
buffer_replace_range(app, &buffer, pos, pos, (char*)character, length);
|
||||
|
||||
// NOTE(allen): finish merging records if necessary
|
||||
if (do_merge){
|
||||
History_Record_Index last_index = buffer_history_get_current_state_index(app, &buffer);
|
||||
buffer_history_merge_record_range(app, &buffer, first_index, last_index, RecordMergeFlag_StateInRange_MoveStateForward);
|
||||
}
|
||||
|
||||
// NOTE(allen): finish updating the cursor
|
||||
managed_object_load_data(app, handle, 0, 1, &next_cursor_marker);
|
||||
managed_object_free(app, handle);
|
||||
|
||||
view_set_cursor(app, &view, seek_pos(next_cursor_marker.pos), true);
|
||||
}
|
||||
}
|
||||
|
@ -928,13 +956,15 @@ CUSTOM_DOC("Queries the user for two strings, and replaces all occurences of the
|
|||
int32_t new_pos;
|
||||
buffer_seek_string_forward(app, &buffer, pos, 0, r.str, r.size, &new_pos);
|
||||
|
||||
while (new_pos + r.size <= range.end){
|
||||
global_history_edit_group_begin(app);
|
||||
for (;new_pos + r.size <= range.end;){
|
||||
buffer_replace_range(app, &buffer, new_pos, new_pos + r.size, w.str, w.size);
|
||||
refresh_view(app, &view);
|
||||
range = get_view_range(&view);
|
||||
pos = new_pos + w.size;
|
||||
buffer_seek_string_forward(app, &buffer, pos, 0, r.str, r.size, &new_pos);
|
||||
}
|
||||
global_history_edit_group_end(app);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1579,16 +1609,165 @@ CUSTOM_DOC("Reopen the current buffer from the hard drive.")
|
|||
|
||||
////////////////////////////////
|
||||
|
||||
CUSTOM_COMMAND_SIG(undo)
|
||||
CUSTOM_DOC("Advances backwards through the undo history.")
|
||||
CUSTOM_COMMAND_SIG(undo_this_buffer)
|
||||
CUSTOM_DOC("Advances backwards through the undo history of the current buffer.")
|
||||
{
|
||||
exec_command(app, cmdid_undo);
|
||||
View_Summary view = get_active_view(app, AccessOpen);
|
||||
Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(redo_this_buffer)
|
||||
CUSTOM_DOC("Advances forwards through the undo history of the current buffer.")
|
||||
{
|
||||
View_Summary view = get_active_view(app, AccessOpen);
|
||||
Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen);
|
||||
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);
|
||||
if (current < max_index){
|
||||
buffer_history_set_current_state_index(app, &buffer, current + 1);
|
||||
}
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(undo)
|
||||
CUSTOM_DOC("Advances backward through the undo history in the buffer containing the most recent regular edit.")
|
||||
{
|
||||
Partition *scratch = &global_part;
|
||||
int32_t highest_edit_number = -1;
|
||||
Buffer_ID first_buffer_match = 0;
|
||||
Buffer_ID last_buffer_match = 0;
|
||||
int32_t match_count = 0;
|
||||
|
||||
for (Buffer_Summary buffer = get_buffer_first(app, AccessAll);
|
||||
buffer.exists;
|
||||
get_buffer_next(app, &buffer, AccessAll)){
|
||||
History_Record_Index index = buffer_history_get_current_state_index(app, &buffer);
|
||||
if (index > 0){
|
||||
Record_Info record = buffer_history_get_record_info(app, &buffer, index);
|
||||
if (record.edit_number > highest_edit_number){
|
||||
highest_edit_number = record.edit_number;
|
||||
first_buffer_match = buffer.buffer_id;
|
||||
last_buffer_match = buffer.buffer_id;
|
||||
match_count = 1;
|
||||
}
|
||||
else if (record.edit_number == highest_edit_number){
|
||||
last_buffer_match = buffer.buffer_id;
|
||||
match_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Temp_Memory temp = begin_temp_memory(scratch);
|
||||
Buffer_ID *match_buffers = push_array(scratch, Buffer_ID, match_count);
|
||||
match_count = 0;
|
||||
|
||||
if (highest_edit_number != -1){
|
||||
for (Buffer_Summary buffer = get_buffer(app, first_buffer_match, AccessAll);
|
||||
buffer.exists;
|
||||
get_buffer_next(app, &buffer, AccessAll)){
|
||||
bool32 did_match = false;
|
||||
for (;;){
|
||||
History_Record_Index index = buffer_history_get_current_state_index(app, &buffer);
|
||||
if (index > 0){
|
||||
Record_Info record = buffer_history_get_record_info(app, &buffer, index);
|
||||
if (record.edit_number == highest_edit_number){
|
||||
did_match = true;
|
||||
buffer_history_set_current_state_index(app, &buffer, index - 1);
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (did_match){
|
||||
match_buffers[match_count] = buffer.buffer_id;
|
||||
match_count += 1;
|
||||
}
|
||||
if (buffer.buffer_id == last_buffer_match){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
view_buffer_set(app, match_buffers, match_count);
|
||||
|
||||
end_temp_memory(temp);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(redo)
|
||||
CUSTOM_DOC("Advances forewards through the undo history.")
|
||||
CUSTOM_DOC("Advances forward through the undo history in the buffer containing the most recent regular edit.")
|
||||
{
|
||||
exec_command(app, cmdid_redo);
|
||||
Partition *scratch = &global_part;
|
||||
int32_t lowest_edit_number = 0x7FFFFFFF;
|
||||
Buffer_ID first_buffer_match = 0;
|
||||
Buffer_ID last_buffer_match = 0;
|
||||
int32_t match_count = 0;
|
||||
|
||||
for (Buffer_Summary buffer = get_buffer_first(app, AccessAll);
|
||||
buffer.exists;
|
||||
get_buffer_next(app, &buffer, AccessAll)){
|
||||
History_Record_Index max_index = buffer_history_get_max_record_index(app, &buffer);
|
||||
History_Record_Index index = buffer_history_get_current_state_index(app, &buffer);
|
||||
if (index < max_index){
|
||||
Record_Info record = buffer_history_get_record_info(app, &buffer, index + 1);
|
||||
if (record.edit_number < lowest_edit_number){
|
||||
lowest_edit_number = record.edit_number;
|
||||
first_buffer_match = buffer.buffer_id;
|
||||
last_buffer_match = buffer.buffer_id;
|
||||
match_count = 1;
|
||||
}
|
||||
else if (record.edit_number == lowest_edit_number){
|
||||
last_buffer_match = buffer.buffer_id;
|
||||
match_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Temp_Memory temp = begin_temp_memory(scratch);
|
||||
Buffer_ID *match_buffers = push_array(scratch, Buffer_ID, match_count);
|
||||
match_count = 0;
|
||||
|
||||
if (lowest_edit_number != -1){
|
||||
for (Buffer_Summary buffer = get_buffer(app, first_buffer_match, AccessAll);
|
||||
buffer.exists;
|
||||
get_buffer_next(app, &buffer, AccessAll)){
|
||||
bool32 did_match = false;
|
||||
History_Record_Index max_index = buffer_history_get_max_record_index(app, &buffer);
|
||||
for (;;){
|
||||
History_Record_Index index = buffer_history_get_current_state_index(app, &buffer);
|
||||
if (index < max_index){
|
||||
Record_Info record = buffer_history_get_record_info(app, &buffer, index + 1);
|
||||
if (record.edit_number == lowest_edit_number){
|
||||
did_match = true;
|
||||
buffer_history_set_current_state_index(app, &buffer, index + 1);
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (did_match){
|
||||
match_buffers[match_count] = buffer.buffer_id;
|
||||
match_count += 1;
|
||||
}
|
||||
if (buffer.buffer_id == last_buffer_match){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
view_buffer_set(app, match_buffers, match_count);
|
||||
|
||||
end_temp_memory(temp);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
|
|
@ -184,12 +184,14 @@ CUSTOM_DOC("Create a new panel by horizontally splitting the active panel.")
|
|||
// NOTE(allen): Credits to nj/FlyingSolomon for authoring the original version of this helper.
|
||||
|
||||
static Buffer_ID
|
||||
create_or_switch_to_buffer_by_name(Application_Links *app, char *name, int32_t name_length,
|
||||
View_Summary default_target_view){
|
||||
create_or_switch_to_buffer_by_name(Application_Links *app, char *name, int32_t name_length, View_Summary default_target_view){
|
||||
uint32_t access = AccessAll;
|
||||
Buffer_Summary search_buffer = get_buffer_by_name(app, name, name_length, access);
|
||||
|
||||
if (search_buffer.exists){
|
||||
buffer_set_setting(app, &search_buffer, BufferSetting_ReadOnly, true);
|
||||
buffer_set_edit_handler(app, search_buffer.buffer_id, 0);
|
||||
|
||||
View_Summary target_view = default_target_view;
|
||||
|
||||
View_Summary view_with_buffer_already_open = get_first_view_with_buffer(app, search_buffer.buffer_id);
|
||||
|
|
|
@ -721,6 +721,7 @@ static void
|
|||
replace_all_occurrences_parameters(Application_Links *app, Heap *heap, Partition *part, String target_string, String new_string){
|
||||
if (target_string.size <= 0) return;
|
||||
|
||||
global_history_edit_group_begin(app);
|
||||
for (bool32 got_all_occurrences = false;
|
||||
!got_all_occurrences;){
|
||||
// Initialize a generic search all buffers
|
||||
|
@ -773,6 +774,7 @@ replace_all_occurrences_parameters(Application_Links *app, Heap *heap, Partition
|
|||
|
||||
end_temp_memory(temp);
|
||||
}
|
||||
global_history_edit_group_end(app);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(replace_all_occurrences)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
struct Application_Links;
|
||||
#define GLOBAL_SET_SETTING_SIG(n) bool32 n(Application_Links *app, Global_Setting_ID setting, int32_t value)
|
||||
#define GLOBAL_SET_MAPPING_SIG(n) bool32 n(Application_Links *app, void *data, int32_t size)
|
||||
#define EXEC_COMMAND_SIG(n) bool32 n(Application_Links *app, Command_ID command_id)
|
||||
#define EXEC_SYSTEM_COMMAND_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Identifier buffer_id, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags)
|
||||
#define CLIPBOARD_POST_SIG(n) void n(Application_Links *app, int32_t clipboard_id, char *str, int32_t len)
|
||||
#define CLIPBOARD_COUNT_SIG(n) int32_t n(Application_Links *app, int32_t clipboard_id)
|
||||
|
@ -14,7 +13,8 @@ struct Application_Links;
|
|||
#define GET_BUFFER_BY_NAME_SIG(n) Buffer_Summary n(Application_Links *app, char *name, int32_t len, Access_Flag access)
|
||||
#define GET_BUFFER_BY_FILE_NAME_SIG(n) Buffer_Summary n(Application_Links *app, char *name, int32_t len, Access_Flag access)
|
||||
#define BUFFER_READ_RANGE_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *out)
|
||||
#define BUFFER_REPLACE_RANGE_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *str, int32_t len)
|
||||
#define BUFFER_REPLACE_RANGE_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t one_past_last, char *str, int32_t len)
|
||||
#define BUFFER_SET_EDIT_HANDLER_SIG(n) bool32 n(Application_Links *app, Buffer_ID buffer_id, Buffer_Edit_Handler *handler)
|
||||
#define BUFFER_COMPUTE_CURSOR_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out)
|
||||
#define BUFFER_BATCH_EDIT_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type)
|
||||
#define BUFFER_GET_SETTING_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t *value_out)
|
||||
|
@ -96,6 +96,15 @@ struct Application_Links;
|
|||
#define GET_LARGEST_FACE_ID_SIG(n) Face_ID n(Application_Links *app)
|
||||
#define SET_GLOBAL_FACE_SIG(n) bool32 n(Application_Links *app, Face_ID id, bool32 apply_to_all_buffers)
|
||||
#define BUFFER_SET_FACE_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Face_ID id)
|
||||
#define BUFFER_HISTORY_GET_MAX_RECORD_INDEX_SIG(n) History_Record_Index n(Application_Links *app, Buffer_Summary *buffer)
|
||||
#define BUFFER_HISTORY_GET_RECORD_INFO_SIG(n) Record_Info n(Application_Links *app, Buffer_Summary *buffer, History_Record_Index index)
|
||||
#define BUFFER_HISTORY_GET_GROUP_SUB_RECORD_SIG(n) Record_Info n(Application_Links *app, Buffer_Summary *buffer, History_Record_Index index, int32_t sub_index)
|
||||
#define BUFFER_HISTORY_GET_CURRENT_STATE_INDEX_SIG(n) History_Record_Index n(Application_Links *app, Buffer_Summary *buffer)
|
||||
#define BUFFER_HISTORY_SET_CURRENT_STATE_INDEX_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, History_Record_Index index)
|
||||
#define BUFFER_HISTORY_MERGE_RECORD_RANGE_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, History_Record_Index first_index, History_Record_Index last_index, Record_Merge_Flag flags)
|
||||
#define BUFFER_HISTORY_CLEAR_AFTER_CURRENT_STATE_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer)
|
||||
#define GLOBAL_HISTORY_EDIT_GROUP_BEGIN_SIG(n) void n(Application_Links *app)
|
||||
#define GLOBAL_HISTORY_EDIT_GROUP_END_SIG(n) void n(Application_Links *app)
|
||||
#define GET_FACE_DESCRIPTION_SIG(n) Face_Description n(Application_Links *app, Face_ID id)
|
||||
#define GET_FACE_ID_SIG(n) Face_ID n(Application_Links *app, Buffer_Summary *buffer)
|
||||
#define TRY_CREATE_NEW_FACE_SIG(n) Face_ID n(Application_Links *app, Face_Description *description)
|
||||
|
@ -129,7 +138,6 @@ struct Application_Links;
|
|||
#define GET_DEFAULT_FONT_FOR_VIEW_SIG(n) Face_ID n(Application_Links *app, View_ID view_id)
|
||||
typedef GLOBAL_SET_SETTING_SIG(Global_Set_Setting_Function);
|
||||
typedef GLOBAL_SET_MAPPING_SIG(Global_Set_Mapping_Function);
|
||||
typedef EXEC_COMMAND_SIG(Exec_Command_Function);
|
||||
typedef EXEC_SYSTEM_COMMAND_SIG(Exec_System_Command_Function);
|
||||
typedef CLIPBOARD_POST_SIG(Clipboard_Post_Function);
|
||||
typedef CLIPBOARD_COUNT_SIG(Clipboard_Count_Function);
|
||||
|
@ -143,6 +151,7 @@ typedef GET_BUFFER_BY_NAME_SIG(Get_Buffer_By_Name_Function);
|
|||
typedef GET_BUFFER_BY_FILE_NAME_SIG(Get_Buffer_By_File_Name_Function);
|
||||
typedef BUFFER_READ_RANGE_SIG(Buffer_Read_Range_Function);
|
||||
typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function);
|
||||
typedef BUFFER_SET_EDIT_HANDLER_SIG(Buffer_Set_Edit_Handler_Function);
|
||||
typedef BUFFER_COMPUTE_CURSOR_SIG(Buffer_Compute_Cursor_Function);
|
||||
typedef BUFFER_BATCH_EDIT_SIG(Buffer_Batch_Edit_Function);
|
||||
typedef BUFFER_GET_SETTING_SIG(Buffer_Get_Setting_Function);
|
||||
|
@ -224,6 +233,15 @@ typedef CHANGE_THEME_BY_INDEX_SIG(Change_Theme_By_Index_Function);
|
|||
typedef GET_LARGEST_FACE_ID_SIG(Get_Largest_Face_ID_Function);
|
||||
typedef SET_GLOBAL_FACE_SIG(Set_Global_Face_Function);
|
||||
typedef BUFFER_SET_FACE_SIG(Buffer_Set_Face_Function);
|
||||
typedef BUFFER_HISTORY_GET_MAX_RECORD_INDEX_SIG(Buffer_History_Get_Max_Record_Index_Function);
|
||||
typedef BUFFER_HISTORY_GET_RECORD_INFO_SIG(Buffer_History_Get_Record_Info_Function);
|
||||
typedef BUFFER_HISTORY_GET_GROUP_SUB_RECORD_SIG(Buffer_History_Get_Group_Sub_Record_Function);
|
||||
typedef BUFFER_HISTORY_GET_CURRENT_STATE_INDEX_SIG(Buffer_History_Get_Current_State_Index_Function);
|
||||
typedef BUFFER_HISTORY_SET_CURRENT_STATE_INDEX_SIG(Buffer_History_Set_Current_State_Index_Function);
|
||||
typedef BUFFER_HISTORY_MERGE_RECORD_RANGE_SIG(Buffer_History_Merge_Record_Range_Function);
|
||||
typedef BUFFER_HISTORY_CLEAR_AFTER_CURRENT_STATE_SIG(Buffer_History_Clear_After_Current_State_Function);
|
||||
typedef GLOBAL_HISTORY_EDIT_GROUP_BEGIN_SIG(Global_History_Edit_Group_Begin_Function);
|
||||
typedef GLOBAL_HISTORY_EDIT_GROUP_END_SIG(Global_History_Edit_Group_End_Function);
|
||||
typedef GET_FACE_DESCRIPTION_SIG(Get_Face_Description_Function);
|
||||
typedef GET_FACE_ID_SIG(Get_Face_ID_Function);
|
||||
typedef TRY_CREATE_NEW_FACE_SIG(Try_Create_New_Face_Function);
|
||||
|
@ -259,7 +277,6 @@ struct Application_Links{
|
|||
#if defined(ALLOW_DEP_4CODER)
|
||||
Global_Set_Setting_Function *global_set_setting;
|
||||
Global_Set_Mapping_Function *global_set_mapping;
|
||||
Exec_Command_Function *exec_command;
|
||||
Exec_System_Command_Function *exec_system_command;
|
||||
Clipboard_Post_Function *clipboard_post;
|
||||
Clipboard_Count_Function *clipboard_count;
|
||||
|
@ -273,6 +290,7 @@ Get_Buffer_By_Name_Function *get_buffer_by_name;
|
|||
Get_Buffer_By_File_Name_Function *get_buffer_by_file_name;
|
||||
Buffer_Read_Range_Function *buffer_read_range;
|
||||
Buffer_Replace_Range_Function *buffer_replace_range;
|
||||
Buffer_Set_Edit_Handler_Function *buffer_set_edit_handler;
|
||||
Buffer_Compute_Cursor_Function *buffer_compute_cursor;
|
||||
Buffer_Batch_Edit_Function *buffer_batch_edit;
|
||||
Buffer_Get_Setting_Function *buffer_get_setting;
|
||||
|
@ -354,6 +372,15 @@ Change_Theme_By_Index_Function *change_theme_by_index;
|
|||
Get_Largest_Face_ID_Function *get_largest_face_id;
|
||||
Set_Global_Face_Function *set_global_face;
|
||||
Buffer_Set_Face_Function *buffer_set_face;
|
||||
Buffer_History_Get_Max_Record_Index_Function *buffer_history_get_max_record_index;
|
||||
Buffer_History_Get_Record_Info_Function *buffer_history_get_record_info;
|
||||
Buffer_History_Get_Group_Sub_Record_Function *buffer_history_get_group_sub_record;
|
||||
Buffer_History_Get_Current_State_Index_Function *buffer_history_get_current_state_index;
|
||||
Buffer_History_Set_Current_State_Index_Function *buffer_history_set_current_state_index;
|
||||
Buffer_History_Merge_Record_Range_Function *buffer_history_merge_record_range;
|
||||
Buffer_History_Clear_After_Current_State_Function *buffer_history_clear_after_current_state;
|
||||
Global_History_Edit_Group_Begin_Function *global_history_edit_group_begin;
|
||||
Global_History_Edit_Group_End_Function *global_history_edit_group_end;
|
||||
Get_Face_Description_Function *get_face_description;
|
||||
Get_Face_ID_Function *get_face_id;
|
||||
Try_Create_New_Face_Function *try_create_new_face;
|
||||
|
@ -388,7 +415,6 @@ Get_Default_Font_For_View_Function *get_default_font_for_view;
|
|||
#else
|
||||
Global_Set_Setting_Function *global_set_setting_;
|
||||
Global_Set_Mapping_Function *global_set_mapping_;
|
||||
Exec_Command_Function *exec_command_;
|
||||
Exec_System_Command_Function *exec_system_command_;
|
||||
Clipboard_Post_Function *clipboard_post_;
|
||||
Clipboard_Count_Function *clipboard_count_;
|
||||
|
@ -402,6 +428,7 @@ Get_Buffer_By_Name_Function *get_buffer_by_name_;
|
|||
Get_Buffer_By_File_Name_Function *get_buffer_by_file_name_;
|
||||
Buffer_Read_Range_Function *buffer_read_range_;
|
||||
Buffer_Replace_Range_Function *buffer_replace_range_;
|
||||
Buffer_Set_Edit_Handler_Function *buffer_set_edit_handler_;
|
||||
Buffer_Compute_Cursor_Function *buffer_compute_cursor_;
|
||||
Buffer_Batch_Edit_Function *buffer_batch_edit_;
|
||||
Buffer_Get_Setting_Function *buffer_get_setting_;
|
||||
|
@ -483,6 +510,15 @@ Change_Theme_By_Index_Function *change_theme_by_index_;
|
|||
Get_Largest_Face_ID_Function *get_largest_face_id_;
|
||||
Set_Global_Face_Function *set_global_face_;
|
||||
Buffer_Set_Face_Function *buffer_set_face_;
|
||||
Buffer_History_Get_Max_Record_Index_Function *buffer_history_get_max_record_index_;
|
||||
Buffer_History_Get_Record_Info_Function *buffer_history_get_record_info_;
|
||||
Buffer_History_Get_Group_Sub_Record_Function *buffer_history_get_group_sub_record_;
|
||||
Buffer_History_Get_Current_State_Index_Function *buffer_history_get_current_state_index_;
|
||||
Buffer_History_Set_Current_State_Index_Function *buffer_history_set_current_state_index_;
|
||||
Buffer_History_Merge_Record_Range_Function *buffer_history_merge_record_range_;
|
||||
Buffer_History_Clear_After_Current_State_Function *buffer_history_clear_after_current_state_;
|
||||
Global_History_Edit_Group_Begin_Function *global_history_edit_group_begin_;
|
||||
Global_History_Edit_Group_End_Function *global_history_edit_group_end_;
|
||||
Get_Face_Description_Function *get_face_description_;
|
||||
Get_Face_ID_Function *get_face_id_;
|
||||
Try_Create_New_Face_Function *try_create_new_face_;
|
||||
|
@ -525,7 +561,6 @@ int32_t type_coroutine;
|
|||
#define FillAppLinksAPI(app_links) do{\
|
||||
app_links->global_set_setting_ = Global_Set_Setting;\
|
||||
app_links->global_set_mapping_ = Global_Set_Mapping;\
|
||||
app_links->exec_command_ = Exec_Command;\
|
||||
app_links->exec_system_command_ = Exec_System_Command;\
|
||||
app_links->clipboard_post_ = Clipboard_Post;\
|
||||
app_links->clipboard_count_ = Clipboard_Count;\
|
||||
|
@ -539,6 +574,7 @@ app_links->get_buffer_by_name_ = Get_Buffer_By_Name;\
|
|||
app_links->get_buffer_by_file_name_ = Get_Buffer_By_File_Name;\
|
||||
app_links->buffer_read_range_ = Buffer_Read_Range;\
|
||||
app_links->buffer_replace_range_ = Buffer_Replace_Range;\
|
||||
app_links->buffer_set_edit_handler_ = Buffer_Set_Edit_Handler;\
|
||||
app_links->buffer_compute_cursor_ = Buffer_Compute_Cursor;\
|
||||
app_links->buffer_batch_edit_ = Buffer_Batch_Edit;\
|
||||
app_links->buffer_get_setting_ = Buffer_Get_Setting;\
|
||||
|
@ -620,6 +656,15 @@ app_links->change_theme_by_index_ = Change_Theme_By_Index;\
|
|||
app_links->get_largest_face_id_ = Get_Largest_Face_ID;\
|
||||
app_links->set_global_face_ = Set_Global_Face;\
|
||||
app_links->buffer_set_face_ = Buffer_Set_Face;\
|
||||
app_links->buffer_history_get_max_record_index_ = Buffer_History_Get_Max_Record_Index;\
|
||||
app_links->buffer_history_get_record_info_ = Buffer_History_Get_Record_Info;\
|
||||
app_links->buffer_history_get_group_sub_record_ = Buffer_History_Get_Group_Sub_Record;\
|
||||
app_links->buffer_history_get_current_state_index_ = Buffer_History_Get_Current_State_Index;\
|
||||
app_links->buffer_history_set_current_state_index_ = Buffer_History_Set_Current_State_Index;\
|
||||
app_links->buffer_history_merge_record_range_ = Buffer_History_Merge_Record_Range;\
|
||||
app_links->buffer_history_clear_after_current_state_ = Buffer_History_Clear_After_Current_State;\
|
||||
app_links->global_history_edit_group_begin_ = Global_History_Edit_Group_Begin;\
|
||||
app_links->global_history_edit_group_end_ = Global_History_Edit_Group_End;\
|
||||
app_links->get_face_description_ = Get_Face_Description;\
|
||||
app_links->get_face_id_ = Get_Face_ID;\
|
||||
app_links->try_create_new_face_ = Try_Create_New_Face;\
|
||||
|
@ -654,7 +699,6 @@ app_links->get_default_font_for_view_ = Get_Default_Font_For_View;} while(false)
|
|||
#if defined(ALLOW_DEP_4CODER)
|
||||
static bool32 global_set_setting(Application_Links *app, Global_Setting_ID setting, int32_t value){return(app->global_set_setting(app, setting, value));}
|
||||
static bool32 global_set_mapping(Application_Links *app, void *data, int32_t size){return(app->global_set_mapping(app, data, size));}
|
||||
static bool32 exec_command(Application_Links *app, Command_ID command_id){return(app->exec_command(app, command_id));}
|
||||
static bool32 exec_system_command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer_id, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags){return(app->exec_system_command(app, view, buffer_id, path, path_len, command, command_len, flags));}
|
||||
static void clipboard_post(Application_Links *app, int32_t clipboard_id, char *str, int32_t len){(app->clipboard_post(app, clipboard_id, str, len));}
|
||||
static int32_t clipboard_count(Application_Links *app, int32_t clipboard_id){return(app->clipboard_count(app, clipboard_id));}
|
||||
|
@ -667,7 +711,8 @@ static Buffer_Summary get_buffer(Application_Links *app, Buffer_ID buffer_id, Ac
|
|||
static Buffer_Summary get_buffer_by_name(Application_Links *app, char *name, int32_t len, Access_Flag access){return(app->get_buffer_by_name(app, name, len, access));}
|
||||
static Buffer_Summary get_buffer_by_file_name(Application_Links *app, char *name, int32_t len, Access_Flag access){return(app->get_buffer_by_file_name(app, name, len, access));}
|
||||
static bool32 buffer_read_range(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *out){return(app->buffer_read_range(app, buffer, start, end, out));}
|
||||
static bool32 buffer_replace_range(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *str, int32_t len){return(app->buffer_replace_range(app, buffer, start, end, str, len));}
|
||||
static bool32 buffer_replace_range(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t one_past_last, char *str, int32_t len){return(app->buffer_replace_range(app, buffer, start, one_past_last, str, len));}
|
||||
static bool32 buffer_set_edit_handler(Application_Links *app, Buffer_ID buffer_id, Buffer_Edit_Handler *handler){return(app->buffer_set_edit_handler(app, buffer_id, handler));}
|
||||
static bool32 buffer_compute_cursor(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out){return(app->buffer_compute_cursor(app, buffer, seek, cursor_out));}
|
||||
static bool32 buffer_batch_edit(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type){return(app->buffer_batch_edit(app, buffer, str, str_len, edits, edit_count, type));}
|
||||
static bool32 buffer_get_setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t *value_out){return(app->buffer_get_setting(app, buffer, setting, value_out));}
|
||||
|
@ -749,6 +794,15 @@ static bool32 change_theme_by_index(Application_Links *app, int32_t index){retur
|
|||
static Face_ID get_largest_face_id(Application_Links *app){return(app->get_largest_face_id(app));}
|
||||
static bool32 set_global_face(Application_Links *app, Face_ID id, bool32 apply_to_all_buffers){return(app->set_global_face(app, id, apply_to_all_buffers));}
|
||||
static bool32 buffer_set_face(Application_Links *app, Buffer_Summary *buffer, Face_ID id){return(app->buffer_set_face(app, buffer, id));}
|
||||
static History_Record_Index buffer_history_get_max_record_index(Application_Links *app, Buffer_Summary *buffer){return(app->buffer_history_get_max_record_index(app, buffer));}
|
||||
static Record_Info buffer_history_get_record_info(Application_Links *app, Buffer_Summary *buffer, History_Record_Index index){return(app->buffer_history_get_record_info(app, buffer, index));}
|
||||
static Record_Info buffer_history_get_group_sub_record(Application_Links *app, Buffer_Summary *buffer, History_Record_Index index, int32_t sub_index){return(app->buffer_history_get_group_sub_record(app, buffer, index, sub_index));}
|
||||
static History_Record_Index buffer_history_get_current_state_index(Application_Links *app, Buffer_Summary *buffer){return(app->buffer_history_get_current_state_index(app, buffer));}
|
||||
static bool32 buffer_history_set_current_state_index(Application_Links *app, Buffer_Summary *buffer, History_Record_Index index){return(app->buffer_history_set_current_state_index(app, buffer, index));}
|
||||
static bool32 buffer_history_merge_record_range(Application_Links *app, Buffer_Summary *buffer, History_Record_Index first_index, History_Record_Index last_index, Record_Merge_Flag flags){return(app->buffer_history_merge_record_range(app, buffer, first_index, last_index, flags));}
|
||||
static bool32 buffer_history_clear_after_current_state(Application_Links *app, Buffer_Summary *buffer){return(app->buffer_history_clear_after_current_state(app, buffer));}
|
||||
static void global_history_edit_group_begin(Application_Links *app){(app->global_history_edit_group_begin(app));}
|
||||
static void global_history_edit_group_end(Application_Links *app){(app->global_history_edit_group_end(app));}
|
||||
static Face_Description get_face_description(Application_Links *app, Face_ID id){return(app->get_face_description(app, id));}
|
||||
static Face_ID get_face_id(Application_Links *app, Buffer_Summary *buffer){return(app->get_face_id(app, buffer));}
|
||||
static Face_ID try_create_new_face(Application_Links *app, Face_Description *description){return(app->try_create_new_face(app, description));}
|
||||
|
@ -783,7 +837,6 @@ static Face_ID get_default_font_for_view(Application_Links *app, View_ID view_id
|
|||
#else
|
||||
static bool32 global_set_setting(Application_Links *app, Global_Setting_ID setting, int32_t value){return(app->global_set_setting_(app, setting, value));}
|
||||
static bool32 global_set_mapping(Application_Links *app, void *data, int32_t size){return(app->global_set_mapping_(app, data, size));}
|
||||
static bool32 exec_command(Application_Links *app, Command_ID command_id){return(app->exec_command_(app, command_id));}
|
||||
static bool32 exec_system_command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer_id, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags){return(app->exec_system_command_(app, view, buffer_id, path, path_len, command, command_len, flags));}
|
||||
static void clipboard_post(Application_Links *app, int32_t clipboard_id, char *str, int32_t len){(app->clipboard_post_(app, clipboard_id, str, len));}
|
||||
static int32_t clipboard_count(Application_Links *app, int32_t clipboard_id){return(app->clipboard_count_(app, clipboard_id));}
|
||||
|
@ -796,7 +849,8 @@ static Buffer_Summary get_buffer(Application_Links *app, Buffer_ID buffer_id, Ac
|
|||
static Buffer_Summary get_buffer_by_name(Application_Links *app, char *name, int32_t len, Access_Flag access){return(app->get_buffer_by_name_(app, name, len, access));}
|
||||
static Buffer_Summary get_buffer_by_file_name(Application_Links *app, char *name, int32_t len, Access_Flag access){return(app->get_buffer_by_file_name_(app, name, len, access));}
|
||||
static bool32 buffer_read_range(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *out){return(app->buffer_read_range_(app, buffer, start, end, out));}
|
||||
static bool32 buffer_replace_range(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *str, int32_t len){return(app->buffer_replace_range_(app, buffer, start, end, str, len));}
|
||||
static bool32 buffer_replace_range(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t one_past_last, char *str, int32_t len){return(app->buffer_replace_range_(app, buffer, start, one_past_last, str, len));}
|
||||
static bool32 buffer_set_edit_handler(Application_Links *app, Buffer_ID buffer_id, Buffer_Edit_Handler *handler){return(app->buffer_set_edit_handler_(app, buffer_id, handler));}
|
||||
static bool32 buffer_compute_cursor(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out){return(app->buffer_compute_cursor_(app, buffer, seek, cursor_out));}
|
||||
static bool32 buffer_batch_edit(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type){return(app->buffer_batch_edit_(app, buffer, str, str_len, edits, edit_count, type));}
|
||||
static bool32 buffer_get_setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t *value_out){return(app->buffer_get_setting_(app, buffer, setting, value_out));}
|
||||
|
@ -878,6 +932,15 @@ static bool32 change_theme_by_index(Application_Links *app, int32_t index){retur
|
|||
static Face_ID get_largest_face_id(Application_Links *app){return(app->get_largest_face_id_(app));}
|
||||
static bool32 set_global_face(Application_Links *app, Face_ID id, bool32 apply_to_all_buffers){return(app->set_global_face_(app, id, apply_to_all_buffers));}
|
||||
static bool32 buffer_set_face(Application_Links *app, Buffer_Summary *buffer, Face_ID id){return(app->buffer_set_face_(app, buffer, id));}
|
||||
static History_Record_Index buffer_history_get_max_record_index(Application_Links *app, Buffer_Summary *buffer){return(app->buffer_history_get_max_record_index_(app, buffer));}
|
||||
static Record_Info buffer_history_get_record_info(Application_Links *app, Buffer_Summary *buffer, History_Record_Index index){return(app->buffer_history_get_record_info_(app, buffer, index));}
|
||||
static Record_Info buffer_history_get_group_sub_record(Application_Links *app, Buffer_Summary *buffer, History_Record_Index index, int32_t sub_index){return(app->buffer_history_get_group_sub_record_(app, buffer, index, sub_index));}
|
||||
static History_Record_Index buffer_history_get_current_state_index(Application_Links *app, Buffer_Summary *buffer){return(app->buffer_history_get_current_state_index_(app, buffer));}
|
||||
static bool32 buffer_history_set_current_state_index(Application_Links *app, Buffer_Summary *buffer, History_Record_Index index){return(app->buffer_history_set_current_state_index_(app, buffer, index));}
|
||||
static bool32 buffer_history_merge_record_range(Application_Links *app, Buffer_Summary *buffer, History_Record_Index first_index, History_Record_Index last_index, Record_Merge_Flag flags){return(app->buffer_history_merge_record_range_(app, buffer, first_index, last_index, flags));}
|
||||
static bool32 buffer_history_clear_after_current_state(Application_Links *app, Buffer_Summary *buffer){return(app->buffer_history_clear_after_current_state_(app, buffer));}
|
||||
static void global_history_edit_group_begin(Application_Links *app){(app->global_history_edit_group_begin_(app));}
|
||||
static void global_history_edit_group_end(Application_Links *app){(app->global_history_edit_group_end_(app));}
|
||||
static Face_Description get_face_description(Application_Links *app, Face_ID id){return(app->get_face_description_(app, id));}
|
||||
static Face_ID get_face_id(Application_Links *app, Buffer_Summary *buffer){return(app->get_face_id_(app, buffer));}
|
||||
static Face_ID try_create_new_face(Application_Links *app, Face_Description *description){return(app->try_create_new_face_(app, description));}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define command_id(c) (fcoder_metacmd_ID_##c)
|
||||
#define command_metadata(c) (&fcoder_metacmd_table[command_id(c)])
|
||||
#define command_metadata_by_id(id) (&fcoder_metacmd_table[id])
|
||||
#define command_one_past_last_id 220
|
||||
#define command_one_past_last_id 222
|
||||
#if defined(CUSTOM_COMMAND_SIG)
|
||||
#define PROC_LINKS(x,y) x
|
||||
#else
|
||||
|
@ -153,6 +153,7 @@ CUSTOM_COMMAND_SIG(query_replace);
|
|||
CUSTOM_COMMAND_SIG(query_replace_identifier);
|
||||
CUSTOM_COMMAND_SIG(query_replace_selection);
|
||||
CUSTOM_COMMAND_SIG(redo);
|
||||
CUSTOM_COMMAND_SIG(redo_this_buffer);
|
||||
CUSTOM_COMMAND_SIG(reload_themes);
|
||||
CUSTOM_COMMAND_SIG(remap_interactive);
|
||||
CUSTOM_COMMAND_SIG(rename_file_query);
|
||||
|
@ -218,6 +219,7 @@ CUSTOM_COMMAND_SIG(toggle_show_whitespace);
|
|||
CUSTOM_COMMAND_SIG(toggle_virtual_whitespace);
|
||||
CUSTOM_COMMAND_SIG(uncomment_line);
|
||||
CUSTOM_COMMAND_SIG(undo);
|
||||
CUSTOM_COMMAND_SIG(undo_this_buffer);
|
||||
CUSTOM_COMMAND_SIG(view_buffer_other_panel);
|
||||
CUSTOM_COMMAND_SIG(view_jump_list_with_lister);
|
||||
CUSTOM_COMMAND_SIG(word_complete);
|
||||
|
@ -240,227 +242,229 @@ char *source_name;
|
|||
int32_t source_name_len;
|
||||
int32_t line_number;
|
||||
};
|
||||
static Command_Metadata fcoder_metacmd_table[220] = {
|
||||
{ PROC_LINKS(allow_mouse, 0), "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "c:\\4ed\\code\\4coder_default_framework.cpp", 40, 240 },
|
||||
{ PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "c:\\4ed\\code\\4coder_auto_indent.cpp", 34, 722 },
|
||||
{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "c:\\4ed\\code\\4coder_auto_indent.cpp", 34, 733 },
|
||||
{ PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "c:\\4ed\\code\\4coder_auto_indent.cpp", 34, 712 },
|
||||
{ PROC_LINKS(backspace_char, 0), "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 69 },
|
||||
{ PROC_LINKS(backspace_word, 0), "backspace_word", 14, "Delete characters between the cursor position and the first alphanumeric boundary to the left.", 94, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1258 },
|
||||
{ PROC_LINKS(basic_change_active_panel, 0), "basic_change_active_panel", 25, "Change the currently active panel, moving to the panel with the next highest view_id. Will not skipe the build panel if it is open.", 132, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 476 },
|
||||
{ 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, "c:\\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, "c:\\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, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 118 },
|
||||
{ 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, "c:\\4ed\\code\\4coder_default_framework.cpp", 40, 144 },
|
||||
{ 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, "c:\\4ed\\code\\4coder_default_framework.cpp", 40, 154 },
|
||||
{ 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, "c:\\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, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 411 },
|
||||
{ PROC_LINKS(click_set_cursor, 0), "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 185 },
|
||||
{ PROC_LINKS(click_set_cursor_and_mark, 0), "click_set_cursor_and_mark", 25, "Sets the cursor position and mark to the mouse position.", 56, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 172 },
|
||||
{ PROC_LINKS(click_set_cursor_if_lbutton, 0), "click_set_cursor_if_lbutton", 27, "If the mouse left button is pressed, sets the cursor position to the mouse position.", 84, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 198 },
|
||||
{ PROC_LINKS(click_set_mark, 0), "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 213 },
|
||||
{ PROC_LINKS(close_all_code, 0), "close_all_code", 14, "Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.", 107, "c:\\4ed\\code\\4coder_project_commands.cpp", 39, 1060 },
|
||||
{ PROC_LINKS(close_build_panel, 0), "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "c:\\4ed\\code\\4coder_build_commands.cpp", 37, 203 },
|
||||
{ PROC_LINKS(close_panel, 0), "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 484 },
|
||||
{ PROC_LINKS(command_lister, 0), "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "c:\\4ed\\code\\4coder_lists.cpp", 28, 977 },
|
||||
{ PROC_LINKS(comment_line, 0), "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "c:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 135 },
|
||||
{ PROC_LINKS(comment_line_toggle, 0), "comment_line_toggle", 19, "Turns uncommented lines into commented lines and vice versa for comments starting with '//'.", 92, "c:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 159 },
|
||||
{ PROC_LINKS(copy, 0), "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "c:\\4ed\\code\\4coder_clipboard.cpp", 32, 26 },
|
||||
{ PROC_LINKS(cursor_mark_swap, 0), "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 96 },
|
||||
{ PROC_LINKS(cut, 0), "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "c:\\4ed\\code\\4coder_clipboard.cpp", 32, 35 },
|
||||
{ PROC_LINKS(decrease_face_size, 0), "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 574 },
|
||||
{ PROC_LINKS(decrease_line_wrap, 0), "decrease_line_wrap", 18, "Decrases the current buffer's width for line wrapping.", 54, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 551 },
|
||||
{ PROC_LINKS(delete_char, 0), "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 51 },
|
||||
{ PROC_LINKS(delete_current_scope, 0), "delete_current_scope", 20, "Deletes the braces surrounding the currently selected scope. Leaves the contents within the scope.", 99, "c:\\4ed\\code\\4coder_scope_commands.cpp", 37, 512 },
|
||||
{ PROC_LINKS(delete_file_query, 0), "delete_file_query", 17, "Deletes the file of the current buffer if 4coder has the appropriate access rights. Will ask the user for confirmation first.", 125, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1135 },
|
||||
{ PROC_LINKS(delete_line, 0), "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1387 },
|
||||
{ PROC_LINKS(delete_range, 0), "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 106 },
|
||||
{ PROC_LINKS(delete_word, 0), "delete_word", 11, "Delete characters between the cursor position and the first alphanumeric boundary to the right.", 95, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1264 },
|
||||
{ PROC_LINKS(duplicate_line, 0), "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1365 },
|
||||
{ PROC_LINKS(eol_dosify, 0), "eol_dosify", 10, "Puts the buffer in DOS line ending mode.", 40, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 621 },
|
||||
{ PROC_LINKS(eol_nixify, 0), "eol_nixify", 10, "Puts the buffer in NIX line ending mode.", 40, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 629 },
|
||||
{ PROC_LINKS(execute_any_cli, 0), "execute_any_cli", 15, "Queries for an output buffer name and system command, runs the system command as a CLI and prints the output to the specified buffer.", 133, "c:\\4ed\\code\\4coder_system_command.cpp", 37, 23 },
|
||||
{ PROC_LINKS(execute_previous_cli, 0), "execute_previous_cli", 20, "If the command execute_any_cli has already been used, this will execute a CLI reusing the most recent buffer name and command.", 126, "c:\\4ed\\code\\4coder_system_command.cpp", 37, 7 },
|
||||
{ PROC_LINKS(exit_4coder, 0), "exit_4coder", 11, "Attempts to close 4coder.", 25, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 637 },
|
||||
{ PROC_LINKS(goto_beginning_of_file, 0), "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1177 },
|
||||
{ PROC_LINKS(goto_end_of_file, 0), "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1185 },
|
||||
{ PROC_LINKS(goto_first_jump_direct, 0), "goto_first_jump_direct", 22, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "c:\\4ed\\code\\4coder_jump_direct.cpp", 34, 84 },
|
||||
{ PROC_LINKS(goto_first_jump_same_panel_sticky, 0), "goto_first_jump_same_panel_sticky", 33, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer and views the buffer in the panel where the jump list was.", 153, "c:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 550 },
|
||||
{ PROC_LINKS(goto_first_jump_sticky, 0), "goto_first_jump_sticky", 22, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "c:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 532 },
|
||||
{ PROC_LINKS(goto_jump_at_cursor_direct, 0), "goto_jump_at_cursor_direct", 26, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "c:\\4ed\\code\\4coder_jump_direct.cpp", 34, 8 },
|
||||
{ PROC_LINKS(goto_jump_at_cursor_same_panel_direct, 0), "goto_jump_at_cursor_same_panel_direct", 37, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list..", 168, "c:\\4ed\\code\\4coder_jump_direct.cpp", 34, 29 },
|
||||
{ PROC_LINKS(goto_jump_at_cursor_same_panel_sticky, 0), "goto_jump_at_cursor_same_panel_sticky", 37, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.", 167, "c:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 376 },
|
||||
{ PROC_LINKS(goto_jump_at_cursor_sticky, 0), "goto_jump_at_cursor_sticky", 26, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "c:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 348 },
|
||||
{ PROC_LINKS(goto_line, 0), "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 645 },
|
||||
{ PROC_LINKS(goto_next_jump_direct, 0), "goto_next_jump_direct", 21, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "c:\\4ed\\code\\4coder_jump_direct.cpp", 34, 48 },
|
||||
{ PROC_LINKS(goto_next_jump_no_skips_direct, 0), "goto_next_jump_no_skips_direct", 30, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "c:\\4ed\\code\\4coder_jump_direct.cpp", 34, 66 },
|
||||
{ PROC_LINKS(goto_next_jump_no_skips_sticky, 0), "goto_next_jump_no_skips_sticky", 30, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "c:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 501 },
|
||||
{ PROC_LINKS(goto_next_jump_sticky, 0), "goto_next_jump_sticky", 21, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "c:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 471 },
|
||||
{ PROC_LINKS(goto_prev_jump_direct, 0), "goto_prev_jump_direct", 21, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "c:\\4ed\\code\\4coder_jump_direct.cpp", 34, 57 },
|
||||
{ PROC_LINKS(goto_prev_jump_no_skips_direct, 0), "goto_prev_jump_no_skips_direct", 30, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "c:\\4ed\\code\\4coder_jump_direct.cpp", 34, 75 },
|
||||
{ PROC_LINKS(goto_prev_jump_no_skips_sticky, 0), "goto_prev_jump_no_skips_sticky", 30, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "c:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 517 },
|
||||
{ PROC_LINKS(goto_prev_jump_sticky, 0), "goto_prev_jump_sticky", 21, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "c:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 487 },
|
||||
{ PROC_LINKS(hide_filebar, 0), "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 514 },
|
||||
{ PROC_LINKS(hide_scrollbar, 0), "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 500 },
|
||||
{ PROC_LINKS(if0_off, 0), "if0_off", 7, "Surround the range between the cursor and mark with an '#if 0' and an '#endif'", 78, "c:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 79 },
|
||||
{ PROC_LINKS(increase_face_size, 0), "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 562 },
|
||||
{ PROC_LINKS(increase_line_wrap, 0), "increase_line_wrap", 18, "Increases the current buffer's width for line wrapping.", 55, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 540 },
|
||||
{ PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "c:\\4ed\\code\\4coder_lists.cpp", 28, 780 },
|
||||
{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "c:\\4ed\\code\\4coder_lists.cpp", 28, 890 },
|
||||
{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "c:\\4ed\\code\\4coder_lists.cpp", 28, 922 },
|
||||
{ PROC_LINKS(interactive_open_or_new, 0), "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "c:\\4ed\\code\\4coder_lists.cpp", 28, 852 },
|
||||
{ PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "c:\\4ed\\code\\4coder_lists.cpp", 28, 761 },
|
||||
{ PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1557 },
|
||||
{ PROC_LINKS(left_adjust_view, 0), "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 133 },
|
||||
{ PROC_LINKS(list_all_functions_all_buffers, 0), "list_all_functions_all_buffers", 30, "Creates a jump list of lines from all buffers that appear to define or declare functions.", 89, "c:\\4ed\\code\\4coder_function_list.cpp", 36, 332 },
|
||||
{ PROC_LINKS(list_all_functions_all_buffers_lister, 0), "list_all_functions_all_buffers_lister", 37, "Creates a lister of locations that look like function definitions and declarations all buffers.", 95, "c:\\4ed\\code\\4coder_function_list.cpp", 36, 338 },
|
||||
{ PROC_LINKS(list_all_functions_current_buffer, 0), "list_all_functions_current_buffer", 33, "Creates a jump list of lines of the current buffer that appear to define or declare functions.", 94, "c:\\4ed\\code\\4coder_function_list.cpp", 36, 309 },
|
||||
{ PROC_LINKS(list_all_functions_current_buffer_lister, 0), "list_all_functions_current_buffer_lister", 40, "Creates a lister of locations that look like function definitions and declarations in the buffer.", 97, "c:\\4ed\\code\\4coder_function_list.cpp", 36, 319 },
|
||||
{ PROC_LINKS(list_all_locations, 0), "list_all_locations", 18, "Queries the user for a string and lists all exact case-sensitive matches found in all open buffers.", 99, "c:\\4ed\\code\\4coder_search.cpp", 29, 769 },
|
||||
{ PROC_LINKS(list_all_locations_case_insensitive, 0), "list_all_locations_case_insensitive", 35, "Queries the user for a string and lists all exact case-insensitive matches found in all open buffers.", 101, "c:\\4ed\\code\\4coder_search.cpp", 29, 783 },
|
||||
{ PROC_LINKS(list_all_locations_of_identifier, 0), "list_all_locations_of_identifier", 32, "Reads a token or word under the cursor and lists all exact case-sensitive mathces in all open buffers.", 102, "c:\\4ed\\code\\4coder_search.cpp", 29, 797 },
|
||||
{ PROC_LINKS(list_all_locations_of_identifier_case_insensitive, 0), "list_all_locations_of_identifier_case_insensitive", 49, "Reads a token or word under the cursor and lists all exact case-insensitive mathces in all open buffers.", 104, "c:\\4ed\\code\\4coder_search.cpp", 29, 804 },
|
||||
{ PROC_LINKS(list_all_locations_of_selection, 0), "list_all_locations_of_selection", 31, "Reads the string in the selected range and lists all exact case-sensitive mathces in all open buffers.", 102, "c:\\4ed\\code\\4coder_search.cpp", 29, 811 },
|
||||
{ PROC_LINKS(list_all_locations_of_selection_case_insensitive, 0), "list_all_locations_of_selection_case_insensitive", 48, "Reads the string in the selected range and lists all exact case-insensitive mathces in all open buffers.", 104, "c:\\4ed\\code\\4coder_search.cpp", 29, 818 },
|
||||
{ PROC_LINKS(list_all_locations_of_type_definition, 0), "list_all_locations_of_type_definition", 37, "Queries user for string, lists all locations of strings that appear to define a type whose name matches the input string.", 121, "c:\\4ed\\code\\4coder_search.cpp", 29, 825 },
|
||||
{ PROC_LINKS(list_all_locations_of_type_definition_of_identifier, 0), "list_all_locations_of_type_definition_of_identifier", 51, "Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it.", 125, "c:\\4ed\\code\\4coder_search.cpp", 29, 836 },
|
||||
{ PROC_LINKS(list_all_substring_locations, 0), "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "c:\\4ed\\code\\4coder_search.cpp", 29, 776 },
|
||||
{ PROC_LINKS(list_all_substring_locations_case_insensitive, 0), "list_all_substring_locations_case_insensitive", 45, "Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.", 105, "c:\\4ed\\code\\4coder_search.cpp", 29, 790 },
|
||||
{ PROC_LINKS(lister__activate, 0), "lister__activate", 16, "A lister mode command that activates the list's action on the highlighted item.", 79, "c:\\4ed\\code\\4coder_lists.cpp", 28, 15 },
|
||||
{ PROC_LINKS(lister__backspace_text_field, 0), "lister__backspace_text_field", 28, "A lister mode command that dispatches to the lister's backspace text field handler.", 83, "c:\\4ed\\code\\4coder_lists.cpp", 28, 41 },
|
||||
{ PROC_LINKS(lister__backspace_text_field__default, 0), "lister__backspace_text_field__default", 37, "A lister mode command that backspaces one character from the text field.", 72, "c:\\4ed\\code\\4coder_lists.cpp", 28, 146 },
|
||||
{ PROC_LINKS(lister__backspace_text_field__file_path, 0), "lister__backspace_text_field__file_path", 39, "A lister mode command that backspaces one character from the text field of a file system list.", 94, "c:\\4ed\\code\\4coder_lists.cpp", 28, 218 },
|
||||
{ PROC_LINKS(lister__mouse_press, 0), "lister__mouse_press", 19, "A lister mode command that beings a click interaction with a list item under the mouse.", 87, "c:\\4ed\\code\\4coder_lists.cpp", 28, 86 },
|
||||
{ PROC_LINKS(lister__mouse_release, 0), "lister__mouse_release", 21, "A lister mode command that ends a click interaction with a list item under the mouse, possibly activating it.", 109, "c:\\4ed\\code\\4coder_lists.cpp", 28, 98 },
|
||||
{ PROC_LINKS(lister__move_down, 0), "lister__move_down", 17, "A lister mode command that dispatches to the lister's navigate down handler.", 76, "c:\\4ed\\code\\4coder_lists.cpp", 28, 61 },
|
||||
{ PROC_LINKS(lister__move_down__default, 0), "lister__move_down__default", 26, "A lister mode command that moves the highlighted item one down in the list.", 75, "c:\\4ed\\code\\4coder_lists.cpp", 28, 177 },
|
||||
{ PROC_LINKS(lister__move_up, 0), "lister__move_up", 15, "A lister mode command that dispatches to the lister's navigate up handler.", 74, "c:\\4ed\\code\\4coder_lists.cpp", 28, 51 },
|
||||
{ PROC_LINKS(lister__move_up__default, 0), "lister__move_up__default", 24, "A lister mode command that moves the highlighted item one up in the list.", 73, "c:\\4ed\\code\\4coder_lists.cpp", 28, 161 },
|
||||
{ PROC_LINKS(lister__quit, 0), "lister__quit", 12, "A lister mode command that quits the list without executing any actions.", 72, "c:\\4ed\\code\\4coder_lists.cpp", 28, 8 },
|
||||
{ PROC_LINKS(lister__repaint, 0), "lister__repaint", 15, "A lister mode command that updates the lists UI data.", 53, "c:\\4ed\\code\\4coder_lists.cpp", 28, 115 },
|
||||
{ PROC_LINKS(lister__wheel_scroll, 0), "lister__wheel_scroll", 20, "A lister mode command that scrolls the list in response to the mouse wheel.", 75, "c:\\4ed\\code\\4coder_lists.cpp", 28, 71 },
|
||||
{ PROC_LINKS(lister__write_character, 0), "lister__write_character", 23, "A lister mode command that dispatches to the lister's write character handler.", 78, "c:\\4ed\\code\\4coder_lists.cpp", 28, 31 },
|
||||
{ PROC_LINKS(lister__write_character__default, 0), "lister__write_character__default", 32, "A lister mode command that inserts a new character to the text field.", 69, "c:\\4ed\\code\\4coder_lists.cpp", 28, 126 },
|
||||
{ PROC_LINKS(lister__write_character__file_path, 0), "lister__write_character__file_path", 34, "A lister mode command that inserts a character into the text field of a file system list.", 89, "c:\\4ed\\code\\4coder_lists.cpp", 28, 193 },
|
||||
{ PROC_LINKS(lister__write_character__fixed_list, 0), "lister__write_character__fixed_list", 35, "A lister mode command that handles input for the fixed sure to kill list.", 73, "c:\\4ed\\code\\4coder_lists.cpp", 28, 253 },
|
||||
{ PROC_LINKS(load_project, 0), "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "c:\\4ed\\code\\4coder_project_commands.cpp", 39, 1083 },
|
||||
{ PROC_LINKS(make_directory_query, 0), "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1245 },
|
||||
{ PROC_LINKS(mouse_wheel_change_face_size, 0), "mouse_wheel_change_face_size", 28, "Reads the state of the mouse wheel and uses it to either increase or decrease the face size.", 92, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 586 },
|
||||
{ PROC_LINKS(mouse_wheel_scroll, 0), "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 226 },
|
||||
{ PROC_LINKS(move_down, 0), "move_down", 9, "Moves the cursor down one line.", 31, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 290 },
|
||||
{ PROC_LINKS(move_down_10, 0), "move_down_10", 12, "Moves the cursor down ten lines.", 32, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 302 },
|
||||
{ PROC_LINKS(move_down_textual, 0), "move_down_textual", 17, "Moves down to the next line of actual text, regardless of line wrapping.", 72, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 308 },
|
||||
{ PROC_LINKS(move_left, 0), "move_left", 9, "Moves the cursor one character to the left.", 43, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 339 },
|
||||
{ PROC_LINKS(move_line_down, 0), "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1342 },
|
||||
{ PROC_LINKS(move_line_up, 0), "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1278 },
|
||||
{ PROC_LINKS(move_right, 0), "move_right", 10, "Moves the cursor one character to the right.", 44, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 349 },
|
||||
{ PROC_LINKS(move_up, 0), "move_up", 7, "Moves the cursor up one line.", 29, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 284 },
|
||||
{ PROC_LINKS(move_up_10, 0), "move_up_10", 10, "Moves the cursor up ten lines.", 30, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 296 },
|
||||
{ PROC_LINKS(newline_or_goto_position_direct, 0), "newline_or_goto_position_direct", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "c:\\4ed\\code\\4coder_jump_direct.cpp", 34, 101 },
|
||||
{ PROC_LINKS(newline_or_goto_position_same_panel_direct, 0), "newline_or_goto_position_same_panel_direct", 42, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "c:\\4ed\\code\\4coder_jump_direct.cpp", 34, 116 },
|
||||
{ PROC_LINKS(newline_or_goto_position_same_panel_sticky, 0), "newline_or_goto_position_same_panel_sticky", 42, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "c:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 588 },
|
||||
{ PROC_LINKS(newline_or_goto_position_sticky, 0), "newline_or_goto_position_sticky", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "c:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 573 },
|
||||
{ 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, "c:\\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, "c:\\4ed\\code\\4coder_project_commands.cpp", 39, 1074 },
|
||||
{ PROC_LINKS(open_color_tweaker, 0), "open_color_tweaker", 18, "Opens the 4coder theme selector list.", 37, "c:\\4ed\\code\\4coder_lists.cpp", 28, 938 },
|
||||
{ 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, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1464 },
|
||||
{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1619 },
|
||||
{ PROC_LINKS(open_long_braces, 0), "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "c:\\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, "c:\\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, "c:\\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, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1500 },
|
||||
{ PROC_LINKS(open_panel_hsplit, 0), "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "c:\\4ed\\code\\4coder_default_framework.cpp", 40, 173 },
|
||||
{ PROC_LINKS(open_panel_vsplit, 0), "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "c:\\4ed\\code\\4coder_default_framework.cpp", 40, 164 },
|
||||
{ PROC_LINKS(page_down, 0), "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 328 },
|
||||
{ PROC_LINKS(page_up, 0), "page_up", 7, "Scrolls the view up one view height and moves the cursor up one view height.", 76, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 319 },
|
||||
{ PROC_LINKS(paste, 0), "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "c:\\4ed\\code\\4coder_clipboard.cpp", 32, 46 },
|
||||
{ PROC_LINKS(paste_and_indent, 0), "paste_and_indent", 16, "Paste from the top of clipboard and run auto-indent on the newly pasted text.", 77, "c:\\4ed\\code\\4coder_clipboard.cpp", 32, 134 },
|
||||
{ PROC_LINKS(paste_next, 0), "paste_next", 10, "If the previous command was paste or paste_next, replaces the paste range with the next text down on the clipboard, otherwise operates as the paste command.", 156, "c:\\4ed\\code\\4coder_clipboard.cpp", 32, 85 },
|
||||
{ PROC_LINKS(paste_next_and_indent, 0), "paste_next_and_indent", 21, "Paste the next item on the clipboard and run auto-indent on the newly pasted text.", 82, "c:\\4ed\\code\\4coder_clipboard.cpp", 32, 141 },
|
||||
{ PROC_LINKS(place_in_scope, 0), "place_in_scope", 14, "Wraps the code contained in the range between cursor and mark with a new curly brace scope.", 91, "c:\\4ed\\code\\4coder_scope_commands.cpp", 37, 506 },
|
||||
{ PROC_LINKS(project_command_lister, 0), "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "c:\\4ed\\code\\4coder_project_commands.cpp", 39, 1527 },
|
||||
{ PROC_LINKS(project_fkey_command, 0), "project_fkey_command", 20, "Run an 'fkey command' configured in a project.4coder file. Determines the index of the 'fkey command' by which function key or numeric key was pressed to trigger the command.", 175, "c:\\4ed\\code\\4coder_project_commands.cpp", 39, 1090 },
|
||||
{ PROC_LINKS(project_go_to_root_directory, 0), "project_go_to_root_directory", 28, "Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns.", 125, "c:\\4ed\\code\\4coder_project_commands.cpp", 39, 1113 },
|
||||
{ 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, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1019 },
|
||||
{ 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, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1043 },
|
||||
{ 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, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1061 },
|
||||
{ PROC_LINKS(redo, 0), "redo", 4, "Advances forewards through the undo history.", 44, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1588 },
|
||||
{ PROC_LINKS(reload_themes, 0), "reload_themes", 13, "Loads all the theme files in the theme folder, replacing duplicates with the new theme data.", 92, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1596 },
|
||||
{ PROC_LINKS(remap_interactive, 0), "remap_interactive", 17, "Switch to a named key binding map.", 34, "c:\\4ed\\code\\4coder_default_framework.cpp", 40, 290 },
|
||||
{ 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, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1201 },
|
||||
{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1572 },
|
||||
{ PROC_LINKS(replace_in_range, 0), "replace_in_range", 16, "Queries the user for two strings, and replaces all occurences of the first string in the range between the cursor and the mark with the second string.", 150, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 900 },
|
||||
{ PROC_LINKS(reverse_search, 0), "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 871 },
|
||||
{ PROC_LINKS(reverse_search_identifier, 0), "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 889 },
|
||||
{ PROC_LINKS(save, 0), "save", 4, "Saves the current buffer.", 25, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1564 },
|
||||
{ PROC_LINKS(save_all_dirty_buffers, 0), "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1105 },
|
||||
{ PROC_LINKS(save_to_query, 0), "save_to_query", 13, "Queries the user for a file name and saves the contents of the current buffer, altering the buffer's name too.", 110, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1161 },
|
||||
{ PROC_LINKS(scope_absorb_down, 0), "scope_absorb_down", 17, "If a scope is currently selected, and a statement or block statement is present below the current scope, the statement is moved into the scope.", 143, "c:\\4ed\\code\\4coder_scope_commands.cpp", 37, 747 },
|
||||
{ PROC_LINKS(search, 0), "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 864 },
|
||||
{ PROC_LINKS(search_identifier, 0), "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 878 },
|
||||
{ PROC_LINKS(seek_alphanumeric_left, 0), "seek_alphanumeric_left", 22, "Seek left for boundary between alphanumeric characters and non-alphanumeric characters.", 87, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1238 },
|
||||
{ PROC_LINKS(seek_alphanumeric_or_camel_left, 0), "seek_alphanumeric_or_camel_left", 31, "Seek left for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 106, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1250 },
|
||||
{ PROC_LINKS(seek_alphanumeric_or_camel_right, 0), "seek_alphanumeric_or_camel_right", 32, "Seek right for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 107, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1244 },
|
||||
{ PROC_LINKS(seek_alphanumeric_right, 0), "seek_alphanumeric_right", 23, "Seek right for boundary between alphanumeric characters and non-alphanumeric characters.", 88, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1232 },
|
||||
{ PROC_LINKS(seek_beginning_of_line, 0), "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1131 },
|
||||
{ PROC_LINKS(seek_beginning_of_textual_line, 0), "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1111 },
|
||||
{ PROC_LINKS(seek_end_of_line, 0), "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1143 },
|
||||
{ PROC_LINKS(seek_end_of_textual_line, 0), "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1121 },
|
||||
{ PROC_LINKS(seek_token_left, 0), "seek_token_left", 15, "Seek left for the next beginning of a token.", 44, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1214 },
|
||||
{ PROC_LINKS(seek_token_right, 0), "seek_token_right", 16, "Seek right for the next end of a token.", 39, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1208 },
|
||||
{ PROC_LINKS(seek_white_or_token_left, 0), "seek_white_or_token_left", 24, "Seek left for the next end of a token or boundary between whitespace and non-whitespace.", 88, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1226 },
|
||||
{ PROC_LINKS(seek_white_or_token_right, 0), "seek_white_or_token_right", 25, "Seek right for the next end of a token or boundary between whitespace and non-whitespace.", 89, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1220 },
|
||||
{ PROC_LINKS(seek_whitespace_down, 0), "seek_whitespace_down", 20, "Seeks the cursor down to the next blank line.", 45, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1101 },
|
||||
{ PROC_LINKS(seek_whitespace_down_end_line, 0), "seek_whitespace_down_end_line", 29, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1166 },
|
||||
{ PROC_LINKS(seek_whitespace_left, 0), "seek_whitespace_left", 20, "Seek left for the next boundary between whitespace and non-whitespace.", 70, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1202 },
|
||||
{ PROC_LINKS(seek_whitespace_right, 0), "seek_whitespace_right", 21, "Seek right for the next boundary between whitespace and non-whitespace.", 71, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1196 },
|
||||
{ PROC_LINKS(seek_whitespace_up, 0), "seek_whitespace_up", 18, "Seeks the cursor up to the next blank line.", 43, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1091 },
|
||||
{ PROC_LINKS(seek_whitespace_up_end_line, 0), "seek_whitespace_up_end_line", 27, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1155 },
|
||||
{ PROC_LINKS(select_all, 0), "select_all", 10, "Puts the cursor at the top of the file, and the mark at the bottom of the file.", 79, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 359 },
|
||||
{ PROC_LINKS(select_next_scope_absolute, 0), "select_next_scope_absolute", 26, "Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.", 102, "c:\\4ed\\code\\4coder_scope_commands.cpp", 37, 387 },
|
||||
{ PROC_LINKS(select_prev_scope_absolute, 0), "select_prev_scope_absolute", 26, "Finds the first scope started by '{' before the cursor and puts the cursor and mark on the '{' and '}'.", 103, "c:\\4ed\\code\\4coder_scope_commands.cpp", 37, 407 },
|
||||
{ PROC_LINKS(select_surrounding_scope, 0), "select_surrounding_scope", 24, "Finds the scope enclosed by '{' '}' surrounding the cursor and puts the cursor and mark on the '{' and '}'.", 107, "c:\\4ed\\code\\4coder_scope_commands.cpp", 37, 371 },
|
||||
{ PROC_LINKS(set_bindings_choose, 0), "set_bindings_choose", 19, "Remap keybindings using the 'choose' mapping rule.", 50, "c:\\4ed\\code\\4coder_remapping_commands.cpp", 41, 47 },
|
||||
{ PROC_LINKS(set_bindings_default, 0), "set_bindings_default", 20, "Remap keybindings using the 'default' mapping rule.", 51, "c:\\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, "c:\\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, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 88 },
|
||||
{ PROC_LINKS(set_mode_to_notepad_like, 0), "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "c:\\4ed\\code\\4coder_default_framework.cpp", 40, 258 },
|
||||
{ PROC_LINKS(set_mode_to_original, 0), "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "c:\\4ed\\code\\4coder_default_framework.cpp", 40, 252 },
|
||||
{ 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, "c:\\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, "c:\\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, "c:\\4ed\\code\\4coder_project_commands.cpp", 39, 1504 },
|
||||
{ PROC_LINKS(setup_new_project, 0), "setup_new_project", 17, "Queries the user for several configuration options and initializes a new 4coder project with build scripts for every OS.", 120, "c:\\4ed\\code\\4coder_project_commands.cpp", 39, 1491 },
|
||||
{ PROC_LINKS(show_filebar, 0), "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 507 },
|
||||
{ PROC_LINKS(show_scrollbar, 0), "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 493 },
|
||||
{ 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, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1270 },
|
||||
{ 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, "c:\\4ed\\code\\4coder_seek.cpp", 27, 1276 },
|
||||
{ PROC_LINKS(snippet_lister, 0), "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "c:\\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, "c:\\4ed\\code\\4coder_default_framework.cpp", 40, 234 },
|
||||
{ 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, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1524 },
|
||||
{ PROC_LINKS(to_lowercase, 0), "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 391 },
|
||||
{ PROC_LINKS(to_uppercase, 0), "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 371 },
|
||||
{ PROC_LINKS(toggle_filebar, 0), "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 521 },
|
||||
{ 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, "c:\\4ed\\code\\4coder_default_framework.cpp", 40, 282 },
|
||||
{ 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, "c:\\4ed\\code\\4coder_default_framework.cpp", 40, 270 },
|
||||
{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "c:\\4ed\\code\\4coder_default_framework.cpp", 40, 264 },
|
||||
{ PROC_LINKS(toggle_line_wrap, 0), "toggle_line_wrap", 16, "Toggles the current buffer's line wrapping status.", 50, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 530 },
|
||||
{ PROC_LINKS(toggle_mouse, 0), "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "c:\\4ed\\code\\4coder_default_framework.cpp", 40, 246 },
|
||||
{ PROC_LINKS(toggle_paren_matching_helper, 0), "toggle_paren_matching_helper", 28, "In code files matching parentheses pairs are colored with distinguishing colors.", 80, "c:\\4ed\\code\\4coder_default_framework.cpp", 40, 276 },
|
||||
{ PROC_LINKS(toggle_show_whitespace, 0), "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 614 },
|
||||
{ PROC_LINKS(toggle_virtual_whitespace, 0), "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 603 },
|
||||
{ PROC_LINKS(uncomment_line, 0), "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "c:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 147 },
|
||||
{ PROC_LINKS(undo, 0), "undo", 4, "Advances backwards through the undo history.", 44, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1582 },
|
||||
{ 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, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 1514 },
|
||||
{ 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, "c:\\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, "c:\\4ed\\code\\4coder_search.cpp", 29, 856 },
|
||||
{ PROC_LINKS(write_and_auto_tab, 0), "write_and_auto_tab", 18, "Inserts a character and auto-indents the line on which the cursor sits.", 71, "c:\\4ed\\code\\4coder_auto_indent.cpp", 34, 745 },
|
||||
{ PROC_LINKS(write_block, 0), "write_block", 11, "At the cursor, insert a block comment.", 38, "c:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 103 },
|
||||
{ PROC_LINKS(write_character, 0), "write_character", 15, "Inserts whatever character was used to trigger this command.", 60, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 35 },
|
||||
{ PROC_LINKS(write_hack, 0), "write_hack", 10, "At the cursor, insert a '// HACK' comment, includes user name if it was specified in config.4coder.", 99, "c:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 91 },
|
||||
{ PROC_LINKS(write_note, 0), "write_note", 10, "At the cursor, insert a '// NOTE' comment, includes user name if it was specified in config.4coder.", 99, "c:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 97 },
|
||||
{ PROC_LINKS(write_todo, 0), "write_todo", 10, "At the cursor, insert a '// TODO' comment, includes user name if it was specified in config.4coder.", 99, "c:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 85 },
|
||||
{ PROC_LINKS(write_underscore, 0), "write_underscore", 16, "Inserts an underscore.", 22, "c:\\4ed\\code\\4coder_base_commands.cpp", 36, 44 },
|
||||
{ PROC_LINKS(write_zero_struct, 0), "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "c:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 109 },
|
||||
static Command_Metadata fcoder_metacmd_table[222] = {
|
||||
{ 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, 242 },
|
||||
{ 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, 721 },
|
||||
{ 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, 732 },
|
||||
{ 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, 711 },
|
||||
{ PROC_LINKS(backspace_char, 0), "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 97 },
|
||||
{ PROC_LINKS(backspace_word, 0), "backspace_word", 14, "Delete characters between the cursor position and the first alphanumeric boundary to the left.", 94, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1258 },
|
||||
{ PROC_LINKS(basic_change_active_panel, 0), "basic_change_active_panel", 25, "Change the currently active panel, moving to the panel with the next highest view_id. Will not skipe the build panel if it is open.", 132, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 504 },
|
||||
{ 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, 146 },
|
||||
{ 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, 144 },
|
||||
{ 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, 154 },
|
||||
{ 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, 439 },
|
||||
{ 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, 213 },
|
||||
{ PROC_LINKS(click_set_cursor_and_mark, 0), "click_set_cursor_and_mark", 25, "Sets the cursor position and mark to the mouse position.", 56, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 200 },
|
||||
{ PROC_LINKS(click_set_cursor_if_lbutton, 0), "click_set_cursor_if_lbutton", 27, "If the mouse left button is pressed, sets the cursor position to the mouse position.", 84, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 226 },
|
||||
{ PROC_LINKS(click_set_mark, 0), "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 241 },
|
||||
{ PROC_LINKS(close_all_code, 0), "close_all_code", 14, "Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.", 107, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1060 },
|
||||
{ PROC_LINKS(close_build_panel, 0), "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 203 },
|
||||
{ PROC_LINKS(close_panel, 0), "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 512 },
|
||||
{ PROC_LINKS(command_lister, 0), "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\4coder_lists.cpp", 28, 977 },
|
||||
{ PROC_LINKS(comment_line, 0), "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 135 },
|
||||
{ PROC_LINKS(comment_line_toggle, 0), "comment_line_toggle", 19, "Turns uncommented lines into commented lines and vice versa for comments starting with '//'.", 92, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 159 },
|
||||
{ PROC_LINKS(copy, 0), "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "w:\\4ed\\code\\4coder_clipboard.cpp", 32, 26 },
|
||||
{ PROC_LINKS(cursor_mark_swap, 0), "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 124 },
|
||||
{ PROC_LINKS(cut, 0), "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "w:\\4ed\\code\\4coder_clipboard.cpp", 32, 35 },
|
||||
{ PROC_LINKS(decrease_face_size, 0), "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 602 },
|
||||
{ PROC_LINKS(decrease_line_wrap, 0), "decrease_line_wrap", 18, "Decrases the current buffer's width for line wrapping.", 54, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 579 },
|
||||
{ PROC_LINKS(delete_char, 0), "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 79 },
|
||||
{ PROC_LINKS(delete_current_scope, 0), "delete_current_scope", 20, "Deletes the braces surrounding the currently selected scope. Leaves the contents within the scope.", 99, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 512 },
|
||||
{ PROC_LINKS(delete_file_query, 0), "delete_file_query", 17, "Deletes the file of the current buffer if 4coder has the appropriate access rights. Will ask the user for confirmation first.", 125, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1165 },
|
||||
{ PROC_LINKS(delete_line, 0), "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1417 },
|
||||
{ PROC_LINKS(delete_range, 0), "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 134 },
|
||||
{ PROC_LINKS(delete_word, 0), "delete_word", 11, "Delete characters between the cursor position and the first alphanumeric boundary to the right.", 95, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1264 },
|
||||
{ PROC_LINKS(duplicate_line, 0), "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1395 },
|
||||
{ PROC_LINKS(eol_dosify, 0), "eol_dosify", 10, "Puts the buffer in DOS line ending mode.", 40, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 649 },
|
||||
{ PROC_LINKS(eol_nixify, 0), "eol_nixify", 10, "Puts the buffer in NIX line ending mode.", 40, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 657 },
|
||||
{ PROC_LINKS(execute_any_cli, 0), "execute_any_cli", 15, "Queries for an output buffer name and system command, runs the system command as a CLI and prints the output to the specified buffer.", 133, "w:\\4ed\\code\\4coder_system_command.cpp", 37, 23 },
|
||||
{ PROC_LINKS(execute_previous_cli, 0), "execute_previous_cli", 20, "If the command execute_any_cli has already been used, this will execute a CLI reusing the most recent buffer name and command.", 126, "w:\\4ed\\code\\4coder_system_command.cpp", 37, 7 },
|
||||
{ PROC_LINKS(exit_4coder, 0), "exit_4coder", 11, "Attempts to close 4coder.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 665 },
|
||||
{ PROC_LINKS(goto_beginning_of_file, 0), "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1177 },
|
||||
{ PROC_LINKS(goto_end_of_file, 0), "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1185 },
|
||||
{ PROC_LINKS(goto_first_jump_direct, 0), "goto_first_jump_direct", 22, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "w:\\4ed\\code\\4coder_jump_direct.cpp", 34, 84 },
|
||||
{ PROC_LINKS(goto_first_jump_same_panel_sticky, 0), "goto_first_jump_same_panel_sticky", 33, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer and views the buffer in the panel where the jump list was.", 153, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 551 },
|
||||
{ PROC_LINKS(goto_first_jump_sticky, 0), "goto_first_jump_sticky", 22, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 533 },
|
||||
{ PROC_LINKS(goto_jump_at_cursor_direct, 0), "goto_jump_at_cursor_direct", 26, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "w:\\4ed\\code\\4coder_jump_direct.cpp", 34, 8 },
|
||||
{ PROC_LINKS(goto_jump_at_cursor_same_panel_direct, 0), "goto_jump_at_cursor_same_panel_direct", 37, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list..", 168, "w:\\4ed\\code\\4coder_jump_direct.cpp", 34, 29 },
|
||||
{ PROC_LINKS(goto_jump_at_cursor_same_panel_sticky, 0), "goto_jump_at_cursor_same_panel_sticky", 37, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.", 167, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 377 },
|
||||
{ PROC_LINKS(goto_jump_at_cursor_sticky, 0), "goto_jump_at_cursor_sticky", 26, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 349 },
|
||||
{ PROC_LINKS(goto_line, 0), "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 673 },
|
||||
{ PROC_LINKS(goto_next_jump_direct, 0), "goto_next_jump_direct", 21, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "w:\\4ed\\code\\4coder_jump_direct.cpp", 34, 48 },
|
||||
{ PROC_LINKS(goto_next_jump_no_skips_direct, 0), "goto_next_jump_no_skips_direct", 30, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "w:\\4ed\\code\\4coder_jump_direct.cpp", 34, 66 },
|
||||
{ PROC_LINKS(goto_next_jump_no_skips_sticky, 0), "goto_next_jump_no_skips_sticky", 30, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 502 },
|
||||
{ PROC_LINKS(goto_next_jump_sticky, 0), "goto_next_jump_sticky", 21, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 472 },
|
||||
{ PROC_LINKS(goto_prev_jump_direct, 0), "goto_prev_jump_direct", 21, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "w:\\4ed\\code\\4coder_jump_direct.cpp", 34, 57 },
|
||||
{ PROC_LINKS(goto_prev_jump_no_skips_direct, 0), "goto_prev_jump_no_skips_direct", 30, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "w:\\4ed\\code\\4coder_jump_direct.cpp", 34, 75 },
|
||||
{ PROC_LINKS(goto_prev_jump_no_skips_sticky, 0), "goto_prev_jump_no_skips_sticky", 30, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 518 },
|
||||
{ PROC_LINKS(goto_prev_jump_sticky, 0), "goto_prev_jump_sticky", 21, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 488 },
|
||||
{ PROC_LINKS(hide_filebar, 0), "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 542 },
|
||||
{ PROC_LINKS(hide_scrollbar, 0), "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 528 },
|
||||
{ PROC_LINKS(if0_off, 0), "if0_off", 7, "Surround the range between the cursor and mark with an '#if 0' and an '#endif'", 78, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 79 },
|
||||
{ PROC_LINKS(increase_face_size, 0), "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 590 },
|
||||
{ PROC_LINKS(increase_line_wrap, 0), "increase_line_wrap", 18, "Increases the current buffer's width for line wrapping.", 55, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 568 },
|
||||
{ PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "w:\\4ed\\code\\4coder_lists.cpp", 28, 780 },
|
||||
{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\4coder_lists.cpp", 28, 890 },
|
||||
{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\4coder_lists.cpp", 28, 922 },
|
||||
{ PROC_LINKS(interactive_open_or_new, 0), "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "w:\\4ed\\code\\4coder_lists.cpp", 28, 852 },
|
||||
{ PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "w:\\4ed\\code\\4coder_lists.cpp", 28, 761 },
|
||||
{ PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1587 },
|
||||
{ PROC_LINKS(left_adjust_view, 0), "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 161 },
|
||||
{ PROC_LINKS(list_all_functions_all_buffers, 0), "list_all_functions_all_buffers", 30, "Creates a jump list of lines from all buffers that appear to define or declare functions.", 89, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 332 },
|
||||
{ PROC_LINKS(list_all_functions_all_buffers_lister, 0), "list_all_functions_all_buffers_lister", 37, "Creates a lister of locations that look like function definitions and declarations all buffers.", 95, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 338 },
|
||||
{ PROC_LINKS(list_all_functions_current_buffer, 0), "list_all_functions_current_buffer", 33, "Creates a jump list of lines of the current buffer that appear to define or declare functions.", 94, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 309 },
|
||||
{ PROC_LINKS(list_all_functions_current_buffer_lister, 0), "list_all_functions_current_buffer_lister", 40, "Creates a lister of locations that look like function definitions and declarations in the buffer.", 97, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 319 },
|
||||
{ PROC_LINKS(list_all_locations, 0), "list_all_locations", 18, "Queries the user for a string and lists all exact case-sensitive matches found in all open buffers.", 99, "w:\\4ed\\code\\4coder_search.cpp", 29, 780 },
|
||||
{ PROC_LINKS(list_all_locations_case_insensitive, 0), "list_all_locations_case_insensitive", 35, "Queries the user for a string and lists all exact case-insensitive matches found in all open buffers.", 101, "w:\\4ed\\code\\4coder_search.cpp", 29, 794 },
|
||||
{ PROC_LINKS(list_all_locations_of_identifier, 0), "list_all_locations_of_identifier", 32, "Reads a token or word under the cursor and lists all exact case-sensitive mathces in all open buffers.", 102, "w:\\4ed\\code\\4coder_search.cpp", 29, 808 },
|
||||
{ PROC_LINKS(list_all_locations_of_identifier_case_insensitive, 0), "list_all_locations_of_identifier_case_insensitive", 49, "Reads a token or word under the cursor and lists all exact case-insensitive mathces in all open buffers.", 104, "w:\\4ed\\code\\4coder_search.cpp", 29, 815 },
|
||||
{ PROC_LINKS(list_all_locations_of_selection, 0), "list_all_locations_of_selection", 31, "Reads the string in the selected range and lists all exact case-sensitive mathces in all open buffers.", 102, "w:\\4ed\\code\\4coder_search.cpp", 29, 822 },
|
||||
{ PROC_LINKS(list_all_locations_of_selection_case_insensitive, 0), "list_all_locations_of_selection_case_insensitive", 48, "Reads the string in the selected range and lists all exact case-insensitive mathces in all open buffers.", 104, "w:\\4ed\\code\\4coder_search.cpp", 29, 829 },
|
||||
{ PROC_LINKS(list_all_locations_of_type_definition, 0), "list_all_locations_of_type_definition", 37, "Queries user for string, lists all locations of strings that appear to define a type whose name matches the input string.", 121, "w:\\4ed\\code\\4coder_search.cpp", 29, 836 },
|
||||
{ PROC_LINKS(list_all_locations_of_type_definition_of_identifier, 0), "list_all_locations_of_type_definition_of_identifier", 51, "Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it.", 125, "w:\\4ed\\code\\4coder_search.cpp", 29, 847 },
|
||||
{ PROC_LINKS(list_all_substring_locations, 0), "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "w:\\4ed\\code\\4coder_search.cpp", 29, 787 },
|
||||
{ PROC_LINKS(list_all_substring_locations_case_insensitive, 0), "list_all_substring_locations_case_insensitive", 45, "Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.", 105, "w:\\4ed\\code\\4coder_search.cpp", 29, 801 },
|
||||
{ PROC_LINKS(lister__activate, 0), "lister__activate", 16, "A lister mode command that activates the list's action on the highlighted item.", 79, "w:\\4ed\\code\\4coder_lists.cpp", 28, 15 },
|
||||
{ PROC_LINKS(lister__backspace_text_field, 0), "lister__backspace_text_field", 28, "A lister mode command that dispatches to the lister's backspace text field handler.", 83, "w:\\4ed\\code\\4coder_lists.cpp", 28, 41 },
|
||||
{ PROC_LINKS(lister__backspace_text_field__default, 0), "lister__backspace_text_field__default", 37, "A lister mode command that backspaces one character from the text field.", 72, "w:\\4ed\\code\\4coder_lists.cpp", 28, 146 },
|
||||
{ PROC_LINKS(lister__backspace_text_field__file_path, 0), "lister__backspace_text_field__file_path", 39, "A lister mode command that backspaces one character from the text field of a file system list.", 94, "w:\\4ed\\code\\4coder_lists.cpp", 28, 218 },
|
||||
{ PROC_LINKS(lister__mouse_press, 0), "lister__mouse_press", 19, "A lister mode command that beings a click interaction with a list item under the mouse.", 87, "w:\\4ed\\code\\4coder_lists.cpp", 28, 86 },
|
||||
{ PROC_LINKS(lister__mouse_release, 0), "lister__mouse_release", 21, "A lister mode command that ends a click interaction with a list item under the mouse, possibly activating it.", 109, "w:\\4ed\\code\\4coder_lists.cpp", 28, 98 },
|
||||
{ PROC_LINKS(lister__move_down, 0), "lister__move_down", 17, "A lister mode command that dispatches to the lister's navigate down handler.", 76, "w:\\4ed\\code\\4coder_lists.cpp", 28, 61 },
|
||||
{ PROC_LINKS(lister__move_down__default, 0), "lister__move_down__default", 26, "A lister mode command that moves the highlighted item one down in the list.", 75, "w:\\4ed\\code\\4coder_lists.cpp", 28, 177 },
|
||||
{ PROC_LINKS(lister__move_up, 0), "lister__move_up", 15, "A lister mode command that dispatches to the lister's navigate up handler.", 74, "w:\\4ed\\code\\4coder_lists.cpp", 28, 51 },
|
||||
{ PROC_LINKS(lister__move_up__default, 0), "lister__move_up__default", 24, "A lister mode command that moves the highlighted item one up in the list.", 73, "w:\\4ed\\code\\4coder_lists.cpp", 28, 161 },
|
||||
{ PROC_LINKS(lister__quit, 0), "lister__quit", 12, "A lister mode command that quits the list without executing any actions.", 72, "w:\\4ed\\code\\4coder_lists.cpp", 28, 8 },
|
||||
{ PROC_LINKS(lister__repaint, 0), "lister__repaint", 15, "A lister mode command that updates the lists UI data.", 53, "w:\\4ed\\code\\4coder_lists.cpp", 28, 115 },
|
||||
{ PROC_LINKS(lister__wheel_scroll, 0), "lister__wheel_scroll", 20, "A lister mode command that scrolls the list in response to the mouse wheel.", 75, "w:\\4ed\\code\\4coder_lists.cpp", 28, 71 },
|
||||
{ PROC_LINKS(lister__write_character, 0), "lister__write_character", 23, "A lister mode command that dispatches to the lister's write character handler.", 78, "w:\\4ed\\code\\4coder_lists.cpp", 28, 31 },
|
||||
{ PROC_LINKS(lister__write_character__default, 0), "lister__write_character__default", 32, "A lister mode command that inserts a new character to the text field.", 69, "w:\\4ed\\code\\4coder_lists.cpp", 28, 126 },
|
||||
{ PROC_LINKS(lister__write_character__file_path, 0), "lister__write_character__file_path", 34, "A lister mode command that inserts a character into the text field of a file system list.", 89, "w:\\4ed\\code\\4coder_lists.cpp", 28, 193 },
|
||||
{ PROC_LINKS(lister__write_character__fixed_list, 0), "lister__write_character__fixed_list", 35, "A lister mode command that handles input for the fixed sure to kill list.", 73, "w:\\4ed\\code\\4coder_lists.cpp", 28, 253 },
|
||||
{ PROC_LINKS(load_project, 0), "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1083 },
|
||||
{ PROC_LINKS(make_directory_query, 0), "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1275 },
|
||||
{ PROC_LINKS(mouse_wheel_change_face_size, 0), "mouse_wheel_change_face_size", 28, "Reads the state of the mouse wheel and uses it to either increase or decrease the face size.", 92, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 614 },
|
||||
{ PROC_LINKS(mouse_wheel_scroll, 0), "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 254 },
|
||||
{ PROC_LINKS(move_down, 0), "move_down", 9, "Moves the cursor down one line.", 31, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 318 },
|
||||
{ PROC_LINKS(move_down_10, 0), "move_down_10", 12, "Moves the cursor down ten lines.", 32, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 330 },
|
||||
{ PROC_LINKS(move_down_textual, 0), "move_down_textual", 17, "Moves down to the next line of actual text, regardless of line wrapping.", 72, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 336 },
|
||||
{ PROC_LINKS(move_left, 0), "move_left", 9, "Moves the cursor one character to the left.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 367 },
|
||||
{ PROC_LINKS(move_line_down, 0), "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1372 },
|
||||
{ PROC_LINKS(move_line_up, 0), "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1308 },
|
||||
{ PROC_LINKS(move_right, 0), "move_right", 10, "Moves the cursor one character to the right.", 44, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 377 },
|
||||
{ PROC_LINKS(move_up, 0), "move_up", 7, "Moves the cursor up one line.", 29, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 312 },
|
||||
{ PROC_LINKS(move_up_10, 0), "move_up_10", 10, "Moves the cursor up ten lines.", 30, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 324 },
|
||||
{ PROC_LINKS(newline_or_goto_position_direct, 0), "newline_or_goto_position_direct", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "w:\\4ed\\code\\4coder_jump_direct.cpp", 34, 101 },
|
||||
{ PROC_LINKS(newline_or_goto_position_same_panel_direct, 0), "newline_or_goto_position_same_panel_direct", 42, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "w:\\4ed\\code\\4coder_jump_direct.cpp", 34, 116 },
|
||||
{ PROC_LINKS(newline_or_goto_position_same_panel_sticky, 0), "newline_or_goto_position_same_panel_sticky", 42, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 588 },
|
||||
{ PROC_LINKS(newline_or_goto_position_sticky, 0), "newline_or_goto_position_sticky", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 574 },
|
||||
{ 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_color_tweaker, 0), "open_color_tweaker", 18, "Opens the 4coder theme selector list.", 37, "w:\\4ed\\code\\4coder_lists.cpp", 28, 938 },
|
||||
{ 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, 1494 },
|
||||
{ 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, 1798 },
|
||||
{ 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, 1530 },
|
||||
{ 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, 173 },
|
||||
{ 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, 164 },
|
||||
{ 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, 356 },
|
||||
{ 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, 347 },
|
||||
{ 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 },
|
||||
{ PROC_LINKS(paste_and_indent, 0), "paste_and_indent", 16, "Paste from the top of clipboard and run auto-indent on the newly pasted text.", 77, "w:\\4ed\\code\\4coder_clipboard.cpp", 32, 134 },
|
||||
{ PROC_LINKS(paste_next, 0), "paste_next", 10, "If the previous command was paste or paste_next, replaces the paste range with the next text down on the clipboard, otherwise operates as the paste command.", 156, "w:\\4ed\\code\\4coder_clipboard.cpp", 32, 85 },
|
||||
{ PROC_LINKS(paste_next_and_indent, 0), "paste_next_and_indent", 21, "Paste the next item on the clipboard and run auto-indent on the newly pasted text.", 82, "w:\\4ed\\code\\4coder_clipboard.cpp", 32, 141 },
|
||||
{ PROC_LINKS(place_in_scope, 0), "place_in_scope", 14, "Wraps the code contained in the range between cursor and mark with a new curly brace scope.", 91, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 506 },
|
||||
{ PROC_LINKS(project_command_lister, 0), "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1527 },
|
||||
{ PROC_LINKS(project_fkey_command, 0), "project_fkey_command", 20, "Run an 'fkey command' configured in a project.4coder file. Determines the index of the 'fkey command' by which function key or numeric key was pressed to trigger the command.", 175, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1090 },
|
||||
{ PROC_LINKS(project_go_to_root_directory, 0), "project_go_to_root_directory", 28, "Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns.", 125, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1113 },
|
||||
{ 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, 1049 },
|
||||
{ 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, 1073 },
|
||||
{ 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, 1091 },
|
||||
{ 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, 1703 },
|
||||
{ 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, 1623 },
|
||||
{ PROC_LINKS(reload_themes, 0), "reload_themes", 13, "Loads all the theme files in the theme folder, replacing duplicates with the new theme data.", 92, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1775 },
|
||||
{ PROC_LINKS(remap_interactive, 0), "remap_interactive", 17, "Switch to a named key binding map.", 34, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 292 },
|
||||
{ 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, 1231 },
|
||||
{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1602 },
|
||||
{ PROC_LINKS(replace_in_range, 0), "replace_in_range", 16, "Queries the user for two strings, and replaces all occurences of the first string in the range between the cursor and the mark with the second string.", 150, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 928 },
|
||||
{ PROC_LINKS(reverse_search, 0), "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 899 },
|
||||
{ PROC_LINKS(reverse_search_identifier, 0), "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 917 },
|
||||
{ PROC_LINKS(save, 0), "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1594 },
|
||||
{ PROC_LINKS(save_all_dirty_buffers, 0), "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1135 },
|
||||
{ PROC_LINKS(save_to_query, 0), "save_to_query", 13, "Queries the user for a file name and saves the contents of the current buffer, altering the buffer's name too.", 110, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1191 },
|
||||
{ PROC_LINKS(scope_absorb_down, 0), "scope_absorb_down", 17, "If a scope is currently selected, and a statement or block statement is present below the current scope, the statement is moved into the scope.", 143, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 747 },
|
||||
{ PROC_LINKS(search, 0), "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 892 },
|
||||
{ PROC_LINKS(search_identifier, 0), "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 906 },
|
||||
{ PROC_LINKS(seek_alphanumeric_left, 0), "seek_alphanumeric_left", 22, "Seek left for boundary between alphanumeric characters and non-alphanumeric characters.", 87, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1238 },
|
||||
{ PROC_LINKS(seek_alphanumeric_or_camel_left, 0), "seek_alphanumeric_or_camel_left", 31, "Seek left for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 106, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1250 },
|
||||
{ PROC_LINKS(seek_alphanumeric_or_camel_right, 0), "seek_alphanumeric_or_camel_right", 32, "Seek right for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 107, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1244 },
|
||||
{ PROC_LINKS(seek_alphanumeric_right, 0), "seek_alphanumeric_right", 23, "Seek right for boundary between alphanumeric characters and non-alphanumeric characters.", 88, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1232 },
|
||||
{ PROC_LINKS(seek_beginning_of_line, 0), "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1131 },
|
||||
{ PROC_LINKS(seek_beginning_of_textual_line, 0), "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1111 },
|
||||
{ PROC_LINKS(seek_end_of_line, 0), "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1143 },
|
||||
{ PROC_LINKS(seek_end_of_textual_line, 0), "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1121 },
|
||||
{ PROC_LINKS(seek_token_left, 0), "seek_token_left", 15, "Seek left for the next beginning of a token.", 44, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1214 },
|
||||
{ PROC_LINKS(seek_token_right, 0), "seek_token_right", 16, "Seek right for the next end of a token.", 39, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1208 },
|
||||
{ PROC_LINKS(seek_white_or_token_left, 0), "seek_white_or_token_left", 24, "Seek left for the next end of a token or boundary between whitespace and non-whitespace.", 88, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1226 },
|
||||
{ PROC_LINKS(seek_white_or_token_right, 0), "seek_white_or_token_right", 25, "Seek right for the next end of a token or boundary between whitespace and non-whitespace.", 89, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1220 },
|
||||
{ PROC_LINKS(seek_whitespace_down, 0), "seek_whitespace_down", 20, "Seeks the cursor down to the next blank line.", 45, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1101 },
|
||||
{ PROC_LINKS(seek_whitespace_down_end_line, 0), "seek_whitespace_down_end_line", 29, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1166 },
|
||||
{ PROC_LINKS(seek_whitespace_left, 0), "seek_whitespace_left", 20, "Seek left for the next boundary between whitespace and non-whitespace.", 70, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1202 },
|
||||
{ PROC_LINKS(seek_whitespace_right, 0), "seek_whitespace_right", 21, "Seek right for the next boundary between whitespace and non-whitespace.", 71, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1196 },
|
||||
{ PROC_LINKS(seek_whitespace_up, 0), "seek_whitespace_up", 18, "Seeks the cursor up to the next blank line.", 43, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1091 },
|
||||
{ PROC_LINKS(seek_whitespace_up_end_line, 0), "seek_whitespace_up_end_line", 27, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "w:\\4ed\\code\\4coder_seek.cpp", 27, 1155 },
|
||||
{ PROC_LINKS(select_all, 0), "select_all", 10, "Puts the cursor at the top of the file, and the mark at the bottom of the file.", 79, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 387 },
|
||||
{ PROC_LINKS(select_next_scope_absolute, 0), "select_next_scope_absolute", 26, "Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.", 102, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 387 },
|
||||
{ PROC_LINKS(select_prev_scope_absolute, 0), "select_prev_scope_absolute", 26, "Finds the first scope started by '{' before the cursor and puts the cursor and mark on the '{' and '}'.", 103, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 407 },
|
||||
{ PROC_LINKS(select_surrounding_scope, 0), "select_surrounding_scope", 24, "Finds the scope enclosed by '{' '}' surrounding the cursor and puts the cursor and mark on the '{' and '}'.", 107, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 371 },
|
||||
{ PROC_LINKS(set_bindings_choose, 0), "set_bindings_choose", 19, "Remap keybindings using the 'choose' mapping rule.", 50, "w:\\4ed\\code\\4coder_remapping_commands.cpp", 41, 47 },
|
||||
{ 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, 116 },
|
||||
{ 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, 260 },
|
||||
{ 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, 254 },
|
||||
{ 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 },
|
||||
{ PROC_LINKS(setup_new_project, 0), "setup_new_project", 17, "Queries the user for several configuration options and initializes a new 4coder project with build scripts for every OS.", 120, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1491 },
|
||||
{ PROC_LINKS(show_filebar, 0), "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 535 },
|
||||
{ PROC_LINKS(show_scrollbar, 0), "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 521 },
|
||||
{ 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, 1270 },
|
||||
{ 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, 1276 },
|
||||
{ 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, 236 },
|
||||
{ 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, 1554 },
|
||||
{ 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, 419 },
|
||||
{ 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, 399 },
|
||||
{ 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, 549 },
|
||||
{ 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, 284 },
|
||||
{ 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, 272 },
|
||||
{ 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, 266 },
|
||||
{ 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, 558 },
|
||||
{ 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, 248 },
|
||||
{ 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, 278 },
|
||||
{ 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, 642 },
|
||||
{ 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, 631 },
|
||||
{ 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, 1635 },
|
||||
{ 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, 1612 },
|
||||
{ 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, 1544 },
|
||||
{ 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, 867 },
|
||||
{ PROC_LINKS(write_and_auto_tab, 0), "write_and_auto_tab", 18, "Inserts a character and auto-indents the line on which the cursor sits.", 71, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 744 },
|
||||
{ PROC_LINKS(write_block, 0), "write_block", 11, "At the cursor, insert a block comment.", 38, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 103 },
|
||||
{ PROC_LINKS(write_character, 0), "write_character", 15, "Inserts whatever character was used to trigger this command.", 60, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 63 },
|
||||
{ PROC_LINKS(write_hack, 0), "write_hack", 10, "At the cursor, insert a '// HACK' comment, includes user name if it was specified in config.4coder.", 99, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 91 },
|
||||
{ PROC_LINKS(write_note, 0), "write_note", 10, "At the cursor, insert a '// NOTE' comment, includes user name if it was specified in config.4coder.", 99, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 97 },
|
||||
{ PROC_LINKS(write_todo, 0), "write_todo", 10, "At the cursor, insert a '// TODO' comment, includes user name if it was specified in config.4coder.", 99, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 85 },
|
||||
{ PROC_LINKS(write_underscore, 0), "write_underscore", 16, "Inserts an underscore.", 22, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 72 },
|
||||
{ PROC_LINKS(write_zero_struct, 0), "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 109 },
|
||||
};
|
||||
static int32_t fcoder_metacmd_ID_allow_mouse = 0;
|
||||
static int32_t fcoder_metacmd_ID_auto_tab_line_at_cursor = 1;
|
||||
|
@ -606,80 +610,82 @@ static int32_t fcoder_metacmd_ID_query_replace = 140;
|
|||
static int32_t fcoder_metacmd_ID_query_replace_identifier = 141;
|
||||
static int32_t fcoder_metacmd_ID_query_replace_selection = 142;
|
||||
static int32_t fcoder_metacmd_ID_redo = 143;
|
||||
static int32_t fcoder_metacmd_ID_reload_themes = 144;
|
||||
static int32_t fcoder_metacmd_ID_remap_interactive = 145;
|
||||
static int32_t fcoder_metacmd_ID_rename_file_query = 146;
|
||||
static int32_t fcoder_metacmd_ID_reopen = 147;
|
||||
static int32_t fcoder_metacmd_ID_replace_in_range = 148;
|
||||
static int32_t fcoder_metacmd_ID_reverse_search = 149;
|
||||
static int32_t fcoder_metacmd_ID_reverse_search_identifier = 150;
|
||||
static int32_t fcoder_metacmd_ID_save = 151;
|
||||
static int32_t fcoder_metacmd_ID_save_all_dirty_buffers = 152;
|
||||
static int32_t fcoder_metacmd_ID_save_to_query = 153;
|
||||
static int32_t fcoder_metacmd_ID_scope_absorb_down = 154;
|
||||
static int32_t fcoder_metacmd_ID_search = 155;
|
||||
static int32_t fcoder_metacmd_ID_search_identifier = 156;
|
||||
static int32_t fcoder_metacmd_ID_seek_alphanumeric_left = 157;
|
||||
static int32_t fcoder_metacmd_ID_seek_alphanumeric_or_camel_left = 158;
|
||||
static int32_t fcoder_metacmd_ID_seek_alphanumeric_or_camel_right = 159;
|
||||
static int32_t fcoder_metacmd_ID_seek_alphanumeric_right = 160;
|
||||
static int32_t fcoder_metacmd_ID_seek_beginning_of_line = 161;
|
||||
static int32_t fcoder_metacmd_ID_seek_beginning_of_textual_line = 162;
|
||||
static int32_t fcoder_metacmd_ID_seek_end_of_line = 163;
|
||||
static int32_t fcoder_metacmd_ID_seek_end_of_textual_line = 164;
|
||||
static int32_t fcoder_metacmd_ID_seek_token_left = 165;
|
||||
static int32_t fcoder_metacmd_ID_seek_token_right = 166;
|
||||
static int32_t fcoder_metacmd_ID_seek_white_or_token_left = 167;
|
||||
static int32_t fcoder_metacmd_ID_seek_white_or_token_right = 168;
|
||||
static int32_t fcoder_metacmd_ID_seek_whitespace_down = 169;
|
||||
static int32_t fcoder_metacmd_ID_seek_whitespace_down_end_line = 170;
|
||||
static int32_t fcoder_metacmd_ID_seek_whitespace_left = 171;
|
||||
static int32_t fcoder_metacmd_ID_seek_whitespace_right = 172;
|
||||
static int32_t fcoder_metacmd_ID_seek_whitespace_up = 173;
|
||||
static int32_t fcoder_metacmd_ID_seek_whitespace_up_end_line = 174;
|
||||
static int32_t fcoder_metacmd_ID_select_all = 175;
|
||||
static int32_t fcoder_metacmd_ID_select_next_scope_absolute = 176;
|
||||
static int32_t fcoder_metacmd_ID_select_prev_scope_absolute = 177;
|
||||
static int32_t fcoder_metacmd_ID_select_surrounding_scope = 178;
|
||||
static int32_t fcoder_metacmd_ID_set_bindings_choose = 179;
|
||||
static int32_t fcoder_metacmd_ID_set_bindings_default = 180;
|
||||
static int32_t fcoder_metacmd_ID_set_bindings_mac_default = 181;
|
||||
static int32_t fcoder_metacmd_ID_set_mark = 182;
|
||||
static int32_t fcoder_metacmd_ID_set_mode_to_notepad_like = 183;
|
||||
static int32_t fcoder_metacmd_ID_set_mode_to_original = 184;
|
||||
static int32_t fcoder_metacmd_ID_setup_build_bat = 185;
|
||||
static int32_t fcoder_metacmd_ID_setup_build_bat_and_sh = 186;
|
||||
static int32_t fcoder_metacmd_ID_setup_build_sh = 187;
|
||||
static int32_t fcoder_metacmd_ID_setup_new_project = 188;
|
||||
static int32_t fcoder_metacmd_ID_show_filebar = 189;
|
||||
static int32_t fcoder_metacmd_ID_show_scrollbar = 190;
|
||||
static int32_t fcoder_metacmd_ID_snipe_token_or_word = 191;
|
||||
static int32_t fcoder_metacmd_ID_snipe_token_or_word_right = 192;
|
||||
static int32_t fcoder_metacmd_ID_snippet_lister = 193;
|
||||
static int32_t fcoder_metacmd_ID_suppress_mouse = 194;
|
||||
static int32_t fcoder_metacmd_ID_swap_buffers_between_panels = 195;
|
||||
static int32_t fcoder_metacmd_ID_to_lowercase = 196;
|
||||
static int32_t fcoder_metacmd_ID_to_uppercase = 197;
|
||||
static int32_t fcoder_metacmd_ID_toggle_filebar = 198;
|
||||
static int32_t fcoder_metacmd_ID_toggle_fullscreen = 199;
|
||||
static int32_t fcoder_metacmd_ID_toggle_highlight_enclosing_scopes = 200;
|
||||
static int32_t fcoder_metacmd_ID_toggle_highlight_line_at_cursor = 201;
|
||||
static int32_t fcoder_metacmd_ID_toggle_line_wrap = 202;
|
||||
static int32_t fcoder_metacmd_ID_toggle_mouse = 203;
|
||||
static int32_t fcoder_metacmd_ID_toggle_paren_matching_helper = 204;
|
||||
static int32_t fcoder_metacmd_ID_toggle_show_whitespace = 205;
|
||||
static int32_t fcoder_metacmd_ID_toggle_virtual_whitespace = 206;
|
||||
static int32_t fcoder_metacmd_ID_uncomment_line = 207;
|
||||
static int32_t fcoder_metacmd_ID_undo = 208;
|
||||
static int32_t fcoder_metacmd_ID_view_buffer_other_panel = 209;
|
||||
static int32_t fcoder_metacmd_ID_view_jump_list_with_lister = 210;
|
||||
static int32_t fcoder_metacmd_ID_word_complete = 211;
|
||||
static int32_t fcoder_metacmd_ID_write_and_auto_tab = 212;
|
||||
static int32_t fcoder_metacmd_ID_write_block = 213;
|
||||
static int32_t fcoder_metacmd_ID_write_character = 214;
|
||||
static int32_t fcoder_metacmd_ID_write_hack = 215;
|
||||
static int32_t fcoder_metacmd_ID_write_note = 216;
|
||||
static int32_t fcoder_metacmd_ID_write_todo = 217;
|
||||
static int32_t fcoder_metacmd_ID_write_underscore = 218;
|
||||
static int32_t fcoder_metacmd_ID_write_zero_struct = 219;
|
||||
static int32_t fcoder_metacmd_ID_redo_this_buffer = 144;
|
||||
static int32_t fcoder_metacmd_ID_reload_themes = 145;
|
||||
static int32_t fcoder_metacmd_ID_remap_interactive = 146;
|
||||
static int32_t fcoder_metacmd_ID_rename_file_query = 147;
|
||||
static int32_t fcoder_metacmd_ID_reopen = 148;
|
||||
static int32_t fcoder_metacmd_ID_replace_in_range = 149;
|
||||
static int32_t fcoder_metacmd_ID_reverse_search = 150;
|
||||
static int32_t fcoder_metacmd_ID_reverse_search_identifier = 151;
|
||||
static int32_t fcoder_metacmd_ID_save = 152;
|
||||
static int32_t fcoder_metacmd_ID_save_all_dirty_buffers = 153;
|
||||
static int32_t fcoder_metacmd_ID_save_to_query = 154;
|
||||
static int32_t fcoder_metacmd_ID_scope_absorb_down = 155;
|
||||
static int32_t fcoder_metacmd_ID_search = 156;
|
||||
static int32_t fcoder_metacmd_ID_search_identifier = 157;
|
||||
static int32_t fcoder_metacmd_ID_seek_alphanumeric_left = 158;
|
||||
static int32_t fcoder_metacmd_ID_seek_alphanumeric_or_camel_left = 159;
|
||||
static int32_t fcoder_metacmd_ID_seek_alphanumeric_or_camel_right = 160;
|
||||
static int32_t fcoder_metacmd_ID_seek_alphanumeric_right = 161;
|
||||
static int32_t fcoder_metacmd_ID_seek_beginning_of_line = 162;
|
||||
static int32_t fcoder_metacmd_ID_seek_beginning_of_textual_line = 163;
|
||||
static int32_t fcoder_metacmd_ID_seek_end_of_line = 164;
|
||||
static int32_t fcoder_metacmd_ID_seek_end_of_textual_line = 165;
|
||||
static int32_t fcoder_metacmd_ID_seek_token_left = 166;
|
||||
static int32_t fcoder_metacmd_ID_seek_token_right = 167;
|
||||
static int32_t fcoder_metacmd_ID_seek_white_or_token_left = 168;
|
||||
static int32_t fcoder_metacmd_ID_seek_white_or_token_right = 169;
|
||||
static int32_t fcoder_metacmd_ID_seek_whitespace_down = 170;
|
||||
static int32_t fcoder_metacmd_ID_seek_whitespace_down_end_line = 171;
|
||||
static int32_t fcoder_metacmd_ID_seek_whitespace_left = 172;
|
||||
static int32_t fcoder_metacmd_ID_seek_whitespace_right = 173;
|
||||
static int32_t fcoder_metacmd_ID_seek_whitespace_up = 174;
|
||||
static int32_t fcoder_metacmd_ID_seek_whitespace_up_end_line = 175;
|
||||
static int32_t fcoder_metacmd_ID_select_all = 176;
|
||||
static int32_t fcoder_metacmd_ID_select_next_scope_absolute = 177;
|
||||
static int32_t fcoder_metacmd_ID_select_prev_scope_absolute = 178;
|
||||
static int32_t fcoder_metacmd_ID_select_surrounding_scope = 179;
|
||||
static int32_t fcoder_metacmd_ID_set_bindings_choose = 180;
|
||||
static int32_t fcoder_metacmd_ID_set_bindings_default = 181;
|
||||
static int32_t fcoder_metacmd_ID_set_bindings_mac_default = 182;
|
||||
static int32_t fcoder_metacmd_ID_set_mark = 183;
|
||||
static int32_t fcoder_metacmd_ID_set_mode_to_notepad_like = 184;
|
||||
static int32_t fcoder_metacmd_ID_set_mode_to_original = 185;
|
||||
static int32_t fcoder_metacmd_ID_setup_build_bat = 186;
|
||||
static int32_t fcoder_metacmd_ID_setup_build_bat_and_sh = 187;
|
||||
static int32_t fcoder_metacmd_ID_setup_build_sh = 188;
|
||||
static int32_t fcoder_metacmd_ID_setup_new_project = 189;
|
||||
static int32_t fcoder_metacmd_ID_show_filebar = 190;
|
||||
static int32_t fcoder_metacmd_ID_show_scrollbar = 191;
|
||||
static int32_t fcoder_metacmd_ID_snipe_token_or_word = 192;
|
||||
static int32_t fcoder_metacmd_ID_snipe_token_or_word_right = 193;
|
||||
static int32_t fcoder_metacmd_ID_snippet_lister = 194;
|
||||
static int32_t fcoder_metacmd_ID_suppress_mouse = 195;
|
||||
static int32_t fcoder_metacmd_ID_swap_buffers_between_panels = 196;
|
||||
static int32_t fcoder_metacmd_ID_to_lowercase = 197;
|
||||
static int32_t fcoder_metacmd_ID_to_uppercase = 198;
|
||||
static int32_t fcoder_metacmd_ID_toggle_filebar = 199;
|
||||
static int32_t fcoder_metacmd_ID_toggle_fullscreen = 200;
|
||||
static int32_t fcoder_metacmd_ID_toggle_highlight_enclosing_scopes = 201;
|
||||
static int32_t fcoder_metacmd_ID_toggle_highlight_line_at_cursor = 202;
|
||||
static int32_t fcoder_metacmd_ID_toggle_line_wrap = 203;
|
||||
static int32_t fcoder_metacmd_ID_toggle_mouse = 204;
|
||||
static int32_t fcoder_metacmd_ID_toggle_paren_matching_helper = 205;
|
||||
static int32_t fcoder_metacmd_ID_toggle_show_whitespace = 206;
|
||||
static int32_t fcoder_metacmd_ID_toggle_virtual_whitespace = 207;
|
||||
static int32_t fcoder_metacmd_ID_uncomment_line = 208;
|
||||
static int32_t fcoder_metacmd_ID_undo = 209;
|
||||
static int32_t fcoder_metacmd_ID_undo_this_buffer = 210;
|
||||
static int32_t fcoder_metacmd_ID_view_buffer_other_panel = 211;
|
||||
static int32_t fcoder_metacmd_ID_view_jump_list_with_lister = 212;
|
||||
static int32_t fcoder_metacmd_ID_word_complete = 213;
|
||||
static int32_t fcoder_metacmd_ID_write_and_auto_tab = 214;
|
||||
static int32_t fcoder_metacmd_ID_write_block = 215;
|
||||
static int32_t fcoder_metacmd_ID_write_character = 216;
|
||||
static int32_t fcoder_metacmd_ID_write_hack = 217;
|
||||
static int32_t fcoder_metacmd_ID_write_note = 218;
|
||||
static int32_t fcoder_metacmd_ID_write_todo = 219;
|
||||
static int32_t fcoder_metacmd_ID_write_underscore = 220;
|
||||
static int32_t fcoder_metacmd_ID_write_zero_struct = 221;
|
||||
#endif
|
||||
|
|
|
@ -64,24 +64,6 @@ end_map(Bind_Helper *helper){
|
|||
helper->group = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
bind(Bind_Helper *helper, Key_Code code, uint8_t modifiers, Command_ID cmdid){
|
||||
if (helper->group == 0 && helper->error == 0){
|
||||
helper->error = BH_ERR_MISSING_BEGIN;
|
||||
}
|
||||
if (!helper->error){
|
||||
++helper->group->map_begin.bind_count;
|
||||
}
|
||||
|
||||
Binding_Unit unit;
|
||||
unit.type = unit_binding;
|
||||
unit.binding.command_id = cmdid;
|
||||
unit.binding.code = code;
|
||||
unit.binding.modifiers = modifiers;
|
||||
|
||||
write_unit(helper, unit);
|
||||
}
|
||||
|
||||
static void
|
||||
bind(Bind_Helper *helper, Key_Code code, uint8_t modifiers, Custom_Command_Function *func){
|
||||
if (helper->group == 0 && helper->error == 0){
|
||||
|
@ -102,17 +84,7 @@ bind(Bind_Helper *helper, Key_Code code, uint8_t modifiers, Custom_Command_Funct
|
|||
|
||||
static void
|
||||
bind(Bind_Helper *helper, Key_Code code, uint8_t modifiers, Generic_Command cmd){
|
||||
if (cmd.cmdid < cmdid_count){
|
||||
bind(helper, code, modifiers, cmd.cmdid);
|
||||
}
|
||||
else{
|
||||
bind(helper, code, modifiers, cmd.command);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bind_vanilla_keys(Bind_Helper *helper, int32_t cmdid){
|
||||
bind(helper, 0, 0, cmdid);
|
||||
bind(helper, code, modifiers, cmd.command);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -120,11 +92,6 @@ bind_vanilla_keys(Bind_Helper *helper, Custom_Command_Function *func){
|
|||
bind(helper, 0, 0, func);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_vanilla_keys(Bind_Helper *helper, unsigned char modifiers, int32_t cmdid){
|
||||
bind(helper, 0, modifiers, cmdid);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_vanilla_keys(Bind_Helper *helper, unsigned char modifiers, Custom_Command_Function *func){
|
||||
bind(helper, 0, modifiers, func);
|
||||
|
@ -301,12 +268,7 @@ exec_command(Application_Links *app, Custom_Command_Function *func){
|
|||
|
||||
static void
|
||||
exec_command(Application_Links *app, Generic_Command cmd){
|
||||
if (cmd.cmdid < cmdid_count){
|
||||
exec_command(app, cmd.cmdid);
|
||||
}
|
||||
else{
|
||||
exec_command(app, cmd.command);
|
||||
}
|
||||
exec_command(app, cmd.command);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
|
@ -735,7 +697,8 @@ get_view_range(View_Summary *view){
|
|||
}
|
||||
|
||||
static bool32
|
||||
read_line(Application_Links *app, Partition *part, Buffer_Summary *buffer, int32_t line, String *str){
|
||||
read_line(Application_Links *app, Partition *part, Buffer_Summary *buffer, int32_t line, String *str,
|
||||
Partial_Cursor *start_out, Partial_Cursor *one_past_last_out){
|
||||
Partial_Cursor begin = {};
|
||||
Partial_Cursor end = {};
|
||||
|
||||
|
@ -749,10 +712,13 @@ read_line(Application_Links *app, Partition *part, Buffer_Summary *buffer, int32
|
|||
char *memory = push_array(part, char, alloc_size);
|
||||
if (memory != 0){
|
||||
*str = make_string(memory, 0, alloc_size);
|
||||
success = true;
|
||||
buffer_read_range(app, buffer, begin.pos, end.pos, str->str);
|
||||
str->size = size;
|
||||
terminate_with_null(str);
|
||||
|
||||
*start_out = begin;
|
||||
*one_past_last_out = end;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -762,6 +728,12 @@ read_line(Application_Links *app, Partition *part, Buffer_Summary *buffer, int32
|
|||
return(success);
|
||||
}
|
||||
|
||||
static bool32
|
||||
read_line(Application_Links *app, Partition *part, Buffer_Summary *buffer, int32_t line, String *str){
|
||||
Partial_Cursor ignore = {};
|
||||
return(read_line(app, part, buffer, line, str, &ignore, &ignore));
|
||||
}
|
||||
|
||||
static int32_t
|
||||
buffer_get_line_start(Application_Links *app, Buffer_Summary *buffer, int32_t line){
|
||||
int32_t result = buffer->size;
|
||||
|
@ -1608,5 +1580,24 @@ view_set_split_pixel_size(Application_Links *app, View_Summary *view, int32_t t)
|
|||
return(view_set_split(app, view, ViewSplitKind_FixedPixels, (float)t));
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
static Record_Info
|
||||
get_single_record(Application_Links *app, Buffer_ID buffer_id, History_Record_Index index){
|
||||
Buffer_Summary buffer = get_buffer(app, buffer_id, AccessOpen);
|
||||
Record_Info record = buffer_history_get_record_info(app, &buffer, index);
|
||||
if (record.error == RecordError_NoError && record.kind == RecordKind_Group){
|
||||
record = buffer_history_get_group_sub_record(app, &buffer, index, record.group.count);
|
||||
}
|
||||
return(record);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
static void
|
||||
view_buffer_set(Application_Links *app, Buffer_ID *buffers, int32_t count){
|
||||
// TODO(allen): do(implement view_buffer_set)
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
|
@ -268,6 +268,7 @@ get_all_stored_jumps_from_list(Application_Links *app, Partition *arena, Marker_
|
|||
|
||||
static bool32
|
||||
get_jump_from_list(Application_Links *app, Marker_List *list, int32_t index, ID_Pos_Jump_Location *location){
|
||||
bool32 result = false;
|
||||
Sticky_Jump_Stored stored = {};
|
||||
if (get_stored_jump_from_list(app, list, index, &stored)){
|
||||
Buffer_ID target_buffer_id = stored.jump_buffer_id;
|
||||
|
@ -284,10 +285,10 @@ get_jump_from_list(Application_Links *app, Marker_List *list, int32_t index, ID_
|
|||
managed_object_load_data(app, marker_array, stored.index_into_marker_array, 1, &marker);
|
||||
location->buffer_id = target_buffer_id;
|
||||
location->pos = marker.pos;
|
||||
return(true);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return(false);
|
||||
return(result);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
|
@ -575,7 +576,6 @@ CUSTOM_DOC("If the buffer in the active view is writable, inserts a character, o
|
|||
{
|
||||
View_Summary view = get_active_view(app, AccessProtected);
|
||||
Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected);
|
||||
|
||||
if (buffer.lock_flags & AccessProtected){
|
||||
goto_jump_at_cursor_sticky(app);
|
||||
lock_jump_buffer(buffer);
|
||||
|
@ -590,7 +590,6 @@ CUSTOM_DOC("If the buffer in the active view is writable, inserts a character, o
|
|||
{
|
||||
View_Summary view = get_active_view(app, AccessProtected);
|
||||
Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected);
|
||||
|
||||
if (buffer.lock_flags & AccessProtected){
|
||||
goto_jump_at_cursor_same_panel_sticky(app);
|
||||
lock_jump_buffer(buffer);
|
||||
|
@ -614,5 +613,138 @@ OPEN_FILE_HOOK_SIG(end_file_close_jump_list){
|
|||
return(0);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
static bool32
|
||||
search_buffer_edit_handler__inner(Application_Links *app, Partition *part, Buffer_ID buffer_id, int32_t start, int32_t one_past_last, String text){
|
||||
Buffer_Summary buffer = get_buffer(app, buffer_id, AccessProtected);
|
||||
|
||||
// NOTE(allen): get the list for this buffer
|
||||
Marker_List *list = get_or_make_list_for_buffer(app, part, &global_heap, buffer_id);
|
||||
if (list == 0){
|
||||
return(false);
|
||||
}
|
||||
|
||||
// NOTE(allen): activate jumps
|
||||
if (match(text, "\n")){
|
||||
// TODO(allen): do(determine when shift is held here and do *same_panel* version of goto_jump_at_cursor_sticky)
|
||||
goto_jump_at_cursor_sticky(app);
|
||||
lock_jump_buffer(buffer);
|
||||
return(false);
|
||||
}
|
||||
|
||||
// NOTE(allen): do not allow new lines to be inserted ever
|
||||
if (find_s_char(text, 0, '\n') != text.size){
|
||||
return(false);
|
||||
}
|
||||
|
||||
// NOTE(allen): check that the range is entirely inside an editable range
|
||||
Partial_Cursor start_cursor = {};
|
||||
Partial_Cursor one_past_last_cursor = {};
|
||||
if (!(buffer_compute_cursor(app, &buffer, seek_pos(start), &start_cursor) &&
|
||||
buffer_compute_cursor(app, &buffer, seek_pos(one_past_last), &one_past_last_cursor))){
|
||||
return(false);
|
||||
}
|
||||
if (start_cursor.line != one_past_last_cursor.line){
|
||||
return(false);
|
||||
}
|
||||
|
||||
int32_t line_number = start_cursor.line;
|
||||
Partial_Cursor line_start_cursor = {};
|
||||
Partial_Cursor line_one_past_last_cursor = {};
|
||||
String line = {};
|
||||
if (!read_line(app, part, &buffer, line_number, &line, &line_start_cursor, &line_one_past_last_cursor)){
|
||||
return(false);
|
||||
}
|
||||
|
||||
int32_t line_start = line_start_cursor.pos;
|
||||
int32_t line_one_past_last = line_one_past_last_cursor.pos;
|
||||
|
||||
int32_t colon_index = find_substr(line, 0, make_lit_string(": "));
|
||||
if (colon_index == line.size){
|
||||
return(false);
|
||||
}
|
||||
|
||||
int32_t editable_start_from_line_start = colon_index + 2;
|
||||
int32_t editable_start = line_start + editable_start_from_line_start;
|
||||
int32_t editable_one_past_last = line_one_past_last;
|
||||
if (!(editable_start <= start && one_past_last <= editable_one_past_last)){
|
||||
return(false);
|
||||
}
|
||||
|
||||
// NOTE(allen): figure out the target buffer make sure we want to edit it
|
||||
int32_t list_index = get_index_exact_from_list(app, part, list, line_number);
|
||||
if (list_index < 0){
|
||||
return(false);
|
||||
}
|
||||
|
||||
ID_Pos_Jump_Location location = {};
|
||||
if (!get_jump_from_list(app, list, list_index, &location)){
|
||||
return(false);
|
||||
}
|
||||
|
||||
Buffer_Summary target_buffer = {};
|
||||
if (!get_jump_buffer(app, &target_buffer, &location, AccessOpen)){
|
||||
return(false);
|
||||
}
|
||||
|
||||
int32_t is_unimportant = false;
|
||||
if (!buffer_get_setting(app, &target_buffer, BufferSetting_Unimportant, &is_unimportant)){
|
||||
return(false);
|
||||
}
|
||||
|
||||
if (is_unimportant){
|
||||
return(false);
|
||||
}
|
||||
|
||||
// NOTE(allen): figure out the shift of the edit from the search buffer to the target buffer
|
||||
Partial_Cursor target_pos = {};
|
||||
if (!buffer_compute_cursor(app, &target_buffer, seek_pos(location.pos), &target_pos)){
|
||||
return(false);
|
||||
}
|
||||
|
||||
int32_t target_line_number = target_pos.line;
|
||||
Partial_Cursor target_line_start_cursor = {};
|
||||
Partial_Cursor target_line_one_past_last_cursor = {};
|
||||
String target_line = {};
|
||||
if (!read_line(app, part, &target_buffer, target_line_number, &target_line, &target_line_start_cursor, &target_line_one_past_last_cursor)){
|
||||
return(false);
|
||||
}
|
||||
|
||||
String editable_string = substr(line, editable_start_from_line_start, editable_one_past_last - editable_start);
|
||||
if (!match(skip_chop_whitespace(target_line), editable_string)){
|
||||
return(false);
|
||||
}
|
||||
|
||||
int32_t target_line_start = target_line_start_cursor.pos;
|
||||
//int32_t target_line_one_past_last = target_line_one_past_last_cursor.pos;
|
||||
|
||||
String target_line_skip_whitespace = skip_whitespace(target_line);
|
||||
int32_t skip_into_line_amount = (int32_t)(target_line_skip_whitespace.str - target_line.str);
|
||||
|
||||
int32_t target_editable_start = target_line_start + skip_into_line_amount;
|
||||
int32_t edit_range_shift = target_editable_start - editable_start;
|
||||
|
||||
// NOTE(allen): try to apply the edits
|
||||
global_history_edit_group_begin(app);
|
||||
bool32 result = false;
|
||||
if (buffer_replace_range(app, &target_buffer, start + edit_range_shift, one_past_last + edit_range_shift, text.str, text.size)){
|
||||
if (buffer_replace_range(app, &buffer, start, one_past_last, text.str, text.size)){
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
global_history_edit_group_end(app);
|
||||
return(result);
|
||||
}
|
||||
|
||||
static bool32
|
||||
search_buffer_edit_handler(Application_Links *app, Buffer_ID buffer_id, int32_t start, int32_t one_past_last, String text){
|
||||
Partition *scratch = &global_part;
|
||||
Temp_Memory temp = begin_temp_memory(scratch);
|
||||
bool32 result = search_buffer_edit_handler__inner(app, scratch, buffer_id, start, one_past_last, text);
|
||||
end_temp_memory(temp);
|
||||
return(result);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
|
@ -221,18 +221,18 @@ parse_jump_from_buffer_line(Application_Links *app, Partition *arena,
|
|||
|
||||
static bool32
|
||||
get_jump_buffer(Application_Links *app, Buffer_Summary *buffer, Name_Line_Column_Location *location){
|
||||
bool32 result = open_file(app, buffer, location->file.str, location->file.size, false, true);
|
||||
return(result);
|
||||
return(open_file(app, buffer, location->file.str, location->file.size, false, true));
|
||||
}
|
||||
|
||||
static bool32
|
||||
get_jump_buffer(Application_Links *app, Buffer_Summary *buffer, ID_Pos_Jump_Location *location, Access_Flag access){
|
||||
*buffer = get_buffer(app, location->buffer_id, access);
|
||||
return((bool32)buffer->exists);
|
||||
}
|
||||
|
||||
static bool32
|
||||
get_jump_buffer(Application_Links *app, Buffer_Summary *buffer, ID_Pos_Jump_Location *location){
|
||||
*buffer = get_buffer(app, location->buffer_id, AccessAll);
|
||||
bool32 result = false;
|
||||
if (buffer->exists){
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
return(get_jump_buffer(app, buffer, location, AccessAll));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -236,6 +236,23 @@ end_temp_memory(Temp_Memory_Arena temp){
|
|||
}
|
||||
}
|
||||
|
||||
static Temp_Memory_Arena_Light
|
||||
temp_memory_light(Temp_Memory_Arena temp){
|
||||
Temp_Memory_Arena_Light light = {};
|
||||
light.part = temp.part;
|
||||
light.pos = temp.pos;
|
||||
return(light);
|
||||
}
|
||||
|
||||
static void
|
||||
end_temp_memory(Arena *arena, Temp_Memory_Arena_Light temp){
|
||||
Temp_Memory_Arena full_temp = {};
|
||||
full_temp.arena = arena;
|
||||
full_temp.part = temp.part;
|
||||
full_temp.pos = temp.pos;
|
||||
end_temp_memory(full_temp);
|
||||
}
|
||||
|
||||
static void*
|
||||
push_allocator_allocate(Arena *arena, i32_4tech size){
|
||||
return(arena_allocate(arena, size));
|
||||
|
|
|
@ -75,6 +75,11 @@ struct Temp_Memory_Arena{
|
|||
i32_4tech pos;
|
||||
};
|
||||
|
||||
struct Temp_Memory_Arena_Light{
|
||||
Partition_Chained *part;
|
||||
i32_4tech pos;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -590,7 +590,8 @@ buffered_memory_reserve(Application_Links *app, Partition *part, Temp_Memory tem
|
|||
}
|
||||
|
||||
static void
|
||||
buffered_print_match_jump_line(Application_Links *app, Partition *part, Temp_Memory temp, Partition *line_part, Buffer_Summary *output_buffer, Buffer_Summary *match_buffer, Partial_Cursor word_pos){
|
||||
buffered_print_match_jump_line(Application_Links *app, Partition *part, Temp_Memory temp, Partition *line_part, Buffer_Summary *output_buffer,
|
||||
Buffer_Summary *match_buffer, Partial_Cursor word_pos){
|
||||
char *file_name = match_buffer->buffer_name;
|
||||
int32_t file_len = match_buffer->buffer_name_len;
|
||||
|
||||
|
@ -622,16 +623,21 @@ buffered_print_match_jump_line(Application_Links *app, Partition *part, Temp_Mem
|
|||
end_temp_memory(line_temp);
|
||||
}
|
||||
|
||||
static bool32
|
||||
search_buffer_edit_handler(Application_Links *app, Buffer_ID buffer_id, int32_t start, int32_t one_past_last, String text);
|
||||
|
||||
static void
|
||||
list__parameters(Application_Links *app, Heap *heap, Partition *scratch,
|
||||
String *strings, int32_t count, Search_Range_Flag match_flags,
|
||||
View_Summary default_target_view){
|
||||
// Open the search buffer
|
||||
String search_name = make_lit_string("*search*");
|
||||
Buffer_ID search_buffer_id = create_or_switch_to_buffer_by_name(app, search_name.str, search_name.size,
|
||||
default_target_view);
|
||||
Buffer_ID search_buffer_id = create_or_switch_to_buffer_by_name(app, search_name.str, search_name.size, default_target_view);
|
||||
Buffer_Summary search_buffer = get_buffer(app, search_buffer_id, AccessAll);
|
||||
|
||||
// Setup the search buffer for 'init' mode - the history will begin only AFTER the buffer is filled
|
||||
buffer_set_setting(app, &search_buffer, BufferSetting_RecordsHistory, false);
|
||||
|
||||
// Initialize a generic search all buffers
|
||||
Search_Set set = {};
|
||||
Search_Iter iter = {};
|
||||
|
@ -672,6 +678,11 @@ list__parameters(Application_Links *app, Heap *heap, Partition *scratch,
|
|||
|
||||
// Lock *search* as the jump buffer
|
||||
lock_jump_buffer(search_name.str, search_name.size);
|
||||
|
||||
// Setup the search buffer for 'reference editing' mode
|
||||
buffer_set_setting(app, &search_buffer, BufferSetting_ReadOnly, false);
|
||||
buffer_set_setting(app, &search_buffer, BufferSetting_RecordsHistory, true);
|
||||
buffer_set_edit_handler(app, search_buffer_id, search_buffer_edit_handler);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
199
4ed.cpp
199
4ed.cpp
|
@ -58,7 +58,14 @@ internal void
|
|||
output_file_append(System_Functions *system, Models *models, Editing_File *file, String value){
|
||||
if (!file->is_dummy){
|
||||
i32 end = buffer_size(&file->state.buffer);
|
||||
edit_single(system, models, file, end, end, value.str, value.size);
|
||||
Edit edit = {};
|
||||
edit.str = value.str;
|
||||
edit.length = value.size;
|
||||
edit.range.first = end;
|
||||
edit.range.one_past_last = end;
|
||||
|
||||
Edit_Behaviors behaviors = {};
|
||||
edit_single(system, models, file, edit, behaviors);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,11 +78,12 @@ file_cursor_to_end(System_Functions *system, Models *models, Editing_File *file)
|
|||
panel != 0;
|
||||
panel = layout_get_next_open_panel(layout, panel)){
|
||||
View *view = panel->view;
|
||||
if (view->transient.file_data.file != file){
|
||||
if (view->file_data.file != file){
|
||||
continue;
|
||||
}
|
||||
view_cursor_move(system, view, pos);
|
||||
view->transient.edit_pos.mark = view->transient.edit_pos.cursor.pos;
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
||||
view->mark = edit_pos.cursor_pos;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,60 +105,8 @@ file_cursor_to_end(System_Functions *system, Models *models, Editing_File *file)
|
|||
|
||||
#define REQ_OPEN_VIEW(n) USE_VIEW(n); if (view_lock_flags(n) != 0) return
|
||||
|
||||
#define REQ_FILE(n,v) Editing_File *n = (v)->transient.file_data.file; if (n == 0) return
|
||||
#define REQ_FILE_HISTORY(n,v) Editing_File *n = (v)->transient.file_data.file; if (n == 0 || n->state.undo.undo.edits == 0) return
|
||||
|
||||
#define COMMAND_DECL(n) internal void command_##n(System_Functions *system, Models *models, Command_Binding binding)
|
||||
|
||||
COMMAND_DECL(null){}
|
||||
|
||||
internal void
|
||||
view_undo_redo(System_Functions *system, Models *models, View *view, Edit_Stack *stack, Edit_Type expected_type){
|
||||
Editing_File *file = view->transient.file_data.file;
|
||||
Assert(file != 0);
|
||||
if (stack->edit_count > 0){
|
||||
Edit_Step step = stack->edits[stack->edit_count - 1];
|
||||
Assert(step.type == expected_type);
|
||||
edit_historical(system, models, file, view, stack,
|
||||
step, hist_normal);
|
||||
}
|
||||
}
|
||||
|
||||
COMMAND_DECL(undo){
|
||||
Panel *active_panel = layout_get_active_panel(&models->layout);
|
||||
View *view = active_panel->view;
|
||||
if (view_lock_flags(view) != 0){
|
||||
return;
|
||||
}
|
||||
Editing_File *file = view->transient.file_data.file;
|
||||
if (file->state.undo.undo.edits == 0){
|
||||
return;
|
||||
}
|
||||
view_undo_redo(system, models, view, &file->state.undo.undo, ED_UNDO);
|
||||
Assert(file->state.undo.undo.size >= 0);
|
||||
}
|
||||
|
||||
COMMAND_DECL(redo){
|
||||
Panel *active_panel = layout_get_active_panel(&models->layout);
|
||||
View *view = active_panel->view;
|
||||
if (view_lock_flags(view) != 0){
|
||||
return;
|
||||
}
|
||||
Editing_File *file = view->transient.file_data.file;
|
||||
if (file->state.undo.undo.edits == 0){
|
||||
return;
|
||||
}
|
||||
view_undo_redo(system, models, view, &file->state.undo.redo, ED_REDO);
|
||||
Assert(file->state.undo.undo.size >= 0);
|
||||
}
|
||||
|
||||
COMMAND_DECL(user_callback){
|
||||
if (binding.custom != 0){
|
||||
binding.custom(&models->app_links);
|
||||
}
|
||||
}
|
||||
|
||||
global Command_Function *command_table[cmdid_count];
|
||||
#define REQ_FILE(n,v) Editing_File *n = (v)->file_data.file; if (n == 0) return
|
||||
#define REQ_FILE_HISTORY(n,v) Editing_File *n = (v)->file_data.file; if (n == 0 || n->state.undo.undo.edits == 0) return
|
||||
|
||||
SCROLL_RULE_SIG(fallback_scroll_rule){
|
||||
b32 result = false;
|
||||
|
@ -171,16 +127,15 @@ SCROLL_RULE_SIG(fallback_scroll_rule){
|
|||
internal void
|
||||
setup_ui_commands(Command_Map *commands, Partition *part, i32 parent){
|
||||
map_init(commands, part, DEFAULT_UI_MAP_SIZE, parent);
|
||||
|
||||
// TODO(allen): do(fix the weird built-in-ness of the ui map)
|
||||
u8 mdfr_array[] = {MDFR_NONE, MDFR_SHIFT, MDFR_CTRL, MDFR_SHIFT | MDFR_CTRL};
|
||||
for (i32 i = 0; i < 4; ++i){
|
||||
u8 mdfr = mdfr_array[i];
|
||||
map_add(commands, key_left , mdfr, command_null, (Custom_Command_Function*)0);
|
||||
map_add(commands, key_right, mdfr, command_null, (Custom_Command_Function*)0);
|
||||
map_add(commands, key_up , mdfr, command_null, (Custom_Command_Function*)0);
|
||||
map_add(commands, key_down , mdfr, command_null, (Custom_Command_Function*)0);
|
||||
map_add(commands, key_back , mdfr, command_null, (Custom_Command_Function*)0);
|
||||
map_add(commands, key_left , mdfr, (Custom_Command_Function*)0);
|
||||
map_add(commands, key_right, mdfr, (Custom_Command_Function*)0);
|
||||
map_add(commands, key_up , mdfr, (Custom_Command_Function*)0);
|
||||
map_add(commands, key_down , mdfr, (Custom_Command_Function*)0);
|
||||
map_add(commands, key_back , mdfr, (Custom_Command_Function*)0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,45 +322,19 @@ interpret_binding_buffer(Models *models, void *buffer, i32 size){
|
|||
}
|
||||
}break;
|
||||
|
||||
case unit_binding:
|
||||
{
|
||||
if (map_ptr != 0){
|
||||
Command_Function *func = 0;
|
||||
if (unit->binding.command_id < cmdid_count){
|
||||
func = command_table[unit->binding.command_id];
|
||||
}
|
||||
if (func != 0){
|
||||
if (unit->binding.code == 0){
|
||||
u32 index = 0;
|
||||
if (map_get_modifiers_hash(unit->binding.modifiers, &index)){
|
||||
map_ptr->vanilla_keyboard_default[index].function = func;
|
||||
map_ptr->vanilla_keyboard_default[index].custom_id = unit->binding.command_id;
|
||||
}
|
||||
}
|
||||
else{
|
||||
map_add(map_ptr, unit->binding.code, unit->binding.modifiers, func, unit->binding.command_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
||||
case unit_callback:
|
||||
{
|
||||
if (map_ptr != 0){
|
||||
Command_Function *func = command_user_callback;
|
||||
Custom_Command_Function *custom = unit->callback.func;
|
||||
if (func != 0){
|
||||
if (unit->callback.code == 0){
|
||||
u32 index = 0;
|
||||
if (map_get_modifiers_hash(unit->binding.modifiers, &index)){
|
||||
map_ptr->vanilla_keyboard_default[index].function = func;
|
||||
map_ptr->vanilla_keyboard_default[index].custom = custom;
|
||||
}
|
||||
}
|
||||
else{
|
||||
map_add(map_ptr, unit->callback.code, unit->callback.modifiers, func, custom);
|
||||
if (unit->callback.code == 0){
|
||||
u32 index = 0;
|
||||
if (map_get_modifiers_hash(unit->callback.modifiers, &index)){
|
||||
map_ptr->vanilla_keyboard_default[index].custom = custom;
|
||||
}
|
||||
}
|
||||
else{
|
||||
map_add(map_ptr, unit->callback.code, unit->callback.modifiers, custom);
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
||||
|
@ -510,18 +439,13 @@ internal void
|
|||
command_caller(Coroutine_Head *coroutine){
|
||||
Command_In *cmd_in = (Command_In*)coroutine->in;
|
||||
Models *models = cmd_in->models;
|
||||
if (models->command_caller){
|
||||
Generic_Command generic;
|
||||
if (cmd_in->bind.function == command_user_callback){
|
||||
generic.command = cmd_in->bind.custom;
|
||||
}
|
||||
else{
|
||||
generic.cmdid = (Command_ID)cmd_in->bind.custom_id;
|
||||
}
|
||||
if (models->command_caller != 0){
|
||||
Generic_Command generic = {};
|
||||
generic.command = cmd_in->bind.custom;
|
||||
models->command_caller(&models->app_links, generic);
|
||||
}
|
||||
else{
|
||||
cmd_in->bind.function(models->system, models, cmd_in->bind);
|
||||
cmd_in->bind.custom(&models->app_links);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -534,15 +458,6 @@ app_links_init(System_Functions *system, Application_Links *app_links, void *dat
|
|||
app_links->system_links = system;
|
||||
}
|
||||
|
||||
internal void
|
||||
setup_command_table(void){
|
||||
#define SET(n) command_table[cmdid_##n] = command_##n
|
||||
SET(null);
|
||||
SET(undo);
|
||||
SET(redo);
|
||||
#undef SET
|
||||
}
|
||||
|
||||
// App Functions
|
||||
|
||||
internal void
|
||||
|
@ -821,7 +736,7 @@ force_abort_coroutine(System_Functions *system, Models *models, View *view){
|
|||
// TODO(allen): post grave warning
|
||||
models->command_coroutine = 0;
|
||||
}
|
||||
init_query_set(&view->transient.query_set);
|
||||
init_query_set(&view->query_set);
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -831,12 +746,12 @@ launch_command_via_event(System_Functions *system, Application_Step_Result *app_
|
|||
i32 map = view_get_map(view);
|
||||
Command_Binding cmd_bind = map_extract_recursive(&models->mapping, map, event);
|
||||
|
||||
if (cmd_bind.function != 0){
|
||||
if (cmd_bind.custom != 0){
|
||||
Assert(models->command_coroutine == 0);
|
||||
Coroutine_Head *command_coroutine = system->create_coroutine(command_caller);
|
||||
models->command_coroutine = command_coroutine;
|
||||
|
||||
Command_In cmd_in;
|
||||
Command_In cmd_in = {};
|
||||
cmd_in.models = models;
|
||||
cmd_in.bind = cmd_bind;
|
||||
|
||||
|
@ -887,20 +802,17 @@ App_Init_Sig(app_init){
|
|||
models->live_set.views = push_array(part, View, models->live_set.max);
|
||||
|
||||
//dll_init_sentinel
|
||||
models->live_set.free_sentinel.transient.next = &models->live_set.free_sentinel;
|
||||
models->live_set.free_sentinel.transient.prev = &models->live_set.free_sentinel;
|
||||
models->live_set.free_sentinel.next = &models->live_set.free_sentinel;
|
||||
models->live_set.free_sentinel.prev = &models->live_set.free_sentinel;
|
||||
|
||||
i32 max = models->live_set.max;
|
||||
View *view = models->live_set.views;
|
||||
for (i32 i = 0; i < max; ++i, ++view){
|
||||
//dll_insert(&models->live_set.free_sentinel, view);
|
||||
view->transient.next = models->live_set.free_sentinel.transient.next;
|
||||
view->transient.prev = &models->live_set.free_sentinel;
|
||||
models->live_set.free_sentinel.transient.next = view;
|
||||
view->transient.next->transient.prev = view;
|
||||
|
||||
View_Persistent *persistent = &view->persistent;
|
||||
persistent->id = i;
|
||||
view->next = models->live_set.free_sentinel.next;
|
||||
view->prev = &models->live_set.free_sentinel;
|
||||
models->live_set.free_sentinel.next = view;
|
||||
view->next->prev = view;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -912,7 +824,6 @@ App_Init_Sig(app_init){
|
|||
}
|
||||
|
||||
{
|
||||
setup_command_table();
|
||||
Assert(models->config_api.get_bindings != 0);
|
||||
i32 wanted_size = models->config_api.get_bindings(models->app_links.memory, models->app_links.memory_size);
|
||||
Assert(wanted_size <= models->app_links.memory_size);
|
||||
|
@ -928,6 +839,9 @@ App_Init_Sig(app_init){
|
|||
models->working_set.default_display_width = DEFAULT_DISPLAY_WIDTH;
|
||||
models->working_set.default_minimum_base_display_width = DEFAULT_MINIMUM_BASE_DISPLAY_WIDTH;
|
||||
|
||||
// NOTE(allen): history setup
|
||||
global_history_init(&models->global_history);
|
||||
|
||||
// NOTE(allen): clipboard setup
|
||||
models->working_set.clipboard_max_size = ArrayCount(models->working_set.clipboards);
|
||||
models->working_set.clipboard_size = 0;
|
||||
|
@ -990,7 +904,7 @@ App_Init_Sig(app_init){
|
|||
Panel *panel = layout_initialize(part, &models->layout);
|
||||
View *new_view = live_set_alloc_view(&models->mem.heap, &models->lifetime_allocator, &models->live_set);
|
||||
panel->view = new_view;
|
||||
new_view->transient.panel = panel;
|
||||
new_view->panel = panel;
|
||||
view_set_file(system, models, new_view, models->scratch_buffer);
|
||||
}
|
||||
|
||||
|
@ -1067,7 +981,7 @@ App_Step_Sig(app_step){
|
|||
|
||||
// NOTE(allen): reorganizing panels on screen
|
||||
Vec2_i32 prev_dim = layout_get_root_size(&models->layout);
|
||||
Vec2_i32 current_dim = V2(target->width, target->height);
|
||||
Vec2_i32 current_dim = V2i32(target->width, target->height);
|
||||
layout_set_root_size(&models->layout, current_dim);
|
||||
|
||||
// NOTE(allen): First frame initialization
|
||||
|
@ -1215,7 +1129,7 @@ App_Step_Sig(app_step){
|
|||
Panel *mouse_panel = 0;
|
||||
Panel *divider_panel = 0;
|
||||
b32 mouse_in_margin = false;
|
||||
Vec2_i32 mouse = V2(input->mouse.x, input->mouse.y);
|
||||
Vec2_i32 mouse = V2i32(input->mouse.x, input->mouse.y);
|
||||
{
|
||||
for (Panel *panel = layout_get_first_open_panel(layout);
|
||||
panel != 0;
|
||||
|
@ -1321,7 +1235,7 @@ App_Step_Sig(app_step){
|
|||
|
||||
app_result.animating = true;
|
||||
if (models->command_coroutine == 0){
|
||||
init_query_set(&view->transient.query_set);
|
||||
init_query_set(&view->query_set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1376,20 +1290,21 @@ App_Step_Sig(app_step){
|
|||
GUI_Scroll_Vars *scroll_vars = 0;
|
||||
i32 max_y = 0;
|
||||
b32 file_scroll = false;
|
||||
if (!view->transient.ui_mode){
|
||||
scroll_vars = &view->transient.edit_pos.scroll;
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
||||
if (!view->ui_mode){
|
||||
scroll_vars = &edit_pos.scroll;
|
||||
max_y = view_compute_max_target_y(view);
|
||||
file_scroll = true;
|
||||
}
|
||||
else{
|
||||
scroll_vars = &view->transient.ui_scroll;
|
||||
i32 bottom = view->transient.ui_control.bounding_box[UICoordinates_Scrolled].y1;
|
||||
scroll_vars = &view->ui_scroll;
|
||||
i32 bottom = view->ui_control.bounding_box[UICoordinates_Scrolled].y1;
|
||||
max_y = view_compute_max_target_y_from_bottom_y(view, (f32)bottom);
|
||||
file_scroll = false;
|
||||
}
|
||||
|
||||
b32 active = (panel == active_panel);
|
||||
Input_Process_Result ip_result = do_step_file_view(system, view, models, panel->rect_inner, active, dt, *scroll_vars, max_y);
|
||||
Input_Process_Result ip_result = do_step_file_view(system, models, view, panel->rect_inner, active, dt, *scroll_vars, max_y);
|
||||
|
||||
if (ip_result.is_animating){
|
||||
app_result.animating = true;
|
||||
|
@ -1412,9 +1327,10 @@ App_Step_Sig(app_step){
|
|||
panel != 0;
|
||||
panel = layout_get_next_open_panel(layout, panel)){
|
||||
View *view = panel->view;
|
||||
GUI_Scroll_Vars *scroll_vars = &view->transient.edit_pos.scroll;
|
||||
scroll_vars->scroll_x = (f32)scroll_vars->target_x;
|
||||
scroll_vars->scroll_y = (f32)scroll_vars->target_y;
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
||||
edit_pos.scroll.scroll_x = (f32)edit_pos.scroll.target_x;
|
||||
edit_pos.scroll.scroll_y = (f32)edit_pos.scroll.target_y;
|
||||
view_set_edit_pos(view, edit_pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1502,11 +1418,14 @@ App_Step_Sig(app_step){
|
|||
|
||||
draw_rectangle(target, full, style->theme.colors[Stag_Back]);
|
||||
|
||||
GUI_Scroll_Vars *scroll_vars = &view->transient.edit_pos.scroll;
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
||||
GUI_Scroll_Vars *scroll_vars = &edit_pos.scroll;
|
||||
|
||||
b32 active = (panel == active_panel);
|
||||
do_render_file_view(system, view, models, scroll_vars, active_view, inner, active, target);
|
||||
|
||||
view_set_edit_pos(view, edit_pos);
|
||||
|
||||
u32 margin_color = 0;
|
||||
if (active){
|
||||
margin_color = style->theme.colors[Stag_Margin_Active];
|
||||
|
|
|
@ -51,32 +51,35 @@ fill_buffer_summary(Buffer_Summary *buffer, Editing_File *file, Working_Set *wor
|
|||
|
||||
internal void
|
||||
fill_view_summary(System_Functions *system, View_Summary *view, View *vptr, Live_Views *live_set, Working_Set *working_set){
|
||||
File_Viewing_Data *data = &vptr->transient.file_data;
|
||||
File_Viewing_Data *data = &vptr->file_data;
|
||||
|
||||
memset(view, 0, sizeof(*view));
|
||||
|
||||
if (vptr->transient.in_use){
|
||||
if (vptr->in_use){
|
||||
view->exists = true;
|
||||
view->view_id = (int32_t)(vptr - live_set->views) + 1;
|
||||
view->line_height = (f32)(vptr->transient.line_height);
|
||||
view->line_height = (f32)(vptr->line_height);
|
||||
view->unwrapped_lines = data->file->settings.unwrapped_lines;
|
||||
view->show_whitespace = data->show_whitespace;
|
||||
view->lock_flags = view_lock_flags(vptr);
|
||||
|
||||
view->buffer_id = vptr->transient.file_data.file->id.id;
|
||||
view->buffer_id = vptr->file_data.file->id.id;
|
||||
|
||||
Assert(data->file != 0);
|
||||
view->mark = file_compute_cursor(system, data->file, seek_pos(vptr->transient.edit_pos.mark), 0);
|
||||
view->cursor = vptr->transient.edit_pos.cursor;
|
||||
view->preferred_x = vptr->transient.edit_pos.preferred_x;
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(vptr);
|
||||
|
||||
view->view_region = vptr->transient.panel->rect_inner;
|
||||
view->file_region = vptr->transient.file_region;
|
||||
if (vptr->transient.ui_mode){
|
||||
view->scroll_vars = vptr->transient.ui_scroll;
|
||||
view->mark = file_compute_cursor(system, data->file, seek_pos(vptr->mark));
|
||||
view->cursor = file_compute_cursor(system, data->file, seek_pos(edit_pos.cursor_pos));
|
||||
|
||||
view->preferred_x = vptr->preferred_x;
|
||||
|
||||
view->view_region = vptr->panel->rect_inner;
|
||||
view->file_region = vptr->file_region;
|
||||
if (vptr->ui_mode){
|
||||
view->scroll_vars = vptr->ui_scroll;
|
||||
}
|
||||
else{
|
||||
view->scroll_vars = vptr->transient.edit_pos.scroll;
|
||||
view->scroll_vars = edit_pos.scroll;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -89,11 +92,11 @@ fill_view_summary(System_Functions *system, View_Summary *view, View *vptr, Mode
|
|||
internal void
|
||||
view_quit_ui(System_Functions *system, Models *models, View *view){
|
||||
Assert(view != 0);
|
||||
view->transient.ui_mode = false;
|
||||
if (view->transient.ui_quit != 0){
|
||||
view->ui_mode = false;
|
||||
if (view->ui_quit != 0){
|
||||
View_Summary view_summary = {};
|
||||
fill_view_summary(system, &view_summary, view, models);
|
||||
view->transient.ui_quit(&models->app_links, view_summary);
|
||||
view->ui_quit(&models->app_links, view_summary);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,7 +139,7 @@ imp_get_view(Models *models, View_ID view_id){
|
|||
view_id = view_id - 1;
|
||||
if (0 <= view_id && view_id < live_set->max){
|
||||
vptr = live_set->views + view_id;
|
||||
if (!vptr->transient.in_use){
|
||||
if (!vptr->in_use){
|
||||
vptr = 0;
|
||||
}
|
||||
}
|
||||
|
@ -190,34 +193,6 @@ DOC(Dumps away the previous mappings and instantiates the mappings described in
|
|||
return(result);
|
||||
}
|
||||
|
||||
API_EXPORT bool32
|
||||
Exec_Command(Application_Links *app, Command_ID command_id)
|
||||
/*
|
||||
DOC_PARAM(command_id, The command_id parameter specifies which internal command to execute.)
|
||||
DOC_RETURN(This call returns non-zero if command_id named a valid internal command.)
|
||||
DOC(A call to exec_command executes an internal command. If command_id is invalid a warning is posted to *messages*.)
|
||||
DOC_SEE(Command_ID)
|
||||
*/{
|
||||
bool32 result = false;
|
||||
|
||||
if (command_id < cmdid_count){
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
Command_Function *function = command_table[command_id];
|
||||
Command_Binding binding = {};
|
||||
binding.function = function;
|
||||
if (function != 0){
|
||||
function(models->system, models, binding);
|
||||
}
|
||||
|
||||
result = true;
|
||||
}
|
||||
else{
|
||||
print_message(app, literal("WARNING: An invalid Command_ID was passed to exec_command."));
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
API_EXPORT bool32
|
||||
Exec_System_Command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer_id, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags)
|
||||
/*
|
||||
|
@ -646,21 +621,21 @@ DOC_SEE(4coder_Buffer_Positioning_System)
|
|||
}
|
||||
|
||||
API_EXPORT bool32
|
||||
Buffer_Replace_Range(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *str, int32_t len)
|
||||
Buffer_Replace_Range(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t one_past_last, char *str, int32_t len)
|
||||
/*
|
||||
DOC_PARAM(buffer, This parameter specifies the buffer to edit.)
|
||||
DOC_PARAM(start, This parameter specifies absolute position of the first character in the replace range.)
|
||||
DOC_PARAM(end, This parameter specifies the absolute position of the the character one past the end of the replace range.)
|
||||
DOC_PARAM(one_past_last, This parameter specifies the absolute position of the the character one past the end of the replace range.)
|
||||
DOC_PARAM(str, This parameter specifies the the string to write into the range; it need not be null terminated.)
|
||||
DOC_PARAM(len, This parameter specifies the length of the str string.)
|
||||
DOC_RETURN(This call returns non-zero if the replacement succeeds.)
|
||||
DOC
|
||||
(
|
||||
If this call succeeds it deletes the range from start to end
|
||||
and writes str in the same position. If end == start then
|
||||
If this call succeeds it deletes the range from start to one_past_last
|
||||
and writes str in the same position. If one_past_last == start then
|
||||
this call is equivalent to inserting the string at start.
|
||||
If len == 0 this call is equivalent to deleteing the range
|
||||
from start to end.
|
||||
from start to one_past_last.
|
||||
|
||||
This call fails if the buffer does not exist, or if the replace
|
||||
range is not within the bounds of the buffer.
|
||||
|
@ -673,15 +648,40 @@ DOC_SEE(4coder_Buffer_Positioning_System)
|
|||
int32_t size = 0;
|
||||
if (file != 0){
|
||||
size = buffer_size(&file->state.buffer);
|
||||
if (0 <= start && start <= end && end <= size){
|
||||
result = true;
|
||||
edit_single(models->system, models, file, start, end, str, len);
|
||||
if (0 <= start && start <= one_past_last && one_past_last <= size){
|
||||
b32 do_low_level_edit = (file->settings.edit_handler == 0 || file->state.in_edit_handler);
|
||||
if (do_low_level_edit){
|
||||
Edit edit = {};
|
||||
edit.str = str;
|
||||
edit.length = len;
|
||||
edit.range.first = start;
|
||||
edit.range.one_past_last = one_past_last;
|
||||
Edit_Behaviors behaviors = {};
|
||||
edit_single(models->system, models, file, edit, behaviors);
|
||||
result = true;
|
||||
}
|
||||
else{
|
||||
file->state.in_edit_handler = true;
|
||||
result = file->settings.edit_handler(app, buffer->buffer_id, start, one_past_last, make_string(str, len));
|
||||
file->state.in_edit_handler = false;
|
||||
}
|
||||
}
|
||||
fill_buffer_summary(buffer, file, &models->working_set);
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
API_EXPORT bool32
|
||||
Buffer_Set_Edit_Handler(Application_Links *app, Buffer_ID buffer_id, Buffer_Edit_Handler *handler){
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
Editing_File *file = imp_get_file(models, buffer_id);
|
||||
bool32 result = (file != 0);
|
||||
if (result){
|
||||
file->settings.edit_handler = handler;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
API_EXPORT bool32
|
||||
Buffer_Compute_Cursor(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out)
|
||||
/*
|
||||
|
@ -702,8 +702,8 @@ DOC_SEE(Partial_Cursor)
|
|||
bool32 result = false;
|
||||
if (file != 0){
|
||||
if (file_compute_partial_cursor(file, seek, cursor_out)){
|
||||
result = true;
|
||||
fill_buffer_summary(buffer, file, &models->working_set);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
|
@ -732,13 +732,22 @@ DOC_SEE(Buffer_Batch_Edit_Type)
|
|||
if (file != 0){
|
||||
if (edit_count > 0){
|
||||
Temp_Memory temp = begin_temp_memory(part);
|
||||
Buffer_Edit *inverse_edits = push_array(part, Buffer_Edit, edit_count);
|
||||
Assert(inverse_edits != 0);
|
||||
char *inv_str = (char*)part->base + part->pos;
|
||||
int32_t inv_str_max = part->max - part->pos;
|
||||
Edit_Spec spec = edit_compute_batch_spec(&mem->heap, file, edits, str, str_len,
|
||||
inverse_edits, inv_str, inv_str_max, edit_count, type);
|
||||
edit_batch(system, models, file, spec, hist_normal, type);
|
||||
Edit_Array real_edits = {};
|
||||
real_edits.vals = push_array(part, Edit, edit_count);
|
||||
real_edits.count = edit_count;
|
||||
Edit *edit_out = real_edits.vals;
|
||||
Buffer_Edit *edit_in = edits;
|
||||
Edit *one_past_last_edit_out = real_edits.vals + edit_count;
|
||||
for (;edit_out < one_past_last_edit_out;
|
||||
edit_out += 1, edit_in += 1){
|
||||
edit_out->str = str + edit_in->str_start;
|
||||
edit_out->length = edit_in->len;
|
||||
edit_out->range.first = edit_in->start;
|
||||
edit_out->range.one_past_last = edit_in->end;
|
||||
}
|
||||
Edit_Behaviors behaviors = {};
|
||||
behaviors.batch_type = type;
|
||||
edit_batch(system, models, file, real_edits, behaviors);
|
||||
end_temp_memory(temp);
|
||||
}
|
||||
result = true;
|
||||
|
@ -815,6 +824,11 @@ DOC_RETURN(returns non-zero on success)
|
|||
*value_out = file->settings.virtual_white;
|
||||
}break;
|
||||
|
||||
case BufferSetting_RecordsHistory:
|
||||
{
|
||||
*value_out = history_is_activated(&file->state.history);
|
||||
}break;
|
||||
|
||||
default:
|
||||
{
|
||||
result = 0;
|
||||
|
@ -999,7 +1013,24 @@ DOC_SEE(Buffer_Setting_ID)
|
|||
}
|
||||
}break;
|
||||
|
||||
default: result = 0; break;
|
||||
case BufferSetting_RecordsHistory:
|
||||
{
|
||||
if (value){
|
||||
if (!history_is_activated(&file->state.history)){
|
||||
history_init(app, &file->state.history);
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (history_is_activated(&file->state.history)){
|
||||
history_free(&models->mem.heap, &file->state.history);
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
||||
default:
|
||||
{
|
||||
result = 0;
|
||||
}break;
|
||||
}
|
||||
fill_buffer_summary(buffer, file, &models->working_set);
|
||||
}
|
||||
|
@ -1252,7 +1283,10 @@ DOC_SEE(Buffer_Create_Flag)
|
|||
if (file != 0 && (flags & BufferCreate_AlwaysNew) != 0){
|
||||
i32 size = buffer_size(&file->state.buffer);
|
||||
if (size > 0){
|
||||
edit_single(system, models, file, 0, size, 0, 0);
|
||||
Edit edit = {};
|
||||
edit.range.one_past_last = size;
|
||||
Edit_Behaviors behaviors = {};
|
||||
edit_single(system, models, file, edit, behaviors);
|
||||
if (has_canon_name){
|
||||
buffer_is_for_new_file = true;
|
||||
}
|
||||
|
@ -1343,7 +1377,7 @@ DOC_SEE(Buffer_Identifier)
|
|||
if (file->canon.name.size != 0){
|
||||
buffer_unbind_file(system, working_set, file);
|
||||
}
|
||||
file_free(system, &models->app_links, &models->mem.heap, &models->lifetime_allocator, file);
|
||||
file_free(system, &models->mem.heap, &models->lifetime_allocator, file);
|
||||
working_set_free_file(&models->mem.heap, working_set, file);
|
||||
|
||||
Layout *layout = &models->layout;
|
||||
|
@ -1354,9 +1388,9 @@ DOC_SEE(Buffer_Identifier)
|
|||
panel != 0;
|
||||
panel = layout_get_next_open_panel(layout, panel)){
|
||||
View *view = panel->view;
|
||||
if (view->transient.file_data.file == file){
|
||||
if (view->file_data.file == file){
|
||||
Assert(file_node != used);
|
||||
view->transient.file_data.file = 0;
|
||||
view->file_data.file = 0;
|
||||
Editing_File *new_file = CastFromMember(Editing_File, main_chain_node, file_node);
|
||||
view_set_file(system, models, view, new_file);
|
||||
if (file_node->next != used){
|
||||
|
@ -1403,7 +1437,6 @@ Reopen_Buffer(Application_Links *app, Buffer_Summary *buffer, Buffer_Reopen_Flag
|
|||
|
||||
// TODO(allen): try(perform a diff maybe apply edits in reopen)
|
||||
|
||||
File_Edit_Positions edit_positions[16];
|
||||
int32_t line_numbers[16];
|
||||
int32_t column_numbers[16];
|
||||
View *vptrs[16];
|
||||
|
@ -1414,29 +1447,29 @@ Reopen_Buffer(Application_Links *app, Buffer_Summary *buffer, Buffer_Reopen_Flag
|
|||
panel != 0;
|
||||
panel = layout_get_next_open_panel(layout, panel)){
|
||||
View *view_it = panel->view;
|
||||
if (view_it->transient.file_data.file != file){
|
||||
if (view_it->file_data.file != file){
|
||||
continue;
|
||||
}
|
||||
vptrs[vptr_count] = view_it;
|
||||
edit_positions[vptr_count] = view_it->transient.edit_pos;
|
||||
line_numbers[vptr_count] = view_it->transient.edit_pos.cursor.line;
|
||||
column_numbers[vptr_count] = view_it->transient.edit_pos.cursor.character;
|
||||
view_it->transient.file_data.file = models->scratch_buffer;
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(view_it);
|
||||
Full_Cursor cursor = file_compute_cursor(system, view_it->file_data.file, seek_pos(edit_pos.cursor_pos));
|
||||
line_numbers[vptr_count] = cursor.line;
|
||||
column_numbers[vptr_count] = cursor.character;
|
||||
view_it->file_data.file = models->scratch_buffer;
|
||||
++vptr_count;
|
||||
}
|
||||
|
||||
file_free(system, &models->app_links, &models->mem.heap, &models->lifetime_allocator, file);
|
||||
file_free(system, &models->mem.heap, &models->lifetime_allocator, file);
|
||||
working_set_file_default_settings(&models->working_set, file);
|
||||
init_normal_file(system, models, file_memory, size, file);
|
||||
|
||||
for (i32 i = 0; i < vptr_count; ++i){
|
||||
view_set_file(system, models, vptrs[i], file);
|
||||
|
||||
vptrs[i]->transient.file_data.file = file;
|
||||
vptrs[i]->transient.edit_pos = edit_positions[i];
|
||||
Full_Cursor cursor = file_compute_cursor(system, file, seek_line_char(line_numbers[i], column_numbers[i]), 0);
|
||||
vptrs[i]->file_data.file = file;
|
||||
Full_Cursor cursor = file_compute_cursor(system, file, seek_line_char(line_numbers[i], column_numbers[i]));
|
||||
|
||||
view_set_cursor(vptrs[i], cursor, true, file->settings.unwrapped_lines);
|
||||
view_set_cursor(system, vptrs[i], cursor, true);
|
||||
}
|
||||
|
||||
result = BufferReopenResult_Reopened;
|
||||
|
@ -1470,7 +1503,7 @@ get_view_next__internal(Models *models, View_Summary *view){
|
|||
i32 index = view->view_id - 1;
|
||||
if (index >= 0 && index < live_set->max){
|
||||
View *vptr = live_set->views + index;
|
||||
Panel *panel = vptr->transient.panel;
|
||||
Panel *panel = vptr->panel;
|
||||
if (panel != 0){
|
||||
panel = layout_get_next_open_panel(layout, panel);
|
||||
}
|
||||
|
@ -1589,7 +1622,7 @@ DOC_SEE(View_Split_Position)
|
|||
System_Functions *system = models->system;
|
||||
Layout *layout = &models->layout;
|
||||
View *vptr = imp_get_view(models, view_location);
|
||||
Panel *panel = vptr->transient.panel;
|
||||
Panel *panel = vptr->panel;
|
||||
View_Summary result = {};
|
||||
b32 vertical_split = ((position == ViewSplit_Left) || (position == ViewSplit_Right));
|
||||
b32 br_split = ((position == ViewSplit_Bottom) || (position == ViewSplit_Right));
|
||||
|
@ -1597,7 +1630,7 @@ DOC_SEE(View_Split_Position)
|
|||
if (new_panel != 0){
|
||||
View *new_view = live_set_alloc_view(&models->mem.heap, &models->lifetime_allocator, &models->live_set);
|
||||
new_panel->view = new_view;
|
||||
new_view->transient.panel = new_panel;
|
||||
new_view->panel = new_panel;
|
||||
view_set_file(system, models, new_view, models->scratch_buffer);
|
||||
fill_view_summary(system, &result, new_view, models);
|
||||
}
|
||||
|
@ -1622,7 +1655,7 @@ in the system, the call will fail.)
|
|||
|
||||
bool32 result = false;
|
||||
if (vptr != 0){
|
||||
if (layout_close_panel(layout, vptr->transient.panel)){
|
||||
if (layout_close_panel(layout, vptr->panel)){
|
||||
live_set_free_view(&models->mem.heap, &models->lifetime_allocator, &models->live_set, vptr);
|
||||
result = true;
|
||||
}
|
||||
|
@ -1645,7 +1678,7 @@ DOC_SEE(get_active_view)
|
|||
View *vptr = imp_get_view(models, view);
|
||||
bool32 result = false;
|
||||
if (vptr != 0){
|
||||
models->layout.active_panel = vptr->transient.panel;
|
||||
models->layout.active_panel = vptr->panel;
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
|
@ -1668,22 +1701,22 @@ DOC_RETURN(returns non-zero on success)
|
|||
switch (setting){
|
||||
case ViewSetting_ShowWhitespace:
|
||||
{
|
||||
*value_out = vptr->transient.file_data.show_whitespace;
|
||||
*value_out = vptr->file_data.show_whitespace;
|
||||
}break;
|
||||
|
||||
case ViewSetting_ShowScrollbar:
|
||||
{
|
||||
*value_out = !vptr->transient.hide_scrollbar;
|
||||
*value_out = !vptr->hide_scrollbar;
|
||||
}break;
|
||||
|
||||
case ViewSetting_ShowFileBar:
|
||||
{
|
||||
*value_out = !vptr->transient.hide_file_bar;
|
||||
*value_out = !vptr->hide_file_bar;
|
||||
}break;
|
||||
|
||||
case ViewSetting_UICommandMap:
|
||||
{
|
||||
*value_out = vptr->transient.ui_map_id;
|
||||
*value_out = vptr->ui_map_id;
|
||||
}break;
|
||||
|
||||
default:
|
||||
|
@ -1715,22 +1748,22 @@ DOC_SEE(View_Setting_ID)
|
|||
switch (setting){
|
||||
case ViewSetting_ShowWhitespace:
|
||||
{
|
||||
vptr->transient.file_data.show_whitespace = value;
|
||||
vptr->file_data.show_whitespace = value;
|
||||
}break;
|
||||
|
||||
case ViewSetting_ShowScrollbar:
|
||||
{
|
||||
vptr->transient.hide_scrollbar = !value;
|
||||
vptr->hide_scrollbar = !value;
|
||||
}break;
|
||||
|
||||
case ViewSetting_ShowFileBar:
|
||||
{
|
||||
vptr->transient.hide_file_bar = !value;
|
||||
vptr->hide_file_bar = !value;
|
||||
}break;
|
||||
|
||||
case ViewSetting_UICommandMap:
|
||||
{
|
||||
vptr->transient.ui_map_id = value;
|
||||
vptr->ui_map_id = value;
|
||||
}break;
|
||||
|
||||
default:
|
||||
|
@ -1758,8 +1791,8 @@ If the view_id does not specify a valid view, the returned scope is null.)
|
|||
View *view = imp_get_view(models, view_id);
|
||||
Managed_Scope lifetime = 0;
|
||||
if (view != 0){
|
||||
Assert(view->transient.lifetime_object != 0);
|
||||
lifetime = (Managed_Scope)(view->transient.lifetime_object->workspace.scope_id);
|
||||
Assert(view->lifetime_object != 0);
|
||||
lifetime = (Managed_Scope)(view->lifetime_object->workspace.scope_id);
|
||||
}
|
||||
return(lifetime);
|
||||
}
|
||||
|
@ -1784,7 +1817,7 @@ DOC_RETURN(This call returns non-zero on success.)
|
|||
View *vptr = imp_get_view(models, view);
|
||||
bool32 result = false;
|
||||
if (vptr != 0){
|
||||
Panel *panel = vptr->transient.panel;
|
||||
Panel *panel = vptr->panel;
|
||||
Panel *intermediate = panel->parent;
|
||||
if (intermediate != 0){
|
||||
Assert(intermediate->kind == PanelKind_Intermediate);
|
||||
|
@ -1836,7 +1869,7 @@ DOC_RETURN(The rectangle of the panel containing this view.)
|
|||
View *vptr = imp_get_view(models, view);
|
||||
i32_Rect result = {};
|
||||
if (vptr != 0){
|
||||
Panel *panel = vptr->transient.panel;
|
||||
Panel *panel = vptr->panel;
|
||||
Assert(panel != 0);
|
||||
Panel *parent = panel->parent;
|
||||
if (parent != 0){
|
||||
|
@ -1866,11 +1899,11 @@ DOC_SEE(Full_Cursor)
|
|||
bool32 result = false;
|
||||
|
||||
if (vptr != 0){
|
||||
Editing_File *file = vptr->transient.file_data.file;
|
||||
Editing_File *file = vptr->file_data.file;
|
||||
Assert(file != 0);
|
||||
if (!file->is_loading){
|
||||
result = true;
|
||||
*cursor_out = file_compute_cursor(system, file, seek, 0);
|
||||
*cursor_out = file_compute_cursor(system, file, seek);
|
||||
fill_view_summary(system, view, vptr, models);
|
||||
}
|
||||
}
|
||||
|
@ -1894,12 +1927,12 @@ DOC_SEE(Buffer_Seek)
|
|||
bool32 result = false;
|
||||
|
||||
if (vptr != 0){
|
||||
Editing_File *file = vptr->transient.file_data.file;
|
||||
Editing_File *file = vptr->file_data.file;
|
||||
if (!file->is_loading){
|
||||
result = true;
|
||||
Full_Cursor cursor = file_compute_cursor(system, file, seek, 0);
|
||||
view_set_cursor(vptr, cursor, set_preferred_x, file->settings.unwrapped_lines);
|
||||
Full_Cursor cursor = file_compute_cursor(system, file, seek);
|
||||
view_set_cursor(system, vptr, cursor, set_preferred_x);
|
||||
fill_view_summary(system, view, vptr, models);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1920,14 +1953,14 @@ DOC_SEE(GUI_Scroll_Vars)
|
|||
bool32 result = false;
|
||||
|
||||
if (vptr != 0){
|
||||
Editing_File *file = vptr->transient.file_data.file;
|
||||
Editing_File *file = vptr->file_data.file;
|
||||
if (!file->is_loading){
|
||||
result = true;
|
||||
if (!vptr->transient.ui_mode){
|
||||
if (!vptr->ui_mode){
|
||||
view_set_scroll(system, vptr, scroll);
|
||||
}
|
||||
else{
|
||||
vptr->transient.ui_scroll = scroll;
|
||||
vptr->ui_scroll = scroll;
|
||||
}
|
||||
fill_view_summary(system, view, vptr, models);
|
||||
}
|
||||
|
@ -1951,17 +1984,17 @@ DOC_SEE(Buffer_Seek)
|
|||
bool32 result = false;
|
||||
|
||||
if (vptr != 0){
|
||||
Editing_File *file = vptr->transient.file_data.file;
|
||||
Editing_File *file = vptr->file_data.file;
|
||||
Assert(file != 0);
|
||||
if (!file->is_loading){
|
||||
if (seek.type != buffer_seek_pos){
|
||||
result = true;
|
||||
Full_Cursor cursor = file_compute_cursor(system, file, seek, 0);
|
||||
vptr->transient.edit_pos.mark = cursor.pos;
|
||||
Full_Cursor cursor = file_compute_cursor(system, file, seek);
|
||||
vptr->mark = cursor.pos;
|
||||
}
|
||||
else{
|
||||
result = true;
|
||||
vptr->transient.edit_pos.mark = seek.pos;
|
||||
vptr->mark = seek.pos;
|
||||
}
|
||||
fill_view_summary(system, view, vptr, models);
|
||||
}
|
||||
|
@ -1972,36 +2005,10 @@ DOC_SEE(Buffer_Seek)
|
|||
|
||||
API_EXPORT bool32
|
||||
View_Set_Highlight(Application_Links *app, View_Summary *view, int32_t start, int32_t end, bool32 turn_on)/*
|
||||
DOC_PARAM(view, The view parameter specifies the view in which to set the highlight.)
|
||||
DOC_PARAM(start, This parameter specifies the absolute position of the first character of the highlight range.)
|
||||
DOC_PARAM(end, This parameter specifies the absolute position of the character one past the end of the highlight range.)
|
||||
DOC_PARAM(turn_on, This parameter indicates whether the highlight is being turned on or off.)
|
||||
DOC_RETURN(This call returns non-zero on success.)
|
||||
DOC
|
||||
(
|
||||
The highlight is mutually exclusive to the cursor. When the turn_on parameter
|
||||
is set to true the highlight will be shown and the cursor will be hidden. After
|
||||
that either setting the cursor with view_set_cursor or calling view_set_highlight
|
||||
and the turn_on set to false, will switch back to showing the cursor.
|
||||
)
|
||||
DOC(This feature has been removed. Transition to the new highlighting system view markers which allow for
|
||||
arbitrarily many highlights, and cursors, at the same time.)
|
||||
*/{
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
System_Functions *system = models->system;
|
||||
View *vptr = imp_get_view(models, view);
|
||||
bool32 result = false;
|
||||
|
||||
if (vptr != 0){
|
||||
result = true;
|
||||
if (turn_on){
|
||||
view_set_temp_highlight(system, vptr, start, end);
|
||||
}
|
||||
else{
|
||||
vptr->transient.file_data.show_temp_highlight = false;
|
||||
}
|
||||
fill_view_summary(system, view, vptr, models);
|
||||
}
|
||||
|
||||
return(result);
|
||||
return(false);
|
||||
}
|
||||
|
||||
API_EXPORT bool32
|
||||
|
@ -2023,7 +2030,7 @@ DOC_SEE(Set_Buffer_Flag)
|
|||
Editing_File *file = working_set_get_active_file(&models->working_set, buffer_id);
|
||||
if (file != 0){
|
||||
result = true;
|
||||
if (file != vptr->transient.file_data.file){
|
||||
if (file != vptr->file_data.file){
|
||||
view_set_file(system, models, vptr, file);
|
||||
if (!(flags & SetBuffer_KeepOriginalGUI)){
|
||||
view_quit_ui(system, models, vptr);
|
||||
|
@ -2074,11 +2081,11 @@ DOC_SEE(view_set_ui)
|
|||
Models *models = (Models*)app->cmd_context;
|
||||
View *vptr = imp_get_view(models, view);
|
||||
if (vptr != 0){
|
||||
if (vptr->transient.ui_mode){
|
||||
if (vptr->ui_mode){
|
||||
return(false);
|
||||
}
|
||||
else{
|
||||
vptr->transient.ui_mode = true;
|
||||
vptr->ui_mode = true;
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
|
@ -2101,9 +2108,9 @@ DOC_SEE(view_set_ui)
|
|||
bool32 result = false;
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
View *vptr = imp_get_view(models, view);
|
||||
if (vptr != 0 && vptr->transient.ui_mode){
|
||||
if (vptr != 0 && vptr->ui_mode){
|
||||
view_quit_ui(models->system, models, vptr);
|
||||
vptr->transient.ui_mode = false;
|
||||
vptr->ui_mode = false;
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
|
@ -2127,11 +2134,11 @@ DOC_SEE(UI_Quit_Function_Type)
|
|||
Heap *heap = &models->mem.heap;
|
||||
View *vptr = imp_get_view(models, view);
|
||||
if (vptr != 0){
|
||||
if (vptr->transient.ui_control.items != 0){
|
||||
heap_free(heap, vptr->transient.ui_control.items);
|
||||
if (vptr->ui_control.items != 0){
|
||||
heap_free(heap, vptr->ui_control.items);
|
||||
}
|
||||
memset(&vptr->transient.ui_control, 0, sizeof(vptr->transient.ui_control));
|
||||
vptr->transient.ui_quit = quit_function;
|
||||
memset(&vptr->ui_control, 0, sizeof(vptr->ui_control));
|
||||
vptr->ui_quit = quit_function;
|
||||
if (control != 0){
|
||||
if (control->count > 0){
|
||||
i32 string_size = 0;
|
||||
|
@ -2202,14 +2209,14 @@ DOC_SEE(UI_Quit_Function_Type)
|
|||
memcpy(new_str, old.str, old.size);
|
||||
}
|
||||
}
|
||||
vptr->transient.ui_control.items = new_items;
|
||||
vptr->transient.ui_control.count = count;
|
||||
vptr->ui_control.items = new_items;
|
||||
vptr->ui_control.count = count;
|
||||
}
|
||||
else{
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
memcpy(vptr->transient.ui_control.bounding_box, control->bounding_box,
|
||||
memcpy(vptr->ui_control.bounding_box, control->bounding_box,
|
||||
sizeof(control->bounding_box));
|
||||
}
|
||||
return(true);
|
||||
|
@ -2230,7 +2237,7 @@ DOC_SEE(view_set_ui)
|
|||
View *vptr = imp_get_view(models, view);
|
||||
UI_Control result = {};
|
||||
if (vptr != 0 && part != 0){
|
||||
UI_Control *control = &vptr->transient.ui_control;
|
||||
UI_Control *control = &vptr->ui_control;
|
||||
result.items = push_array(part, UI_Item, control->count);
|
||||
if (result.items != 0){
|
||||
result.count = control->count;
|
||||
|
@ -2314,7 +2321,7 @@ get_lifetime_object_from_workspace(Dynamic_Workspace *workspace){
|
|||
case DynamicWorkspace_View:
|
||||
{
|
||||
View *vptr = (View*)workspace->user_back_ptr;
|
||||
result = vptr->transient.lifetime_object;
|
||||
result = vptr->lifetime_object;
|
||||
}break;
|
||||
default:
|
||||
{
|
||||
|
@ -2554,7 +2561,7 @@ DOC(Managed objects allocate memory that is tied to the scope. When the scope i
|
|||
Managed_Object result = 0;
|
||||
if (workspace != 0){
|
||||
int32_t size = count*item_size;
|
||||
void *ptr = dynamic_memory_bank_allocate(heap, &workspace->mem_bank, size + sizeof(Managed_Memory_Header));
|
||||
void *ptr = memory_bank_allocate(heap, &workspace->mem_bank, size + sizeof(Managed_Memory_Header));
|
||||
Managed_Memory_Header *header = (Managed_Memory_Header*)ptr;
|
||||
header->std_header.type = ManagedObjectType_Memory;
|
||||
header->std_header.item_size = item_size;
|
||||
|
@ -2591,7 +2598,7 @@ DOC_SEE(Marker)
|
|||
Managed_Object result = 0;
|
||||
if (workspace != 0){
|
||||
i32 size = count*sizeof(Marker);
|
||||
void *ptr = dynamic_memory_bank_allocate(heap, &workspace->mem_bank, size + sizeof(Managed_Buffer_Markers_Header));
|
||||
void *ptr = memory_bank_allocate(heap, &workspace->mem_bank, size + sizeof(Managed_Buffer_Markers_Header));
|
||||
Managed_Buffer_Markers_Header *header = (Managed_Buffer_Markers_Header*)ptr;
|
||||
header->std_header.type = ManagedObjectType_Markers;
|
||||
header->std_header.item_size = sizeof(Marker);
|
||||
|
@ -2935,7 +2942,7 @@ DOC(Permanently frees the specified object. Not only does this free up the memo
|
|||
workspace->buffer_markers_list.count -= 1;
|
||||
}
|
||||
dynamic_workspace_erase_pointer(workspace, lo_id);
|
||||
dynamic_memory_bank_free(&workspace->mem_bank, object_ptr);
|
||||
memory_bank_free(&workspace->mem_bank, object_ptr);
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
|
@ -3078,7 +3085,7 @@ max_result_count of 1 and be assured you will get the most recent bar if any exi
|
|||
Models *models = (Models*)app->cmd_context;
|
||||
View *view = imp_get_view(models, view_id);
|
||||
if (view != 0){
|
||||
for (Query_Slot *slot = view->transient.query_set.used_slot;
|
||||
for (Query_Slot *slot = view->query_set.used_slot;
|
||||
slot != 0 && (result < max_result_count);
|
||||
slot = slot->next){
|
||||
if (slot->query_bar != 0){
|
||||
|
@ -3109,7 +3116,7 @@ only use for this call is in an interactive command that makes calls to get_user
|
|||
Models *models = (Models*)app->cmd_context;
|
||||
Panel *active_panel = layout_get_active_panel(&models->layout);
|
||||
View *active_view = active_panel->view;
|
||||
Query_Slot *slot = alloc_query_slot(&active_view->transient.query_set);
|
||||
Query_Slot *slot = alloc_query_slot(&active_view->query_set);
|
||||
bool32 result = (slot != 0);
|
||||
if (result){
|
||||
slot->query_bar = bar;
|
||||
|
@ -3127,7 +3134,7 @@ DOC(Stops showing the particular query bar specified by the bar parameter.)
|
|||
Models *models = (Models*)app->cmd_context;
|
||||
Panel *active_panel = layout_get_active_panel(&models->layout);
|
||||
View *active_view = active_panel->view;
|
||||
free_query_slot(&active_view->transient.query_set, bar);
|
||||
free_query_slot(&active_view->query_set, bar);
|
||||
}
|
||||
|
||||
API_EXPORT void
|
||||
|
@ -3319,6 +3326,212 @@ DOC_RETURN(Returns true if the given id was a valid face and the change was made
|
|||
return(did_change);
|
||||
}
|
||||
|
||||
API_EXPORT History_Record_Index
|
||||
Buffer_History_Get_Max_Record_Index(Application_Links *app, Buffer_Summary *buffer){
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
Editing_File *file = imp_get_file(models, buffer);
|
||||
History_Record_Index result = 0;
|
||||
if (file != 0 && history_is_activated(&file->state.history)){
|
||||
result = history_get_record_count(&file->state.history);
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
buffer_history__fill_record_info(Record *record, Record_Info *out){
|
||||
out->kind = record->kind;
|
||||
out->edit_number = record->edit_number;
|
||||
switch (out->kind){
|
||||
case RecordKind_Single:
|
||||
{
|
||||
out->single.string_forward = make_string(record->single.str_forward , record->single.length_forward );
|
||||
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;
|
||||
}break;
|
||||
default:
|
||||
{
|
||||
InvalidCodePath;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
API_EXPORT Record_Info
|
||||
Buffer_History_Get_Record_Info(Application_Links *app, Buffer_Summary *buffer, History_Record_Index index){
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
Editing_File *file = imp_get_file(models, buffer);
|
||||
Record_Info result = {};
|
||||
if (file != 0){
|
||||
History *history = &file->state.history;
|
||||
if (history_is_activated(history)){
|
||||
i32 max_index = history_get_record_count(history);
|
||||
if (0 <= index && index <= max_index){
|
||||
if (0 < index){
|
||||
Record *record = history_get_record(history, index);
|
||||
buffer_history__fill_record_info(record, &result);
|
||||
}
|
||||
else{
|
||||
result.error = RecordError_InitialStateDummyRecord;
|
||||
}
|
||||
}
|
||||
else{
|
||||
result.error = RecordError_IndexOutOfBounds;
|
||||
}
|
||||
}
|
||||
else{
|
||||
result.error = RecordError_NoHistoryAttached;
|
||||
}
|
||||
}
|
||||
else{
|
||||
result.error = RecordError_InvalidBuffer;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
API_EXPORT Record_Info
|
||||
Buffer_History_Get_Group_Sub_Record(Application_Links *app, Buffer_Summary *buffer, History_Record_Index index, int32_t sub_index){
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
Editing_File *file = imp_get_file(models, buffer);
|
||||
Record_Info result = {};
|
||||
if (file != 0){
|
||||
History *history = &file->state.history;
|
||||
if (history_is_activated(history)){
|
||||
i32 max_index = history_get_record_count(history);
|
||||
if (0 <= index && index <= max_index){
|
||||
if (0 < index){
|
||||
Record *record = history_get_record(history, index);
|
||||
if (record->kind == RecordKind_Group){
|
||||
record = history_get_sub_record(record, sub_index);
|
||||
buffer_history__fill_record_info(record, &result);
|
||||
}
|
||||
else{
|
||||
result.error = RecordError_WrongRecordTypeAtIndex;
|
||||
}
|
||||
}
|
||||
else{
|
||||
result.error = RecordError_InitialStateDummyRecord;
|
||||
}
|
||||
}
|
||||
else{
|
||||
result.error = RecordError_IndexOutOfBounds;
|
||||
}
|
||||
}
|
||||
else{
|
||||
result.error = RecordError_NoHistoryAttached;
|
||||
}
|
||||
}
|
||||
else{
|
||||
result.error = RecordError_InvalidBuffer;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
API_EXPORT History_Record_Index
|
||||
Buffer_History_Get_Current_State_Index(Application_Links *app, Buffer_Summary *buffer){
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
Editing_File *file = imp_get_file(models, buffer);
|
||||
History_Record_Index result = 0;
|
||||
if (file != 0 && history_is_activated(&file->state.history)){
|
||||
result = file_get_current_record_index(file);
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
API_EXPORT bool32
|
||||
Buffer_History_Set_Current_State_Index(Application_Links *app, Buffer_Summary *buffer, History_Record_Index index){
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
Editing_File *file = imp_get_file(models, buffer);
|
||||
bool32 result = false;
|
||||
if (file != 0 && history_is_activated(&file->state.history)){
|
||||
i32 max_index = history_get_record_count(&file->state.history);
|
||||
if (0 <= index && index <= max_index){
|
||||
System_Functions *system = models->system;
|
||||
edit_change_current_history_state(system, models, file, index);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
API_EXPORT bool32
|
||||
Buffer_History_Merge_Record_Range(Application_Links *app, Buffer_Summary *buffer, History_Record_Index first_index, History_Record_Index last_index, Record_Merge_Flag flags){
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
Editing_File *file = imp_get_file(models, buffer);
|
||||
bool32 result = false;
|
||||
if (file != 0 && history_is_activated(&file->state.history)){
|
||||
History *history = &file->state.history;
|
||||
i32 max_index = history_get_record_count(history);
|
||||
first_index = clamp_bottom(1, first_index);
|
||||
if (first_index <= last_index && last_index <= max_index){
|
||||
i32 current_index = file->state.current_record_index;
|
||||
if (first_index <= current_index && current_index < last_index){
|
||||
System_Functions *system = models->system;
|
||||
u32 in_range_handler = flags & (bit_0 | bit_1);
|
||||
switch (in_range_handler){
|
||||
case RecordMergeFlag_StateInRange_MoveStateForward:
|
||||
{
|
||||
edit_change_current_history_state(system, models, file, last_index);
|
||||
current_index = last_index;
|
||||
}break;
|
||||
|
||||
case RecordMergeFlag_StateInRange_MoveStateBackward:
|
||||
{
|
||||
edit_change_current_history_state(system, models, file, first_index);
|
||||
current_index = first_index;
|
||||
}break;
|
||||
|
||||
case RecordMergeFlag_StateInRange_ErrorOut:
|
||||
{
|
||||
goto done;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
if (first_index < last_index){
|
||||
history_merge_records(&models->mem.part, &models->mem.heap, history, first_index, last_index);
|
||||
}
|
||||
if (current_index >= last_index){
|
||||
current_index -= (last_index - first_index);
|
||||
}
|
||||
file->state.current_record_index = current_index;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
done:;
|
||||
return(result);
|
||||
}
|
||||
|
||||
API_EXPORT bool32
|
||||
Buffer_History_Clear_After_Current_State(Application_Links *app, Buffer_Summary *buffer){
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
Editing_File *file = imp_get_file(models, buffer);
|
||||
bool32 result = false;
|
||||
if (file != 0 && history_is_activated(&file->state.history)){
|
||||
history_dump_records_after_index(&file->state.history, file->state.current_record_index);
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
API_EXPORT void
|
||||
Global_History_Edit_Group_Begin(Application_Links *app){
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
global_history_adjust_edit_grouping_counter(&models->global_history, 1);
|
||||
}
|
||||
|
||||
API_EXPORT void
|
||||
Global_History_Edit_Group_End(Application_Links *app){
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
global_history_adjust_edit_grouping_counter(&models->global_history, -1);
|
||||
}
|
||||
|
||||
internal void
|
||||
font_pointers_to_face_description(Font_Pointers font, Face_Description *description){
|
||||
Font_Metrics *metrics = font.metrics;
|
||||
|
@ -3901,7 +4114,7 @@ Get_Default_Font_For_View(Application_Links *app, View_ID view_id)
|
|||
{
|
||||
Models *models = (Models*)app->cmd_context;
|
||||
View *view = imp_get_view(models, view_id);
|
||||
Editing_File *file = view->transient.file_data.file;
|
||||
Editing_File *file = view->file_data.file;
|
||||
Assert(file != 0);
|
||||
Face_ID face_id = file->settings.font_id;
|
||||
return(face_id);
|
||||
|
|
|
@ -68,6 +68,7 @@ struct Models{
|
|||
Working_Set working_set;
|
||||
Live_Views live_set;
|
||||
Parse_Context_Memory parse_context_memory;
|
||||
Global_History global_history;
|
||||
|
||||
Dynamic_Variable_Layout variable_layout;
|
||||
Dynamic_Workspace dynamic_workspace;
|
||||
|
|
|
@ -44,13 +44,14 @@ struct Mem_Options{
|
|||
#include "4ed_linked_node_macros.h"
|
||||
#include "4ed_log.h"
|
||||
#include "4ed_ptr_check.h"
|
||||
#include "4ed_memory_bank.h"
|
||||
#include "4ed_dynamic_variables.h"
|
||||
|
||||
#include "4ed_buffer_model.h"
|
||||
#include "4ed_translation.h"
|
||||
#include "4ed_command.h"
|
||||
#include "4ed_buffer.h"
|
||||
#include "4ed_undo.h"
|
||||
#include "4ed_history.h"
|
||||
#include "4ed_file.h"
|
||||
#include "4ed_code_wrap.h"
|
||||
|
||||
|
@ -62,11 +63,13 @@ struct Mem_Options{
|
|||
#include "4ed_gui.h"
|
||||
#include "4ed_layout.h"
|
||||
#include "4ed_view.h"
|
||||
#include "4ed_edit.h"
|
||||
#include "4ed_app_models.h"
|
||||
|
||||
#include "4ed_mem.cpp"
|
||||
#include "4ed_hash_functions.cpp"
|
||||
#include "4ed_ptr_check.cpp"
|
||||
#include "4ed_memory_bank.cpp"
|
||||
#include "4ed_dynamic_variables.cpp"
|
||||
#include "4ed_parse_context.cpp"
|
||||
#include "4ed_font.cpp"
|
||||
|
@ -75,7 +78,7 @@ struct Mem_Options{
|
|||
#include "4ed_render_format.cpp"
|
||||
#include "4ed_command.cpp"
|
||||
#include "4ed_buffer.cpp"
|
||||
#include "4ed_undo.cpp"
|
||||
#include "4ed_history.cpp"
|
||||
#include "4ed_file_lex.cpp"
|
||||
#include "4ed_file.cpp"
|
||||
#include "4ed_code_wrap.cpp"
|
||||
|
|
102
4ed_buffer.cpp
102
4ed_buffer.cpp
|
@ -112,71 +112,66 @@ buffer_batch_debug_sort_check(Buffer_Edit *sorted_edits, i32 edit_count){
|
|||
return(result);
|
||||
}
|
||||
|
||||
internal i32
|
||||
buffer_batch_edit_max_shift(Buffer_Edit *sorted_edits, i32 edit_count){
|
||||
i32 i = 0;
|
||||
i32 shift_total = 0, shift_max = 0;
|
||||
|
||||
Buffer_Edit *edit = sorted_edits;
|
||||
for (i = 0; i < edit_count; ++i, ++edit){
|
||||
shift_total += (edit->len - (edit->end - edit->start));
|
||||
if (shift_total > shift_max){
|
||||
shift_max = shift_total;
|
||||
}
|
||||
}
|
||||
|
||||
return(shift_max);
|
||||
}
|
||||
// TODO(allen): This now relies on Edit and Edit_Array from 4ed_edit.h even though we sort of think of that
|
||||
// as cheating... gotta rethink the separation of buffer from everything else moving forward or something.
|
||||
|
||||
internal i32
|
||||
buffer_batch_edit_update_cursors(Cursor_With_Index *sorted_positions, i32 count, Buffer_Edit *sorted_edits, i32 edit_count, b32 lean_right){
|
||||
buffer_batch_edit_update_cursors(Cursor_With_Index *sorted_positions, i32 count, Edit_Array sorted_edits, b32 lean_right){
|
||||
Cursor_With_Index *position = sorted_positions;
|
||||
Cursor_With_Index *end_position = sorted_positions + count;
|
||||
Buffer_Edit *edit = sorted_edits;
|
||||
Buffer_Edit *end_edit = sorted_edits + edit_count;
|
||||
i32 shift_amount = 0;
|
||||
Cursor_With_Index *one_past_last_position = sorted_positions + count;
|
||||
Edit *edit = sorted_edits.vals;
|
||||
Edit *one_past_last_edit = sorted_edits.vals + sorted_edits.count;
|
||||
|
||||
i32 shift_amount = 0;
|
||||
if (lean_right){
|
||||
for (; edit < end_edit && position < end_position; ++edit){
|
||||
i32 start = edit->start;
|
||||
i32 end = edit->end;
|
||||
for (;edit < one_past_last_edit && position < one_past_last_position;
|
||||
++edit){
|
||||
i32 start = edit->range.first;
|
||||
i32 end = edit->range.one_past_last;
|
||||
|
||||
for (; position->pos < start && position < end_position; ++position){
|
||||
for (;position->pos < start && position < one_past_last_position;
|
||||
++position){
|
||||
position->pos += shift_amount;
|
||||
}
|
||||
|
||||
i32 new_end = start + edit->len + shift_amount;
|
||||
for (; position->pos <= end && position < end_position; ++position){
|
||||
i32 new_end = start + edit->length + shift_amount;
|
||||
for (;position->pos <= end && position < one_past_last_position;
|
||||
++position){
|
||||
position->pos = new_end;
|
||||
}
|
||||
|
||||
shift_amount += (edit->len - (end - start));
|
||||
shift_amount += (edit->length - (end - start));
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (; edit < end_edit && position < end_position; ++edit){
|
||||
i32 start = edit->start;
|
||||
i32 end = edit->end;
|
||||
for (;edit < one_past_last_edit && position < one_past_last_position;
|
||||
++edit){
|
||||
i32 start = edit->range.first;
|
||||
i32 end = edit->range.one_past_last;
|
||||
|
||||
for (; position->pos < start && position < end_position; ++position){
|
||||
for (;position->pos < start && position < one_past_last_position;
|
||||
++position){
|
||||
position->pos += shift_amount;
|
||||
}
|
||||
|
||||
i32 new_end = start + shift_amount;
|
||||
for (; position->pos <= end && position < end_position; ++position){
|
||||
for (;position->pos <= end && position < one_past_last_position;
|
||||
++position){
|
||||
position->pos = new_end;
|
||||
}
|
||||
|
||||
shift_amount += (edit->len - (end - start));
|
||||
shift_amount += (edit->length - (end - start));
|
||||
}
|
||||
}
|
||||
|
||||
for (; position < end_position; ++position){
|
||||
for (;position < one_past_last_position;
|
||||
++position){
|
||||
position->pos += shift_amount;
|
||||
}
|
||||
|
||||
for (; edit < end_edit; ++edit){
|
||||
shift_amount += (edit->len - (edit->end - edit->start));
|
||||
for (;edit < one_past_last_edit;
|
||||
++edit){
|
||||
shift_amount += (edit->length - (edit->range.one_past_last - edit->range.first));
|
||||
}
|
||||
|
||||
return(shift_amount);
|
||||
|
@ -471,21 +466,25 @@ buffer_replace_range(Gap_Buffer *buffer, i32 start, i32 end, char *str, i32 len,
|
|||
// TODO(allen): do(optimize Gap_Buffer batch edit)
|
||||
// Now that we are just using Gap_Buffer we could afford to improve
|
||||
// this for the Gap_Buffer's behavior.
|
||||
internal i32
|
||||
buffer_batch_edit_step(Buffer_Batch_State *state, Gap_Buffer *buffer, Buffer_Edit *sorted_edits, char *strings, i32 edit_count,
|
||||
void *scratch, i32 scratch_size, i32 *request_amount){
|
||||
Buffer_Edit *edit = 0;
|
||||
i32 shift_total = state->shift_total;
|
||||
i32 result = 0;
|
||||
|
||||
// TODO(allen): This now relies on Edit and Edit_Array from 4ed_edit.h even though we sort of think of that
|
||||
// as cheating... gotta rethink the separation of buffer from everything else moving forward or something.
|
||||
|
||||
internal b32
|
||||
buffer_batch_edit_step(Buffer_Batch_State *state, Gap_Buffer *buffer, Edit_Array sorted_edits, void *scratch, i32 scratch_size, i32 *request_amount){
|
||||
b32 result = false;
|
||||
|
||||
i32 shift_total = state->shift_total;
|
||||
i32 i = state->i;
|
||||
edit = sorted_edits + i;
|
||||
for (; i < edit_count; ++i, ++edit){
|
||||
i32 start = edit->start + shift_total;
|
||||
i32 end = edit->end + shift_total;
|
||||
i32 len = edit->len;
|
||||
i32 shift_amount = buffer_replace_range_compute_shift(start, end, len);
|
||||
result = buffer_replace_range(buffer, start, end, strings + edit->str_start, len, shift_amount, scratch, scratch_size, request_amount);
|
||||
|
||||
Edit *edit = sorted_edits.vals + i;
|
||||
for (; i < sorted_edits.count; ++i, ++edit){
|
||||
char *str = edit->str;
|
||||
i32 length = edit->length;
|
||||
i32 start = edit->range.first + shift_total;
|
||||
i32 end = edit->range.one_past_last + shift_total;
|
||||
i32 shift_amount = buffer_replace_range_compute_shift(start, end, length);
|
||||
result = buffer_replace_range(buffer, start, end, str, length, shift_amount, scratch, scratch_size, request_amount);
|
||||
if (result){
|
||||
break;
|
||||
}
|
||||
|
@ -553,6 +552,11 @@ buffer_stringify(Gap_Buffer *buffer, i32 start, i32 end, char *out){
|
|||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
buffer_stringify_range(Gap_Buffer *buffer, Range range, char *out){
|
||||
buffer_stringify(buffer, range.first, range.one_past_last, out);
|
||||
}
|
||||
|
||||
internal i32
|
||||
buffer_convert_out(Gap_Buffer *buffer, char *dest, i32 max){
|
||||
Gap_Buffer_Stream stream = {};
|
||||
|
|
|
@ -88,7 +88,7 @@ map_hash(Key_Code event_code, u8 modifiers){
|
|||
}
|
||||
|
||||
internal b32
|
||||
map_add(Command_Map *map, Key_Code event_code, u8 modifiers, Command_Function *function, Custom_Command_Function *custom){
|
||||
map_add(Command_Map *map, Key_Code event_code, u8 modifiers, Custom_Command_Function *custom){
|
||||
b32 result = false;
|
||||
Assert(map->count * 8 < map->max * 7);
|
||||
u64 hash = map_hash(event_code, modifiers);
|
||||
|
@ -96,7 +96,7 @@ map_add(Command_Map *map, Key_Code event_code, u8 modifiers, Command_Function *f
|
|||
u32 max = map->max;
|
||||
u32 index = hash % max;
|
||||
Command_Binding entry = map->commands[index];
|
||||
for (; entry.function != 0 && entry.hash != COMMAND_HASH_ERASED;){
|
||||
for (; entry.custom != 0 && entry.hash != COMMAND_HASH_ERASED;){
|
||||
if (entry.hash == hash){
|
||||
result = true;
|
||||
break;
|
||||
|
@ -106,7 +106,6 @@ map_add(Command_Map *map, Key_Code event_code, u8 modifiers, Command_Function *f
|
|||
}
|
||||
|
||||
Command_Binding bind = {};
|
||||
bind.function = function;
|
||||
bind.custom = custom;
|
||||
bind.hash = hash;
|
||||
map->commands[index] = bind;
|
||||
|
@ -117,11 +116,6 @@ map_add(Command_Map *map, Key_Code event_code, u8 modifiers, Command_Function *f
|
|||
return(result);
|
||||
}
|
||||
|
||||
internal b32
|
||||
map_add(Command_Map *map, Key_Code event_code, u8 modifiers, Command_Function *function, u64 custom_id){
|
||||
return(map_add(map, event_code, modifiers, function, (Custom_Command_Function*)custom_id));
|
||||
}
|
||||
|
||||
internal b32
|
||||
map_find_entry(Command_Map *map, Key_Code event_code, u8 modifiers, u32 *index_out){
|
||||
u64 hash = map_hash(event_code, modifiers);
|
||||
|
@ -129,7 +123,7 @@ map_find_entry(Command_Map *map, Key_Code event_code, u8 modifiers, u32 *index_o
|
|||
u32 index = hash % max;
|
||||
b32 result = false;
|
||||
Command_Binding entry = map->commands[index];
|
||||
for (; entry.function != 0;){
|
||||
for (; entry.custom != 0;){
|
||||
if (entry.hash == hash){
|
||||
*index_out = index;
|
||||
result = true;
|
||||
|
@ -156,7 +150,7 @@ map_drop(Command_Map *map, Key_Code event_code, u8 modifiers){
|
|||
u32 index = 0;
|
||||
b32 result = map_find_entry(map, event_code, modifiers, &index);
|
||||
if (result){
|
||||
map->commands[index].function = 0;
|
||||
map->commands[index].custom = 0;
|
||||
map->commands[index].hash = COMMAND_HASH_ERASED;
|
||||
}
|
||||
return(result);
|
||||
|
@ -228,7 +222,7 @@ map_extract(Command_Map *map, Key_Event_Data key){
|
|||
mod_flags &= ~(MDFR_SHIFT);
|
||||
}
|
||||
map_find(map, code, mod_flags, &bind);
|
||||
if (bind.function == 0){
|
||||
if (bind.custom == 0){
|
||||
map_get_vanilla_keyboard_default(map, mod_flags, &bind);
|
||||
}
|
||||
}
|
||||
|
@ -249,7 +243,7 @@ map_extract_recursive(Mapping *mapping, i32 map_id, Key_Event_Data key){
|
|||
Command_Binding cmd_bind = {};
|
||||
for (; map != 0; ){
|
||||
cmd_bind = map_extract(map, key);
|
||||
if (cmd_bind.function == 0){
|
||||
if (cmd_bind.custom == 0){
|
||||
if (visited_top < ArrayCount(visited_maps)){
|
||||
visited_maps[visited_top++] = map;
|
||||
map = get_map(mapping, map->parent);
|
||||
|
|
|
@ -12,17 +12,8 @@
|
|||
#if !defined(FRED_COMMAND_H)
|
||||
#define FRED_COMMAND_H
|
||||
|
||||
#define Command_Function_Sig(name) \
|
||||
void (name)(System_Functions *system, struct Models *models, struct Command_Binding binding)
|
||||
|
||||
typedef Command_Function_Sig(Command_Function);
|
||||
|
||||
struct Command_Binding{
|
||||
Command_Function *function;
|
||||
union{
|
||||
Custom_Command_Function *custom;
|
||||
u64 custom_id;
|
||||
};
|
||||
Custom_Command_Function *custom;
|
||||
u64 hash;
|
||||
};
|
||||
|
||||
|
|
|
@ -66,49 +66,6 @@ dynamic_variables_create(Heap *heap, Dynamic_Variable_Layout *layout, String nam
|
|||
|
||||
////////////////////////////////
|
||||
|
||||
internal void
|
||||
dynamic_memory_bank_init(Heap *heap, Dynamic_Memory_Bank *mem_bank){
|
||||
heap_init(&mem_bank->heap);
|
||||
mem_bank->first = 0;
|
||||
mem_bank->last = 0;
|
||||
mem_bank->total_memory_size = 0;
|
||||
}
|
||||
|
||||
internal void*
|
||||
dynamic_memory_bank_allocate(Heap *heap, Dynamic_Memory_Bank *mem_bank, i32 size){
|
||||
void *ptr = heap_allocate(&mem_bank->heap, size);
|
||||
if (ptr == 0){
|
||||
i32 alloc_size = clamp_bottom(4096, size*4 + sizeof(Dynamic_Memory_Header));
|
||||
void *new_block = heap_allocate(heap, alloc_size);
|
||||
if (new_block != 0){
|
||||
Dynamic_Memory_Header *header = (Dynamic_Memory_Header*)new_block;
|
||||
sll_push(mem_bank->first, mem_bank->last, header);
|
||||
mem_bank->total_memory_size += alloc_size;
|
||||
heap_extend(&mem_bank->heap, header + 1, alloc_size - sizeof(*header));
|
||||
ptr = heap_allocate(&mem_bank->heap, size);
|
||||
}
|
||||
}
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
internal void
|
||||
dynamic_memory_bank_free(Dynamic_Memory_Bank *mem_bank, void *ptr){
|
||||
heap_free(&mem_bank->heap, ptr);
|
||||
}
|
||||
|
||||
internal void
|
||||
dynamic_memory_bank_free_all(Heap *heap, Dynamic_Memory_Bank *mem_bank){
|
||||
for (Dynamic_Memory_Header *header = mem_bank->first, *next = 0;
|
||||
header != 0;
|
||||
header = next){
|
||||
next = header->next;
|
||||
heap_free(heap, header);
|
||||
}
|
||||
mem_bank->total_memory_size = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal void
|
||||
dynamic_variables_block_init(Dynamic_Variable_Block *block){
|
||||
block->val_array = 0;
|
||||
|
@ -117,12 +74,12 @@ dynamic_variables_block_init(Dynamic_Variable_Block *block){
|
|||
}
|
||||
|
||||
internal void
|
||||
dynamic_variables_block_grow_max_to(Heap *heap, Dynamic_Memory_Bank *mem_bank, i32 new_max, Dynamic_Variable_Block *block){
|
||||
dynamic_variables_block_grow_max_to(Heap *heap, Memory_Bank *mem_bank, i32 new_max, Dynamic_Variable_Block *block){
|
||||
i32 new_size = new_max*sizeof(u64);
|
||||
u64 *new_array = (u64*)dynamic_memory_bank_allocate(heap, mem_bank, new_size);
|
||||
u64 *new_array = (u64*)memory_bank_allocate(heap, mem_bank, new_size);
|
||||
if (block->val_array != 0){
|
||||
memcpy(new_array, block->val_array, sizeof(u64)*block->count);
|
||||
dynamic_memory_bank_free(mem_bank, block->val_array);
|
||||
memory_bank_free(mem_bank, block->val_array);
|
||||
}
|
||||
block->val_array = new_array;
|
||||
}
|
||||
|
@ -142,7 +99,7 @@ dynamic_variables_block_fill_unset_values(Dynamic_Variable_Layout *layout, Dynam
|
|||
}
|
||||
|
||||
internal b32
|
||||
dynamic_variables_get_ptr(Heap *heap, Dynamic_Memory_Bank *mem_bank,
|
||||
dynamic_variables_get_ptr(Heap *heap, Memory_Bank *mem_bank,
|
||||
Dynamic_Variable_Layout *layout, Dynamic_Variable_Block *block,
|
||||
i32 location, u64 **ptr_out){
|
||||
b32 result = false;
|
||||
|
@ -164,17 +121,17 @@ dynamic_variables_get_ptr(Heap *heap, Dynamic_Memory_Bank *mem_bank,
|
|||
////////////////////////////////
|
||||
|
||||
internal void
|
||||
insert_u32_Ptr_table(Heap *heap, Dynamic_Memory_Bank *mem_bank, u32_Ptr_Table *table, u32 key, void* val){
|
||||
insert_u32_Ptr_table(Heap *heap, Memory_Bank *mem_bank, u32_Ptr_Table *table, u32 key, void* val){
|
||||
if (at_max_u32_Ptr_table(table)){
|
||||
i32 new_max = (table->max + 1)*2;
|
||||
i32 new_mem_size = max_to_memsize_u32_Ptr_table(new_max);
|
||||
void *new_mem = dynamic_memory_bank_allocate(heap, mem_bank, new_mem_size);
|
||||
void *new_mem = memory_bank_allocate(heap, mem_bank, new_mem_size);
|
||||
u32_Ptr_Table new_table = make_u32_Ptr_table(new_mem, new_mem_size);
|
||||
if (table->mem != 0){
|
||||
b32 result = move_u32_Ptr_table(&new_table, table);
|
||||
Assert(result);
|
||||
AllowLocal(result);
|
||||
dynamic_memory_bank_free(mem_bank, table->mem);
|
||||
memory_bank_free(mem_bank, table->mem);
|
||||
}
|
||||
*table = new_table;
|
||||
}
|
||||
|
@ -191,12 +148,12 @@ marker_visual_allocator_init(Marker_Visual_Allocator *allocator){
|
|||
}
|
||||
|
||||
internal Marker_Visual_Data*
|
||||
dynamic_workspace_alloc_visual(Heap *heap, Dynamic_Memory_Bank *mem_bank, Dynamic_Workspace *workspace){
|
||||
dynamic_workspace_alloc_visual(Heap *heap, Memory_Bank *mem_bank, Dynamic_Workspace *workspace){
|
||||
Marker_Visual_Allocator *allocator = &workspace->visual_allocator;
|
||||
if (allocator->free_count == 0){
|
||||
i32 new_slots_count = clamp_bottom(16, allocator->total_visual_count);
|
||||
i32 memsize = new_slots_count*sizeof(Marker_Visual_Data);
|
||||
void *new_slots_memory = dynamic_memory_bank_allocate(heap, mem_bank, memsize);
|
||||
void *new_slots_memory = memory_bank_allocate(heap, mem_bank, memsize);
|
||||
memset(new_slots_memory, 0, memsize);
|
||||
Marker_Visual_Data *new_slot = (Marker_Visual_Data*)new_slots_memory;
|
||||
allocator->free_count += new_slots_count;
|
||||
|
@ -254,7 +211,7 @@ marker_visual_defaults(Marker_Visual_Data *data){
|
|||
internal void
|
||||
dynamic_workspace_init(Heap *heap, Lifetime_Allocator *lifetime_allocator, i32 user_type, void *user_back_ptr, Dynamic_Workspace *workspace){
|
||||
memset(workspace, 0, sizeof(*workspace));
|
||||
dynamic_memory_bank_init(heap, &workspace->mem_bank);
|
||||
memory_bank_init(&workspace->mem_bank);
|
||||
dynamic_variables_block_init(&workspace->var_block);
|
||||
marker_visual_allocator_init(&workspace->visual_allocator);
|
||||
if (lifetime_allocator->scope_id_counter == 0){
|
||||
|
@ -269,13 +226,13 @@ dynamic_workspace_init(Heap *heap, Lifetime_Allocator *lifetime_allocator, i32 u
|
|||
internal void
|
||||
dynamic_workspace_free(Heap *heap, Lifetime_Allocator *lifetime_allocator, Dynamic_Workspace *workspace){
|
||||
erase_u32_Ptr_table(&lifetime_allocator->scope_id_to_scope_ptr_table, workspace->scope_id);
|
||||
dynamic_memory_bank_free_all(heap, &workspace->mem_bank);
|
||||
memory_bank_free_all(heap, &workspace->mem_bank);
|
||||
}
|
||||
|
||||
internal void
|
||||
dynamic_workspace_clear_contents(Heap *heap, Dynamic_Workspace *workspace){
|
||||
dynamic_memory_bank_free_all(heap, &workspace->mem_bank);
|
||||
dynamic_memory_bank_init(heap, &workspace->mem_bank);
|
||||
memory_bank_free_all(heap, &workspace->mem_bank);
|
||||
memory_bank_init(&workspace->mem_bank);
|
||||
|
||||
dynamic_variables_block_init(&workspace->var_block);
|
||||
marker_visual_allocator_init(&workspace->visual_allocator);
|
||||
|
|
|
@ -98,22 +98,9 @@ struct Dynamic_Variable_Block{
|
|||
|
||||
////////////////////////////////
|
||||
|
||||
struct Dynamic_Memory_Header{
|
||||
Dynamic_Memory_Header *next;
|
||||
};
|
||||
|
||||
struct Dynamic_Memory_Bank{
|
||||
Heap heap;
|
||||
Dynamic_Memory_Header *first;
|
||||
Dynamic_Memory_Header *last;
|
||||
umem total_memory_size;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
struct Dynamic_Workspace{
|
||||
Dynamic_Variable_Block var_block;
|
||||
Dynamic_Memory_Bank mem_bank;
|
||||
Memory_Bank mem_bank;
|
||||
Marker_Visual_Allocator visual_allocator;
|
||||
u32_Ptr_Table object_id_to_object_ptr;
|
||||
u32 object_id_counter;
|
||||
|
|
446
4ed_edit.cpp
446
4ed_edit.cpp
|
@ -23,6 +23,18 @@ edit_pre_state_change(System_Functions *system, Heap *heap, Models *models, Edit
|
|||
file_set_dirty_flag(file, DirtyState_UnsavedChanges);
|
||||
}
|
||||
file_unmark_edit_finished(file);
|
||||
Layout *layout = &models->layout;
|
||||
for (Panel *panel = layout_get_first_open_panel(layout);
|
||||
panel != 0;
|
||||
panel = layout_get_next_open_panel(layout, panel)){
|
||||
View *view = panel->view;
|
||||
if (view->file_data.file == file){
|
||||
Full_Cursor render_cursor = view_get_render_cursor(system, view);
|
||||
Full_Cursor target_cursor = view_get_render_cursor_target(system, view);
|
||||
view->temp_view_top_left_pos = render_cursor.pos;
|
||||
view->temp_view_top_left_target_pos = target_cursor.pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -32,7 +44,6 @@ edit_fix_markers__write_workspace_markers(Dynamic_Workspace *workspace, Buffer_I
|
|||
node != 0;
|
||||
node = node->next){
|
||||
if (node->buffer_id != buffer_id) continue;
|
||||
|
||||
Marker *markers = (Marker*)(node + 1);
|
||||
Assert(sizeof(*markers) == node->std_header.item_size);
|
||||
i32 count = node->std_header.count;
|
||||
|
@ -54,7 +65,6 @@ edit_fix_markers__read_workspace_markers(Dynamic_Workspace *workspace, Buffer_ID
|
|||
node != 0;
|
||||
node = node->next){
|
||||
if (node->buffer_id != buffer_id) continue;
|
||||
|
||||
Marker *markers = (Marker*)(node + 1);
|
||||
Assert(sizeof(*markers) == node->std_header.item_size);
|
||||
i32 count = node->std_header.count;
|
||||
|
@ -69,9 +79,24 @@ edit_fix_markers__read_workspace_markers(Dynamic_Workspace *workspace, Buffer_ID
|
|||
}
|
||||
}
|
||||
|
||||
internal f32
|
||||
edit_fix_markers__compute_scroll_y(i32 line_height, f32 old_y_val, f32 new_y_val_aligned){
|
||||
f32 y_offset = MOD(old_y_val, line_height);
|
||||
f32 y_position = new_y_val_aligned + y_offset;
|
||||
return(y_position);
|
||||
}
|
||||
|
||||
internal i32
|
||||
edit_fix_markers__compute_scroll_y(i32 line_height, i32 old_y_val, f32 new_y_val_aligned){
|
||||
return((i32)edit_fix_markers__compute_scroll_y(line_height, (f32)old_y_val, new_y_val_aligned));
|
||||
}
|
||||
|
||||
internal void
|
||||
edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, Layout *layout, Cursor_Fix_Descriptor desc){
|
||||
edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, Edit_Array edits){
|
||||
Assert(edits.count > 0);
|
||||
|
||||
Partition *part = &models->mem.part;
|
||||
Layout *layout = &models->layout;
|
||||
|
||||
Temp_Memory cursor_temp = begin_temp_memory(part);
|
||||
|
||||
|
@ -79,7 +104,7 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, L
|
|||
Buffer_ID file_id = file->id.id;
|
||||
Assert(file_lifetime_object != 0);
|
||||
|
||||
i32 cursor_max = layout_get_open_panel_count(layout)*3;
|
||||
i32 cursor_max = layout_get_open_panel_count(layout)*4;
|
||||
i32 total_marker_count = 0;
|
||||
{
|
||||
total_marker_count += file_lifetime_object->workspace.total_marker_count;
|
||||
|
@ -110,10 +135,12 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, L
|
|||
panel != 0;
|
||||
panel = layout_get_next_open_panel(layout, panel)){
|
||||
View *view = panel->view;
|
||||
if (view->transient.file_data.file == file){
|
||||
write_cursor_with_index(cursors, &cursor_count, view->transient.edit_pos.cursor.pos);
|
||||
write_cursor_with_index(cursors, &cursor_count, view->transient.edit_pos.mark);
|
||||
write_cursor_with_index(cursors, &cursor_count, view->transient.edit_pos.scroll_i);
|
||||
if (view->file_data.file == file){
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
||||
write_cursor_with_index(cursors, &cursor_count, edit_pos.cursor_pos);
|
||||
write_cursor_with_index(cursors, &cursor_count, view->mark);
|
||||
write_cursor_with_index(cursors, &cursor_count, view->temp_view_top_left_pos);
|
||||
write_cursor_with_index(cursors, &cursor_count, view->temp_view_top_left_target_pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,13 +163,14 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, L
|
|||
|
||||
if (cursor_count > 0 || r_cursor_count > 0){
|
||||
buffer_sort_cursors(cursors, cursor_count);
|
||||
if (desc.is_batch){
|
||||
buffer_batch_edit_update_cursors(cursors, cursor_count, desc.batch, desc.batch_size, false);
|
||||
buffer_batch_edit_update_cursors(r_cursors, r_cursor_count, desc.batch, desc.batch_size, true);
|
||||
if (edits.count > 1){
|
||||
buffer_batch_edit_update_cursors( cursors, cursor_count, edits, false);
|
||||
buffer_batch_edit_update_cursors(r_cursors, r_cursor_count, edits, true);
|
||||
}
|
||||
else{
|
||||
buffer_update_cursors(cursors, cursor_count, desc.start, desc.end, desc.shift_amount + (desc.end - desc.start), false);
|
||||
buffer_update_cursors(r_cursors, r_cursor_count, desc.start, desc.end, desc.shift_amount + (desc.end - desc.start), true);
|
||||
Edit edit = edits.vals[0];
|
||||
buffer_update_cursors( cursors, cursor_count, edit.range.first, edit.range.one_past_last, edit.length, false);
|
||||
buffer_update_cursors(r_cursors, r_cursor_count, edit.range.first, edit.range.one_past_last, edit.length, true);
|
||||
}
|
||||
buffer_unsort_cursors(cursors, cursor_count);
|
||||
|
||||
|
@ -152,31 +180,42 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, L
|
|||
panel != 0;
|
||||
panel = layout_get_next_open_panel(layout, panel)){
|
||||
View *view = panel->view;
|
||||
if (view->transient.file_data.file == file){
|
||||
if (view->file_data.file == file){
|
||||
i32 cursor_pos = cursors[cursor_count++].pos;
|
||||
Full_Cursor new_cursor = file_compute_cursor(system, file, seek_pos(cursor_pos), 0);
|
||||
Full_Cursor new_cursor = file_compute_cursor(system, file, seek_pos(cursor_pos));
|
||||
|
||||
GUI_Scroll_Vars scroll = view->transient.edit_pos.scroll;
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
||||
GUI_Scroll_Vars scroll = edit_pos.scroll;
|
||||
|
||||
view->transient.edit_pos.mark = cursors[cursor_count++].pos;
|
||||
i32 new_scroll_i = cursors[cursor_count++].pos;
|
||||
if (view->transient.edit_pos.scroll_i != new_scroll_i){
|
||||
view->transient.edit_pos.scroll_i = new_scroll_i;
|
||||
|
||||
Full_Cursor temp_cursor = file_compute_cursor(system, file, seek_pos(view->transient.edit_pos.scroll_i), 0);
|
||||
|
||||
f32 y_offset = MOD(view->transient.edit_pos.scroll.scroll_y, view->transient.line_height);
|
||||
f32 y_position = temp_cursor.wrapped_y;
|
||||
view->mark = cursors[cursor_count++].pos;
|
||||
i32 line_height = view->line_height;
|
||||
i32 top_left_pos = cursors[cursor_count++].pos;
|
||||
i32 top_left_target_pos = cursors[cursor_count++].pos;
|
||||
f32 new_y_val_aligned = 0;
|
||||
if (view->temp_view_top_left_pos != top_left_pos){
|
||||
Full_Cursor new_position_cursor = file_compute_cursor(system, file, seek_pos(top_left_pos));
|
||||
if (file->settings.unwrapped_lines){
|
||||
y_position = temp_cursor.unwrapped_y;
|
||||
new_y_val_aligned = new_position_cursor.unwrapped_y;
|
||||
}
|
||||
y_position += y_offset;
|
||||
|
||||
scroll.target_y += round32(y_position - scroll.scroll_y);
|
||||
scroll.scroll_y = y_position;
|
||||
else{
|
||||
new_y_val_aligned = new_position_cursor.wrapped_y;
|
||||
}
|
||||
scroll.scroll_y = edit_fix_markers__compute_scroll_y(line_height, scroll.scroll_y, new_y_val_aligned);
|
||||
}
|
||||
if (view->temp_view_top_left_target_pos != top_left_target_pos){
|
||||
if (top_left_target_pos != top_left_pos){
|
||||
Full_Cursor new_position_cursor = file_compute_cursor(system, file, seek_pos(top_left_target_pos));
|
||||
if (file->settings.unwrapped_lines){
|
||||
new_y_val_aligned = new_position_cursor.unwrapped_y;
|
||||
}
|
||||
else{
|
||||
new_y_val_aligned = new_position_cursor.wrapped_y;
|
||||
}
|
||||
}
|
||||
scroll.target_y = edit_fix_markers__compute_scroll_y(line_height, scroll.target_y, new_y_val_aligned);
|
||||
}
|
||||
|
||||
view_set_cursor_and_scroll(view, new_cursor, 1, view->transient.file_data.file->settings.unwrapped_lines, scroll);
|
||||
view_set_cursor_and_scroll(view, new_cursor, true, scroll);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,52 +239,58 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, L
|
|||
}
|
||||
|
||||
internal void
|
||||
edit_single__inner(System_Functions *system, Models *models, Editing_File *file, Edit_Spec spec, History_Mode history_mode){
|
||||
edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, Edit edit){
|
||||
Edit_Array edits = {};
|
||||
edits.vals = &edit;
|
||||
edits.count = 1;
|
||||
edit_fix_markers(system, models, file, edits);
|
||||
}
|
||||
|
||||
internal void
|
||||
edit_single(System_Functions *system, Models *models, Editing_File *file, Edit edit, Edit_Behaviors behaviors){
|
||||
Mem_Options *mem = &models->mem;
|
||||
Layout *layout = &models->layout;
|
||||
Heap *heap = &mem->heap;
|
||||
Partition *part = &mem->part;
|
||||
|
||||
Gap_Buffer *buffer = &file->state.buffer;
|
||||
Assert(0 <= edit.range.first);
|
||||
Assert(edit.range.first <= edit.range.one_past_last);
|
||||
Assert(edit.range.one_past_last <= buffer_size(buffer));
|
||||
|
||||
// NOTE(allen): history update
|
||||
if (!behaviors.do_not_post_to_history){
|
||||
history_dump_records_after_index(&file->state.history, file->state.current_record_index);
|
||||
history_record_edit(heap, &models->global_history, &file->state.history, buffer, edit);
|
||||
file->state.current_record_index = history_get_record_count(&file->state.history);
|
||||
}
|
||||
|
||||
// NOTE(allen): fixing stuff beforewards????
|
||||
file_update_history_before_edit(mem, file, spec.step, spec.str, history_mode);
|
||||
edit_pre_state_change(system, &mem->heap, models, file);
|
||||
|
||||
// NOTE(allen): expand spec, compute shift
|
||||
char *str = (char*)spec.str;
|
||||
i32 start = spec.step.edit.start;
|
||||
i32 end = spec.step.edit.end;
|
||||
i32 str_len = spec.step.edit.len;
|
||||
i32 shift_amount = buffer_replace_range_compute_shift(start, end, str_len);
|
||||
|
||||
// NOTE(allen): cursor fixing
|
||||
Cursor_Fix_Descriptor desc = {};
|
||||
desc.start = start;
|
||||
desc.end = end;
|
||||
desc.shift_amount = shift_amount;
|
||||
edit_fix_markers(system, models, file, layout, desc);
|
||||
i32 shift_amount = buffer_replace_range_compute_shift(edit.range.first, edit.range.one_past_last, edit.length);
|
||||
|
||||
// NOTE(allen): actual text replacement
|
||||
i32 scratch_size = part_remaining(part);
|
||||
Assert(scratch_size > 0);
|
||||
i32 request_amount = 0;
|
||||
Assert(end <= buffer_size(&file->state.buffer));
|
||||
for (;buffer_replace_range(&file->state.buffer, start, end, str, str_len, shift_amount, part->base + part->pos, scratch_size, &request_amount);){
|
||||
for (;buffer_replace_range(buffer, edit.range.first, edit.range.one_past_last, edit.str, edit.length,
|
||||
shift_amount, part->base + part->pos, scratch_size, &request_amount);){
|
||||
void *new_data = 0;
|
||||
if (request_amount > 0){
|
||||
new_data = heap_allocate(heap, request_amount);
|
||||
}
|
||||
void *old_data = buffer_edit_provide_memory(&file->state.buffer, new_data, request_amount);
|
||||
void *old_data = buffer_edit_provide_memory(buffer, new_data, request_amount);
|
||||
if (old_data){
|
||||
heap_free(heap, old_data);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(allen): line meta data
|
||||
Gap_Buffer *buffer = &file->state.buffer;
|
||||
i32 line_start = buffer_get_line_number(&file->state.buffer, start);
|
||||
i32 line_end = buffer_get_line_number(&file->state.buffer, end);
|
||||
i32 line_start = buffer_get_line_number(buffer, edit.range.first);
|
||||
i32 line_end = buffer_get_line_number(buffer, edit.range.one_past_last);
|
||||
i32 replaced_line_count = line_end - line_start;
|
||||
i32 new_line_count = buffer_count_newlines(&file->state.buffer, start, start+str_len);
|
||||
i32 new_line_count = buffer_count_newlines(buffer, edit.range.first, edit.range.first + edit.length);
|
||||
i32 line_shift = new_line_count - replaced_line_count;
|
||||
|
||||
Font_Pointers font = system->font.get_pointers_by_id(file->settings.font_id);
|
||||
|
@ -259,9 +304,15 @@ edit_single__inner(System_Functions *system, Models *models, Editing_File *file,
|
|||
|
||||
// NOTE(allen): token fixing
|
||||
if (file->settings.tokens_exist){
|
||||
file_relex(system, models, file, start, end, shift_amount);
|
||||
file_relex(system, models, file, edit.range.first, edit.range.one_past_last, shift_amount);
|
||||
}
|
||||
|
||||
// NOTE(allen): wrap meta data
|
||||
file_measure_wraps(system, &models->mem, file, font);
|
||||
|
||||
// NOTE(allen): cursor fixing
|
||||
edit_fix_markers(system, models, file, edit);
|
||||
|
||||
// NOTE(allen): mark edit finished
|
||||
if (file->settings.tokens_exist){
|
||||
if (file->settings.virtual_white){
|
||||
|
@ -271,80 +322,33 @@ edit_single__inner(System_Functions *system, Models *models, Editing_File *file,
|
|||
else{
|
||||
file_mark_edit_finished(&models->working_set, file);
|
||||
}
|
||||
|
||||
// NOTE(allen): wrap meta data
|
||||
file_measure_wraps(system, &models->mem, file, font);
|
||||
}
|
||||
|
||||
internal void
|
||||
edit_single(System_Functions *system, Models *models, Editing_File *file,
|
||||
i32 start, i32 end, char *str, i32 len){
|
||||
Edit_Spec spec = {};
|
||||
spec.step.type = ED_NORMAL;
|
||||
spec.step.edit.start = start;
|
||||
spec.step.edit.end = end;
|
||||
spec.step.edit.len = len;
|
||||
spec.str = (u8*)str;
|
||||
edit_single__inner(system, models, file, spec, hist_normal);
|
||||
}
|
||||
|
||||
internal Edit_Spec
|
||||
edit_compute_batch_spec(Heap *heap,
|
||||
Editing_File *file,
|
||||
Buffer_Edit *edits, char *str_base, i32 str_size,
|
||||
Buffer_Edit *inverse_array, char *inv_str, i32 inv_max, i32 edit_count, i32 batch_type){
|
||||
|
||||
i32 inv_str_pos = 0;
|
||||
Buffer_Invert_Batch state = {};
|
||||
if (buffer_invert_batch(&state, &file->state.buffer, edits, edit_count,
|
||||
inverse_array, inv_str, &inv_str_pos, inv_max)){
|
||||
InvalidCodePath;
|
||||
}
|
||||
|
||||
i32 first_child = undo_children_push(heap, &file->state.undo.children, edits, edit_count, (u8*)(str_base), str_size);
|
||||
i32 inverse_first_child = undo_children_push(heap, &file->state.undo.children, inverse_array, edit_count, (u8*)(inv_str), inv_str_pos);
|
||||
|
||||
Edit_Spec spec = {};
|
||||
spec.step.type = ED_NORMAL;
|
||||
spec.step.first_child = first_child;
|
||||
spec.step.inverse_first_child = inverse_first_child;
|
||||
spec.step.special_type = batch_type;
|
||||
spec.step.child_count = edit_count;
|
||||
spec.step.inverse_child_count = edit_count;
|
||||
return(spec);
|
||||
}
|
||||
|
||||
internal void
|
||||
edit_batch(System_Functions *system, Models *models, Editing_File *file, Edit_Spec spec, History_Mode history_mode, Buffer_Batch_Edit_Type batch_type){
|
||||
edit_batch(System_Functions *system, Models *models, Editing_File *file, Edit_Array edits, Edit_Behaviors behaviors){
|
||||
Mem_Options *mem = &models->mem;
|
||||
Heap *heap = &mem->heap;
|
||||
Partition *part = &mem->part;
|
||||
Layout *layout = &models->layout;
|
||||
|
||||
Gap_Buffer *buffer = &file->state.buffer;
|
||||
Assert(edits.count > 0);
|
||||
|
||||
// NOTE(allen): history update
|
||||
if (!behaviors.do_not_post_to_history){
|
||||
history_dump_records_after_index(&file->state.history, file->state.current_record_index);
|
||||
history_record_edit(heap, &models->global_history, &file->state.history, buffer, edits, behaviors.batch_type);
|
||||
file->state.current_record_index = history_get_record_count(&file->state.history);
|
||||
}
|
||||
|
||||
// NOTE(allen): fixing stuff "beforewards"???
|
||||
Assert(spec.str == 0);
|
||||
file_update_history_before_edit(mem, file, spec.step, 0, history_mode);
|
||||
edit_pre_state_change(system, &mem->heap, models, file);
|
||||
|
||||
// NOTE(allen): expand spec
|
||||
u8 *str_base = file->state.undo.children.strings;
|
||||
i32 batch_size = spec.step.child_count;
|
||||
Buffer_Edit *batch = file->state.undo.children.edits + spec.step.first_child;
|
||||
Assert(spec.step.first_child < file->state.undo.children.edit_count);
|
||||
Assert(batch_size >= 0);
|
||||
|
||||
// NOTE(allen): cursor fixing
|
||||
Cursor_Fix_Descriptor desc = {};
|
||||
desc.is_batch = true;
|
||||
desc.batch = batch;
|
||||
desc.batch_size = batch_size;
|
||||
edit_fix_markers(system, models, file, layout, desc);
|
||||
|
||||
// NOTE(allen): actual text replacement
|
||||
void *scratch = push_array(part, u8, 0);
|
||||
i32 scratch_size = part_remaining(part);
|
||||
Buffer_Batch_State state = {};
|
||||
i32 request_amount = 0;
|
||||
for (;buffer_batch_edit_step(&state, &file->state.buffer, batch, (char*)str_base, batch_size, part->base + part->pos, scratch_size, &request_amount);){
|
||||
for (;buffer_batch_edit_step(&state, buffer, edits, scratch, scratch_size, &request_amount);){
|
||||
void *new_data = 0;
|
||||
if (request_amount > 0){
|
||||
new_data = heap_allocate(heap, request_amount);
|
||||
|
@ -367,14 +371,14 @@ edit_batch(System_Functions *system, Models *models, Editing_File *file, Edit_Sp
|
|||
buffer_measure_character_starts(system, font, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white);
|
||||
|
||||
// NOTE(allen): token fixing
|
||||
switch (batch_type){
|
||||
switch (behaviors.batch_type){
|
||||
case BatchEdit_Normal:
|
||||
{
|
||||
if (file->settings.tokens_exist){
|
||||
// TODO(allen): Write a smart fast one here someday.
|
||||
Buffer_Edit *first_edit = batch;
|
||||
Buffer_Edit *last_edit = batch + batch_size - 1;
|
||||
file_relex(system, models, file, first_edit->start, last_edit->end, shift_total);
|
||||
i32 start = edits.vals[0].range.first;
|
||||
i32 end = edits.vals[edits.count - 1].range.one_past_last;
|
||||
file_relex(system, models, file, start, end, shift_total);
|
||||
}
|
||||
else{
|
||||
file_mark_edit_finished(&models->working_set, file);
|
||||
|
@ -389,22 +393,25 @@ edit_batch(System_Functions *system, Models *models, Editing_File *file, Edit_Sp
|
|||
Cpp_Token *end_token = tokens.tokens + tokens.count;
|
||||
Cpp_Token original = {};
|
||||
|
||||
Buffer_Edit *edit = batch;
|
||||
Buffer_Edit *end_edit = batch + batch_size;
|
||||
Edit *edit = edits.vals;
|
||||
Edit *one_past_last_edit = edits.vals + edits.count;
|
||||
|
||||
i32 shift_amount = 0;
|
||||
i32 local_shift = 0;
|
||||
|
||||
for (;token < end_token; ++token){
|
||||
original = *token;
|
||||
for (; edit < end_edit && edit->start <= original.start; ++edit){
|
||||
local_shift = (edit->len - (edit->end - edit->start));
|
||||
for (;edit < one_past_last_edit && edit->range.first <= original.start;
|
||||
++edit){
|
||||
local_shift = (edit->length - (edit->range.one_past_last - edit->range.first));
|
||||
shift_amount += local_shift;
|
||||
}
|
||||
token->start += shift_amount;
|
||||
local_shift = 0;
|
||||
for (; edit < end_edit && edit->start < original.start + original.size; ++edit){
|
||||
local_shift += (edit->len - (edit->end - edit->start));
|
||||
i32 original_end = original.start + original.size;
|
||||
for (;edit < one_past_last_edit && edit->range.first < original_end;
|
||||
++edit){
|
||||
local_shift += (edit->length - (edit->range.one_past_last - edit->range.first));
|
||||
}
|
||||
token->size += local_shift;
|
||||
shift_amount += local_shift;
|
||||
|
@ -414,6 +421,12 @@ edit_batch(System_Functions *system, Models *models, Editing_File *file, Edit_Sp
|
|||
}break;
|
||||
}
|
||||
|
||||
// NOTE(allen): wrap meta data
|
||||
file_measure_wraps(system, &models->mem, file, font);
|
||||
|
||||
// NOTE(allen): cursor fixing
|
||||
edit_fix_markers(system, models, file, edits);
|
||||
|
||||
// NOTE(allen): mark edit finished
|
||||
if (file->settings.tokens_exist){
|
||||
if (file->settings.virtual_white){
|
||||
|
@ -423,9 +436,6 @@ edit_batch(System_Functions *system, Models *models, Editing_File *file, Edit_Sp
|
|||
else{
|
||||
file_mark_edit_finished(&models->working_set, file);
|
||||
}
|
||||
|
||||
// NOTE(allen): wrap meta data
|
||||
file_measure_wraps(system, &models->mem, file, font);
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -451,46 +461,188 @@ edit_clear(System_Functions *system, Models *models, Editing_File *file){
|
|||
panel != 0;
|
||||
panel = layout_get_next_open_panel(layout, panel)){
|
||||
View *view = panel->view;
|
||||
if (view->transient.file_data.file == file){
|
||||
if (view->file_data.file == file){
|
||||
Full_Cursor cursor = {};
|
||||
cursor.line = 1;
|
||||
cursor.character = 1;
|
||||
cursor.wrap_line = 1;
|
||||
view_set_cursor(view, cursor, true, file->settings.unwrapped_lines);
|
||||
view_set_cursor(system, view, cursor, true);
|
||||
no_views_see_file = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (no_views_see_file){
|
||||
block_zero_struct(&file->state.edit_pos_most_recent);
|
||||
block_zero(file->state.edit_pos_stack, sizeof(file->state.edit_pos_stack));
|
||||
file->state.edit_pos_stack_top = -1;
|
||||
}
|
||||
|
||||
edit_single(system, models, file, 0, buffer_size(&file->state.buffer), 0, 0);
|
||||
Edit edit = {};
|
||||
edit.range.one_past_last = buffer_size(&file->state.buffer);
|
||||
|
||||
Edit_Behaviors behaviors = {};
|
||||
edit_single(system, models, file, edit, behaviors);
|
||||
}
|
||||
|
||||
internal void
|
||||
edit_historical(System_Functions *system, Models *models, Editing_File *file, View *view, Edit_Stack *stack,
|
||||
Edit_Step step, History_Mode history_mode){
|
||||
Edit_Spec spec = {};
|
||||
spec.step = step;
|
||||
edit__apply_record_forward(System_Functions *system, Models *models, Editing_File *file, Record *record, Edit_Behaviors behaviors_prototype){
|
||||
// NOTE(allen): // NOTE(allen): // NOTE(allen): // NOTE(allen): // NOTE(allen):
|
||||
// Whenever you change this also change the backward version!
|
||||
|
||||
if (step.child_count == 0){
|
||||
spec.step.edit.str_start = 0;
|
||||
spec.str = stack->strings + step.edit.str_start;
|
||||
switch (record->kind){
|
||||
case RecordKind_Single:
|
||||
{
|
||||
Edit edit = {};
|
||||
edit.str = record->single.str_forward;
|
||||
edit.length = record->single.length_forward;
|
||||
edit.range.first = record->single.first;
|
||||
edit.range.one_past_last = edit.range.first + record->single.length_backward;
|
||||
edit_single(system, models, file, edit, behaviors_prototype);
|
||||
}break;
|
||||
|
||||
edit_single__inner(system, models, file, spec, history_mode);
|
||||
|
||||
if (view != 0){
|
||||
view_cursor_move(system, view, step.edit.start + step.edit.len);
|
||||
view->transient.edit_pos.mark = view->transient.edit_pos.cursor.pos;
|
||||
case RecordKind_Batch:
|
||||
{
|
||||
Partition *scratch = &models->mem.part;
|
||||
Temp_Memory temp = begin_temp_memory(scratch);
|
||||
|
||||
Style *style = &models->styles.styles[0];
|
||||
view_post_paste_effect(view, 0.333f, step.edit.start, step.edit.len, style->theme.colors[Stag_Undo]);
|
||||
}
|
||||
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;
|
||||
for (Node *node = sentinel->next;
|
||||
node != sentinel;
|
||||
node = node->next){
|
||||
Record *record = CastFromMember(Record, node, node);
|
||||
edit__apply_record_forward(system, models, file, record, behaviors_prototype);
|
||||
}
|
||||
}break;
|
||||
|
||||
default:
|
||||
{
|
||||
InvalidCodePath;
|
||||
}break;
|
||||
}
|
||||
else{
|
||||
edit_batch(system, models, view->transient.file_data.file, spec, hist_normal, spec.step.special_type);
|
||||
}
|
||||
|
||||
internal void
|
||||
edit__apply_record_backward(System_Functions *system, Models *models, Editing_File *file, Record *record, Edit_Behaviors behaviors_prototype){
|
||||
// NOTE(allen): // NOTE(allen): // NOTE(allen): // NOTE(allen): // NOTE(allen):
|
||||
// Whenever you change this also change the forward version!
|
||||
|
||||
switch (record->kind){
|
||||
case RecordKind_Single:
|
||||
{
|
||||
Edit edit = {};
|
||||
edit.str = record->single.str_backward;
|
||||
edit.length = record->single.length_backward;
|
||||
edit.range.first = record->single.first;
|
||||
edit.range.one_past_last = edit.range.first + record->single.length_forward;
|
||||
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;
|
||||
for (Node *node = sentinel->prev;
|
||||
node != sentinel;
|
||||
node = node->prev){
|
||||
Record *record = CastFromMember(Record, node, node);
|
||||
edit__apply_record_backward(system, models, file, record, behaviors_prototype);
|
||||
}
|
||||
}break;
|
||||
|
||||
default:
|
||||
{
|
||||
InvalidCodePath;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
edit_change_current_history_state(System_Functions *system, Models *models, Editing_File *file, i32 target_index){
|
||||
History *history = &file->state.history;
|
||||
if (history->activated && file->state.current_record_index != target_index){
|
||||
Assert(0 <= target_index && target_index <= history->record_count);
|
||||
|
||||
i32 current = file->state.current_record_index;
|
||||
Record *record = history_get_record(history, current);
|
||||
Assert(record != 0);
|
||||
Record *dummy_record = history_get_dummy_record(history);
|
||||
|
||||
Edit_Behaviors behaviors_prototype = {};
|
||||
behaviors_prototype.do_not_post_to_history = true;
|
||||
|
||||
if (current < target_index){
|
||||
do{
|
||||
current += 1;
|
||||
record = CastFromMember(Record, node, record->node.next);
|
||||
Assert(record != dummy_record);
|
||||
edit__apply_record_forward(system, models, file, record, behaviors_prototype);
|
||||
} while (current != target_index);
|
||||
}
|
||||
else{
|
||||
do{
|
||||
Assert(record != dummy_record);
|
||||
edit__apply_record_backward(system, models, file, record, behaviors_prototype);
|
||||
current -= 1;
|
||||
record = CastFromMember(Record, node, record->node.prev);
|
||||
} while (current != target_index);
|
||||
}
|
||||
|
||||
file->state.current_record_index = current;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 07.02.2019
|
||||
*
|
||||
* Types used for edit operations
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#if !defined(FRED_EDIT_H)
|
||||
#define FRED_EDIT_H
|
||||
|
||||
struct Edit{
|
||||
char *str;
|
||||
i32 length;
|
||||
Range range;
|
||||
};
|
||||
|
||||
struct Edit_Array{
|
||||
Edit *vals;
|
||||
i32 count;
|
||||
};
|
||||
|
||||
struct Edit_Behaviors{
|
||||
Buffer_Batch_Edit_Type batch_type;
|
||||
b32 do_not_post_to_history;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
||||
|
97
4ed_file.cpp
97
4ed_file.cpp
|
@ -19,25 +19,19 @@ to_file_id(i32 id){
|
|||
////////////////////////////////
|
||||
|
||||
internal void
|
||||
edit_pos_set_cursor(File_Edit_Positions *edit_pos, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapped_lines){
|
||||
edit_pos->cursor = cursor;
|
||||
if (set_preferred_x){
|
||||
edit_pos->preferred_x = cursor.wrapped_x;
|
||||
if (unwrapped_lines){
|
||||
edit_pos->preferred_x = cursor.unwrapped_x;
|
||||
}
|
||||
}
|
||||
file_edit_positions_set_cursor(File_Edit_Positions *edit_pos, i32 pos){
|
||||
edit_pos->cursor_pos = pos;
|
||||
edit_pos->last_set_type = EditPos_CursorSet;
|
||||
}
|
||||
|
||||
internal void
|
||||
edit_pos_set_scroll(File_Edit_Positions *edit_pos, GUI_Scroll_Vars scroll){
|
||||
file_edit_positions_set_scroll(File_Edit_Positions *edit_pos, GUI_Scroll_Vars scroll){
|
||||
edit_pos->scroll = scroll;
|
||||
edit_pos->last_set_type = EditPos_ScrollSet;
|
||||
}
|
||||
|
||||
internal void
|
||||
edit_pos_push(Editing_File *file, File_Edit_Positions edit_pos){
|
||||
file_edit_positions_push(Editing_File *file, File_Edit_Positions edit_pos){
|
||||
if (file->state.edit_pos_stack_top + 1 < ArrayCount(file->state.edit_pos_stack)){
|
||||
file->state.edit_pos_stack_top += 1;
|
||||
file->state.edit_pos_stack[file->state.edit_pos_stack_top] = edit_pos;
|
||||
|
@ -45,12 +39,15 @@ edit_pos_push(Editing_File *file, File_Edit_Positions edit_pos){
|
|||
}
|
||||
|
||||
internal File_Edit_Positions
|
||||
edit_pos_pop(Editing_File *file){
|
||||
file_edit_positions_pop(Editing_File *file){
|
||||
File_Edit_Positions edit_pos = {};
|
||||
if (file->state.edit_pos_stack_top >= 0){
|
||||
edit_pos = file->state.edit_pos_stack[file->state.edit_pos_stack_top];
|
||||
file->state.edit_pos_stack_top -= 1;
|
||||
}
|
||||
else{
|
||||
edit_pos = file->state.edit_pos_most_recent;
|
||||
}
|
||||
return(edit_pos);
|
||||
}
|
||||
|
||||
|
@ -215,6 +212,8 @@ file_compute_partial_cursor(Editing_File *file, Buffer_Seek seek, Partial_Cursor
|
|||
*cursor = buffer_partial_from_line_character(&file->state.buffer, seek.line, seek.character);
|
||||
}break;
|
||||
|
||||
// TODO(allen): do(support buffer_seek_character_pos and character_pos coordiantes in partial cursor system)
|
||||
|
||||
default:
|
||||
{
|
||||
result = false;
|
||||
|
@ -224,7 +223,7 @@ file_compute_partial_cursor(Editing_File *file, Buffer_Seek seek, Partial_Cursor
|
|||
}
|
||||
|
||||
internal Full_Cursor
|
||||
file_compute_cursor(System_Functions *system, Editing_File *file, Buffer_Seek seek, b32 return_hint){
|
||||
file_compute_cursor__inner(System_Functions *system, Editing_File *file, Buffer_Seek seek, b32 return_hint){
|
||||
Font_Pointers font = system->font.get_pointers_by_id(file->settings.font_id);
|
||||
Assert(font.valid);
|
||||
|
||||
|
@ -247,10 +246,10 @@ file_compute_cursor(System_Functions *system, Editing_File *file, Buffer_Seek se
|
|||
i32 size = buffer_size(params.buffer);
|
||||
|
||||
f32 line_shift = 0.f;
|
||||
b32 do_wrap = 0;
|
||||
b32 do_wrap = false;
|
||||
i32 wrap_unit_end = 0;
|
||||
|
||||
b32 first_wrap_determination = 1;
|
||||
b32 first_wrap_determination = true;
|
||||
i32 wrap_array_index = 0;
|
||||
|
||||
do{
|
||||
|
@ -259,7 +258,7 @@ file_compute_cursor(System_Functions *system, Editing_File *file, Buffer_Seek se
|
|||
case BLStatus_NeedWrapDetermination:
|
||||
{
|
||||
if (stop.pos >= size){
|
||||
do_wrap = 0;
|
||||
do_wrap = false;
|
||||
wrap_unit_end = max_i32;
|
||||
}
|
||||
else{
|
||||
|
@ -267,18 +266,18 @@ file_compute_cursor(System_Functions *system, Editing_File *file, Buffer_Seek se
|
|||
wrap_array_index = binary_search(file->state.wrap_positions, stop.pos, 0, file->state.wrap_position_count);
|
||||
++wrap_array_index;
|
||||
if (file->state.wrap_positions[wrap_array_index] == stop.pos){
|
||||
do_wrap = 1;
|
||||
do_wrap = true;
|
||||
wrap_unit_end = file->state.wrap_positions[wrap_array_index];
|
||||
}
|
||||
else{
|
||||
do_wrap = 0;
|
||||
do_wrap = false;
|
||||
wrap_unit_end = file->state.wrap_positions[wrap_array_index];
|
||||
}
|
||||
first_wrap_determination = 0;
|
||||
first_wrap_determination = false;
|
||||
}
|
||||
else{
|
||||
Assert(stop.pos == wrap_unit_end);
|
||||
do_wrap = 1;
|
||||
do_wrap = true;
|
||||
++wrap_array_index;
|
||||
wrap_unit_end = file->state.wrap_positions[wrap_array_index];
|
||||
}
|
||||
|
@ -296,6 +295,16 @@ file_compute_cursor(System_Functions *system, Editing_File *file, Buffer_Seek se
|
|||
return(result);
|
||||
}
|
||||
|
||||
internal Full_Cursor
|
||||
file_compute_cursor(System_Functions *system, Editing_File *file, Buffer_Seek seek){
|
||||
return(file_compute_cursor__inner(system, file, seek, false));
|
||||
}
|
||||
|
||||
internal Full_Cursor
|
||||
file_compute_cursor_hint(System_Functions *system, Editing_File *file, Buffer_Seek seek){
|
||||
return(file_compute_cursor__inner(system, file, seek, true));
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal i32
|
||||
|
@ -441,31 +450,7 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File *
|
|||
|
||||
file->settings.read_only = ((flags & FileCreateFlag_ReadOnly) != 0);
|
||||
if (!file->settings.read_only){
|
||||
// TODO(allen): Redo undo system (if you don't mind the pun)
|
||||
i32 request_size = KB(64);
|
||||
file->state.undo.undo.max = request_size;
|
||||
file->state.undo.undo.strings = (u8*)heap_allocate(heap, request_size);
|
||||
file->state.undo.undo.edit_max = request_size/sizeof(Edit_Step);
|
||||
file->state.undo.undo.edits = (Edit_Step*)heap_allocate(heap, request_size);
|
||||
|
||||
file->state.undo.redo.max = request_size;
|
||||
file->state.undo.redo.strings = (u8*)heap_allocate(heap, request_size);
|
||||
file->state.undo.redo.edit_max = request_size/sizeof(Edit_Step);
|
||||
file->state.undo.redo.edits = (Edit_Step*)heap_allocate(heap, request_size);
|
||||
|
||||
file->state.undo.history.max = request_size;
|
||||
file->state.undo.history.strings = (u8*)heap_allocate(heap, request_size);
|
||||
file->state.undo.history.edit_max = request_size/sizeof(Edit_Step);
|
||||
file->state.undo.history.edits = (Edit_Step*)heap_allocate(heap, request_size);
|
||||
|
||||
file->state.undo.children.max = request_size;
|
||||
file->state.undo.children.strings = (u8*)heap_allocate(heap, request_size);
|
||||
file->state.undo.children.edit_max = request_size/sizeof(Buffer_Edit);
|
||||
file->state.undo.children.edits = (Buffer_Edit*)heap_allocate(heap, request_size);
|
||||
|
||||
file->state.undo.history_block_count = 1;
|
||||
file->state.undo.history_head_block = 0;
|
||||
file->state.undo.current_block_normal = 1;
|
||||
history_init(&models->app_links, &file->state.history);
|
||||
}
|
||||
|
||||
// TODO(allen): do(cleanup the create and settings dance)
|
||||
|
@ -491,8 +476,7 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File *
|
|||
}
|
||||
|
||||
internal void
|
||||
file_free(System_Functions *system, Application_Links *app, Heap *heap, Lifetime_Allocator *lifetime_allocator,
|
||||
Editing_File *file){
|
||||
file_free(System_Functions *system, Heap *heap, Lifetime_Allocator *lifetime_allocator, Editing_File *file){
|
||||
if (file->state.still_lexing){
|
||||
system->cancel_job(BACKGROUND_THREADS, file->state.lex_job);
|
||||
if (file->state.swap_array.tokens){
|
||||
|
@ -516,19 +500,7 @@ file_free(System_Functions *system, Application_Links *app, Heap *heap, Lifetime
|
|||
heap_free(heap, file->state.character_starts);
|
||||
heap_free(heap, file->state.line_indents);
|
||||
|
||||
if (file->state.undo.undo.edits){
|
||||
heap_free(heap, file->state.undo.undo.strings);
|
||||
heap_free(heap, file->state.undo.undo.edits);
|
||||
|
||||
heap_free(heap, file->state.undo.redo.strings);
|
||||
heap_free(heap, file->state.undo.redo.edits);
|
||||
|
||||
heap_free(heap, file->state.undo.history.strings);
|
||||
heap_free(heap, file->state.undo.history.edits);
|
||||
|
||||
heap_free(heap, file->state.undo.children.strings);
|
||||
heap_free(heap, file->state.undo.children.edits);
|
||||
}
|
||||
history_free(heap, &file->state.history);
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -543,5 +515,12 @@ init_read_only_file(System_Functions *system, Models *models, Editing_File *file
|
|||
file_create_from_string(system, models, file, val, FileCreateFlag_ReadOnly);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal i32
|
||||
file_get_current_record_index(Editing_File *file){
|
||||
return(file->state.current_record_index);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
29
4ed_file.h
29
4ed_file.h
|
@ -12,26 +12,25 @@
|
|||
#if !defined(FRED_FILE_H)
|
||||
#define FRED_FILE_H
|
||||
|
||||
enum Edit_Pos_Set_Type{
|
||||
typedef i32 Edit_Pos_Set_Type;
|
||||
enum{
|
||||
EditPos_None,
|
||||
EditPos_CursorSet,
|
||||
EditPos_ScrollSet
|
||||
};
|
||||
struct File_Edit_Positions{
|
||||
Edit_Pos_Set_Type last_set_type;
|
||||
GUI_Scroll_Vars scroll;
|
||||
Full_Cursor cursor;
|
||||
i32 mark;
|
||||
f32 preferred_x;
|
||||
i32 scroll_i;
|
||||
i32 last_set_type;
|
||||
b32 in_view;
|
||||
i32 cursor_pos;
|
||||
};
|
||||
|
||||
// TODO(NAME): Replace this with markers over time.
|
||||
// TODO(NAME): do(replace Text_Effect with markers over time)
|
||||
struct Text_Effect{
|
||||
i32 start, end;
|
||||
i32 start;
|
||||
i32 end;
|
||||
u32 color;
|
||||
f32 seconds_down, seconds_max;
|
||||
f32 seconds_down;
|
||||
f32 seconds_max;
|
||||
};
|
||||
|
||||
union Buffer_Slot_ID{
|
||||
|
@ -40,6 +39,7 @@ union Buffer_Slot_ID{
|
|||
};
|
||||
|
||||
struct Editing_File_Settings{
|
||||
Buffer_Edit_Handler *edit_handler;
|
||||
i32 base_map_id;
|
||||
i32 display_width;
|
||||
i32 minimum_base_display_width;
|
||||
|
@ -75,19 +75,22 @@ struct Editing_File_State{
|
|||
i32 wrap_position_count;
|
||||
i32 wrap_position_max;
|
||||
|
||||
Undo_Data undo;
|
||||
History history;
|
||||
i32 current_record_index;
|
||||
|
||||
Cpp_Token_Array token_array;
|
||||
Cpp_Token_Array swap_array;
|
||||
u32 lex_job;
|
||||
b32 tokens_complete;
|
||||
b32 still_lexing;
|
||||
b8 tokens_complete;
|
||||
b8 still_lexing;
|
||||
b8 in_edit_handler;
|
||||
|
||||
Text_Effect paste_effect;
|
||||
|
||||
Dirty_State dirty;
|
||||
u32 ignore_behind_os;
|
||||
|
||||
File_Edit_Positions edit_pos_most_recent;
|
||||
File_Edit_Positions edit_pos_stack[16];
|
||||
i32 edit_pos_stack_top;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,521 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 24.03.2018
|
||||
*
|
||||
* History
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
internal Node*
|
||||
history__to_node(Node *sentinel, i32 index){
|
||||
Node *result = 0;
|
||||
i32 counter = 0;
|
||||
Node *it = sentinel;
|
||||
do{
|
||||
if (counter == index){
|
||||
result = it;
|
||||
break;
|
||||
}
|
||||
counter += 1;
|
||||
it = it->next;
|
||||
} while (it != sentinel);
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
history__push_back_record_ptr(Heap *heap, Record_Ptr_Lookup_Table *lookup, Record *record){
|
||||
if (lookup->records == 0 || lookup->count == lookup->max){
|
||||
i32 new_max = clamp_bottom(1024, lookup->max*2);
|
||||
Record **new_records = (Record**)heap_allocate(heap, sizeof(Record*)*new_max);
|
||||
block_copy(new_records, lookup->records, sizeof(*new_records)*lookup->count);
|
||||
if (lookup->records != 0){
|
||||
heap_free(heap, lookup->records);
|
||||
}
|
||||
lookup->records = new_records;
|
||||
lookup->max = new_max;
|
||||
}
|
||||
Assert(lookup->count < lookup->max);
|
||||
lookup->records[lookup->count] = record;
|
||||
lookup->count += 1;
|
||||
}
|
||||
|
||||
internal void
|
||||
history__shrink_array(Record_Ptr_Lookup_Table *lookup, i32 new_count){
|
||||
Assert(0 <= new_count && new_count <= lookup->count);
|
||||
lookup->count = new_count;
|
||||
}
|
||||
|
||||
internal void
|
||||
history__merge_record_ptr_range_to_one_ptr(Record_Ptr_Lookup_Table *lookup, i32 first_one_based, i32 last_one_based, Record *record){
|
||||
i32 first = first_one_based - 1;
|
||||
i32 one_past_last = last_one_based;
|
||||
Assert(0 <= first && first <= one_past_last && one_past_last <= lookup->count);
|
||||
if (first < one_past_last){
|
||||
i32 shift = 1 + first - one_past_last;
|
||||
block_copy(lookup->records + one_past_last + shift, lookup->records + one_past_last, lookup->count - one_past_last);
|
||||
lookup->count += shift;
|
||||
}
|
||||
lookup->records[first] = record;
|
||||
}
|
||||
|
||||
internal Node*
|
||||
history__to_node(History *history, i32 index){
|
||||
Node *result = 0;
|
||||
if (index == 0){
|
||||
result = &history->records;
|
||||
}
|
||||
else if (0 < index && index <= history->record_count){
|
||||
Record_Ptr_Lookup_Table *lookup = &history->record_lookup;
|
||||
Assert(lookup->count == history->record_count);
|
||||
result = &lookup->records[index - 1]->node;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal Record*
|
||||
history__allocate_record(Heap *heap, History *history){
|
||||
Node *sentinel = &history->free_records;
|
||||
Node *new_node = sentinel->next;
|
||||
if (new_node == sentinel){
|
||||
i32 new_record_count = 1024;
|
||||
void *memory = memory_bank_allocate(heap, &history->bank, sizeof(Record)*new_record_count);
|
||||
|
||||
Record *new_record = (Record*)memory;
|
||||
sentinel->next = &new_record->node;
|
||||
new_record->node.prev = sentinel;
|
||||
for (i32 i = 1; i < new_record_count; i += 1, new_record += 1){
|
||||
new_record[0].node.next = &new_record[1].node;
|
||||
new_record[1].node.prev = &new_record[0].node;
|
||||
}
|
||||
new_record[0].node.next = sentinel;
|
||||
sentinel->prev = &new_record[0].node;
|
||||
|
||||
new_node = &((Record*)memory)->node;
|
||||
}
|
||||
dll_remove(new_node);
|
||||
Record *record = CastFromMember(Record, node, new_node);
|
||||
block_zero_struct(record);
|
||||
return(record);
|
||||
}
|
||||
|
||||
internal void
|
||||
global_history_init(Global_History *global_history){
|
||||
global_history->edit_number_counter = 0;
|
||||
global_history->edit_grouping_counter = 0;
|
||||
}
|
||||
|
||||
internal i32
|
||||
global_history_get_edit_number(Global_History *global_history){
|
||||
i32 result = global_history->edit_number_counter;
|
||||
if (global_history->edit_grouping_counter == 0){
|
||||
global_history->edit_number_counter += 1;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
global_history_adjust_edit_grouping_counter(Global_History *global_history, i32 adjustment){
|
||||
i32 original = global_history->edit_grouping_counter;
|
||||
global_history->edit_grouping_counter = clamp_bottom(0, global_history->edit_grouping_counter + adjustment);
|
||||
if (global_history->edit_grouping_counter == 0 && original > 0){
|
||||
global_history->edit_number_counter += 1;
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
history_init(Application_Links *app, History *history){
|
||||
history->activated = true;
|
||||
history->arena = make_arena(app, KB(32));
|
||||
memory_bank_init(&history->bank);
|
||||
dll_init_sentinel(&history->free_records);
|
||||
dll_init_sentinel(&history->records);
|
||||
history->record_count = 0;
|
||||
block_zero_struct(&history->record_lookup);
|
||||
}
|
||||
|
||||
internal b32
|
||||
history_is_activated(History *history){
|
||||
return(history->activated);
|
||||
}
|
||||
|
||||
internal void
|
||||
history_free(Heap *heap, History *history){
|
||||
if (!history->activated){
|
||||
return;
|
||||
}
|
||||
arena_release_all(&history->arena);
|
||||
memory_bank_free_all(heap, &history->bank);
|
||||
block_zero_struct(history);
|
||||
}
|
||||
|
||||
internal i32
|
||||
history_get_record_count(History *history){
|
||||
if (!history->activated){
|
||||
return(0);
|
||||
}
|
||||
return(history->record_count);
|
||||
}
|
||||
|
||||
internal Record*
|
||||
history_get_record(History *history, i32 index){
|
||||
if (!history->activated){
|
||||
return(0);
|
||||
}
|
||||
Record *record = 0;
|
||||
Node *node = history__to_node(history, index);
|
||||
if (node != 0){
|
||||
record = CastFromMember(Record, node, node);
|
||||
}
|
||||
return(record);
|
||||
}
|
||||
|
||||
internal Record*
|
||||
history_get_sub_record(Record *record, i32 sub_index){
|
||||
Record *result = 0;
|
||||
if (record->kind == RecordKind_Group){
|
||||
if (0 <= sub_index && sub_index <= record->group.count){
|
||||
Node *node = history__to_node(&record->group.children, sub_index);
|
||||
if (node != 0){
|
||||
result = CastFromMember(Record, node, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal Record*
|
||||
history_get_dummy_record(History *history){
|
||||
if (!history->activated){
|
||||
return(0);
|
||||
}
|
||||
return(CastFromMember(Record, node, &history->records));
|
||||
}
|
||||
|
||||
internal void
|
||||
history__stash_record(Heap *heap, History *history, Record *new_record){
|
||||
Assert(history->record_lookup.count == history->record_count);
|
||||
dll_insert_back(&history->records, &new_record->node);
|
||||
history->record_count += 1;
|
||||
history__push_back_record_ptr(heap, &history->record_lookup, new_record);
|
||||
Assert(history->record_lookup.count == history->record_count);
|
||||
}
|
||||
|
||||
internal void
|
||||
history__free_single_node(History *history, Node *node){
|
||||
dll_remove(node);
|
||||
dll_insert(&history->free_records, node);
|
||||
}
|
||||
|
||||
internal void
|
||||
history__free_nodes(History *history, i32 first_index, Node *first_node, Node *last_node){
|
||||
if (first_node == last_node){
|
||||
history__free_single_node(history, first_node);
|
||||
}
|
||||
else{
|
||||
{
|
||||
Node *left = first_node->prev;
|
||||
Node *right = last_node->next;
|
||||
left->next = right;
|
||||
right->prev = left;
|
||||
}
|
||||
|
||||
{
|
||||
Node *left = &history->free_records;
|
||||
Node *right = left->next;
|
||||
left->next = first_node;
|
||||
first_node->prev = left;
|
||||
right->prev = last_node;
|
||||
last_node->next = right;
|
||||
}
|
||||
}
|
||||
Assert(first_index != 0);
|
||||
history->record_count = first_index - 1;
|
||||
history__shrink_array(&history->record_lookup, history->record_count);
|
||||
}
|
||||
|
||||
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 first = edit->range.first;
|
||||
i32 length_forward = edit->length;
|
||||
i32 length_backward = edit->range.one_past_last - first;
|
||||
|
||||
batch_slot->length_forward = length_forward ;
|
||||
batch_slot->length_backward = length_backward;
|
||||
batch_slot->first = first;
|
||||
|
||||
block_copy(cursor_forward , edit->str, length_forward);
|
||||
buffer_stringify_range(buffer, edit->range, cursor_backward);
|
||||
|
||||
cursor_forward += length_forward ;
|
||||
cursor_backward += length_backward;
|
||||
}
|
||||
|
||||
Assert(history->record_lookup.count == history->record_count);
|
||||
}
|
||||
|
||||
internal void
|
||||
history_dump_records_after_index(History *history, i32 index){
|
||||
if (!history->activated){
|
||||
return;
|
||||
}
|
||||
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
|
||||
history__optimize_group(Partition *scratch, History *history, Record *record){
|
||||
Assert(record->kind == RecordKind_Group);
|
||||
for (;;){
|
||||
Record *right = CastFromMember(Record, node, record->group.children.prev);
|
||||
if (record->group.count == 1){
|
||||
Record *child = right;
|
||||
record->restore_point = child->restore_point;
|
||||
record->edit_number = child->edit_number;
|
||||
record->kind = RecordKind_Single;
|
||||
record->single = child->single;
|
||||
// NOTE(allen): don't use "free" because the child node is no longer linked
|
||||
// to a valid sentinel, and removing it first (as free does) will mess with
|
||||
// the data in record->single
|
||||
dll_insert(&history->free_records, &child->node);
|
||||
break;
|
||||
}
|
||||
Record *left = CastFromMember(Record, node, right->node.prev);
|
||||
if (right->kind == RecordKind_Single && left->kind == RecordKind_Single){
|
||||
b32 do_merge = false;
|
||||
|
||||
Temp_Memory temp = begin_temp_memory(scratch);
|
||||
i32 new_length_forward = left->single.length_forward + right->single.length_forward ;
|
||||
i32 new_length_backward = left->single.length_backward + right->single.length_backward;
|
||||
|
||||
char *temp_str_forward = 0;
|
||||
char *temp_str_backward = 0;
|
||||
|
||||
if (left->single.first + left->single.length_forward == right->single.first){
|
||||
do_merge = true;
|
||||
temp_str_forward = push_array(scratch, char, new_length_forward );
|
||||
temp_str_backward = push_array(scratch, char, new_length_backward);
|
||||
block_copy(temp_str_forward , left->single.str_forward , left->single.length_forward );
|
||||
block_copy(temp_str_forward + left->single.length_forward, right->single.str_forward, right->single.length_forward);
|
||||
block_copy(temp_str_backward , left->single.str_backward , left->single.length_backward );
|
||||
block_copy(temp_str_backward + left->single.length_backward, right->single.str_backward, right->single.length_backward);
|
||||
}
|
||||
else if (right->single.first + right->single.length_backward == left->single.first){
|
||||
do_merge = true;
|
||||
temp_str_forward = push_array(scratch, char, new_length_forward );
|
||||
temp_str_backward = push_array(scratch, char, new_length_backward);
|
||||
block_copy(temp_str_forward , right->single.str_forward, right->single.length_forward);
|
||||
block_copy(temp_str_forward + right->single.length_forward, left->single.str_forward , left->single.length_forward );
|
||||
block_copy(temp_str_backward , right->single.str_backward, right->single.length_backward);
|
||||
block_copy(temp_str_backward + right->single.length_backward, left->single.str_backward , left->single.length_backward );
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
|
||||
if (do_merge){
|
||||
end_temp_memory(&history->arena, left->restore_point);
|
||||
|
||||
char *new_str_forward = push_array(&history->arena, char, new_length_forward );
|
||||
char *new_str_backward = push_array(&history->arena, char, new_length_backward);
|
||||
|
||||
block_copy(new_str_forward , temp_str_forward , new_length_forward );
|
||||
block_copy(new_str_backward, temp_str_backward, new_length_backward);
|
||||
|
||||
left->edit_number = right->edit_number;
|
||||
left->single.str_forward = new_str_forward ;
|
||||
left->single.str_backward = new_str_backward;
|
||||
left->single.length_forward = new_length_forward ;
|
||||
left->single.length_backward = new_length_backward;
|
||||
|
||||
history__free_single_node(history, &right->node);
|
||||
record->group.count -= 1;
|
||||
}
|
||||
|
||||
end_temp_memory(temp);
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
Node *right = new_sentinel;
|
||||
Node *left = new_sentinel->prev;
|
||||
left->next = first;
|
||||
first->prev = left;
|
||||
last->next = right;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 24.03.2018
|
||||
*
|
||||
* History
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#if !defined(FRED_HISTORY_H)
|
||||
#define FRED_HISTORY_H
|
||||
|
||||
struct Record_Batch_Slot{
|
||||
i32 length_forward;
|
||||
i32 length_backward;
|
||||
i32 first;
|
||||
};
|
||||
|
||||
struct Record{
|
||||
Node node;
|
||||
Temp_Memory_Arena_Light restore_point;
|
||||
i32 edit_number;
|
||||
Record_Kind kind;
|
||||
union{
|
||||
struct{
|
||||
char *str_forward;
|
||||
char *str_backward;
|
||||
i32 length_forward;
|
||||
i32 length_backward;
|
||||
i32 first;
|
||||
} single;
|
||||
|
||||
struct{
|
||||
Buffer_Batch_Edit_Type type;
|
||||
i32 count;
|
||||
char *str_base_forward;
|
||||
char *str_base_backward;
|
||||
Record_Batch_Slot *batch_records;
|
||||
} batch;
|
||||
|
||||
struct{
|
||||
Node children;
|
||||
i32 count;
|
||||
} group;
|
||||
};
|
||||
};
|
||||
|
||||
struct Record_Ptr_Lookup_Table{
|
||||
Record **records;
|
||||
i32 count;
|
||||
i32 max;
|
||||
};
|
||||
|
||||
struct History{
|
||||
b32 activated;
|
||||
Arena arena;
|
||||
Memory_Bank bank;
|
||||
Node free_records;
|
||||
Node records;
|
||||
i32 record_count;
|
||||
Record_Ptr_Lookup_Table record_lookup;
|
||||
};
|
||||
|
||||
struct Global_History{
|
||||
i32 edit_number_counter;
|
||||
i32 edit_grouping_counter;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
99
4ed_math.h
99
4ed_math.h
|
@ -209,7 +209,7 @@ V4(f32 x, f32 y, f32 z, f32 w){
|
|||
}
|
||||
|
||||
internal Vec2_i32
|
||||
V2(i32 x, i32 y){
|
||||
V2i32(i32 x, i32 y){
|
||||
Vec2_i32 result = {};
|
||||
result.x = x;
|
||||
result.y = y;
|
||||
|
@ -217,7 +217,7 @@ V2(i32 x, i32 y){
|
|||
}
|
||||
|
||||
internal Vec3_i32
|
||||
V3(i32 x, i32 y, i32 z){
|
||||
V3i32(i32 x, i32 y, i32 z){
|
||||
Vec3_i32 result = {};
|
||||
result.x = x;
|
||||
result.y = y;
|
||||
|
@ -226,7 +226,7 @@ V3(i32 x, i32 y, i32 z){
|
|||
}
|
||||
|
||||
internal Vec4_i32
|
||||
V4(i32 x, i32 y, i32 z, i32 w){
|
||||
V4i32(i32 x, i32 y, i32 z, i32 w){
|
||||
Vec4_i32 result = {};
|
||||
result.x = x;
|
||||
result.y = y;
|
||||
|
@ -734,12 +734,14 @@ rgba_to_hsla(Vec4 rgba){
|
|||
|
||||
internal Vec4
|
||||
hsla_to_rgba(Vec4 hsla){
|
||||
if (hsla.h >= 1.f) hsla.h = 0.f;
|
||||
Vec4 rgba = {};
|
||||
if (hsla.h >= 1.f){
|
||||
hsla.h = 0.f;
|
||||
}
|
||||
f32 C = (1.f - ABS(2*hsla.z - 1.f))*hsla.y;
|
||||
f32 X = C*(1.f-ABS(MOD(hsla.x*6.f, 2)-1.f));
|
||||
f32 m = hsla.z - C*.5f;
|
||||
i32 H = floor32(hsla.x*6.f);
|
||||
Vec4 rgba = {};
|
||||
rgba.a = hsla.a;
|
||||
switch (H){
|
||||
case 0: rgba.r = C; rgba.g = X; rgba.b = 0; break;
|
||||
|
@ -760,7 +762,7 @@ hsla_to_rgba(Vec4 hsla){
|
|||
//
|
||||
|
||||
internal i32_Rect
|
||||
i32R(int32_t l, int32_t t, int32_t r, int32_t b){
|
||||
i32R(i32 l, i32 t, i32 r, i32 b){
|
||||
i32_Rect rect = {};
|
||||
rect.x0 = l;
|
||||
rect.y0 = t;
|
||||
|
@ -771,45 +773,46 @@ i32R(int32_t l, int32_t t, int32_t r, int32_t b){
|
|||
|
||||
internal i32_Rect
|
||||
i32R(f32_Rect r){
|
||||
i32_Rect rect;
|
||||
rect.x0 = (int32_t)r.x0;
|
||||
rect.y0 = (int32_t)r.y0;
|
||||
rect.x1 = (int32_t)r.x1;
|
||||
rect.y1 = (int32_t)r.y1;
|
||||
i32_Rect rect = {};
|
||||
rect.x0 = (i32)r.x0;
|
||||
rect.y0 = (i32)r.y0;
|
||||
rect.x1 = (i32)r.x1;
|
||||
rect.y1 = (i32)r.y1;
|
||||
return(rect);
|
||||
}
|
||||
|
||||
internal f32_Rect
|
||||
f32R(float l, float t, float r, float b){
|
||||
f32_Rect rect;
|
||||
rect.x0 = l; rect.y0 = t;
|
||||
rect.x1 = r; rect.y1 = b;
|
||||
f32R(f32 l, f32 t, f32 r, f32 b){
|
||||
f32_Rect rect = {};
|
||||
rect.x0 = l;
|
||||
rect.y0 = t;
|
||||
rect.x1 = r;
|
||||
rect.y1 = b;
|
||||
return(rect);
|
||||
}
|
||||
|
||||
internal f32_Rect
|
||||
f32R(i32_Rect r){
|
||||
f32_Rect rect;
|
||||
rect.x0 = (float)r.x0;
|
||||
rect.y0 = (float)r.y0;
|
||||
rect.x1 = (float)r.x1;
|
||||
rect.y1 = (float)r.y1;
|
||||
f32_Rect rect = {};
|
||||
rect.x0 = (f32)r.x0;
|
||||
rect.y0 = (f32)r.y0;
|
||||
rect.x1 = (f32)r.x1;
|
||||
rect.y1 = (f32)r.y1;
|
||||
return(rect);
|
||||
}
|
||||
|
||||
internal int32_t
|
||||
internal i32
|
||||
rect_equal(i32_Rect r1, i32_Rect r2){
|
||||
int32_t result = (r1.x0 == r2.x0 && r1.y0 == r2.y0 && r1.x1 == r2.x1 && r1.y1 == r2.y1);
|
||||
return(result);
|
||||
return(r1.x0 == r2.x0 && r1.y0 == r2.y0 && r1.x1 == r2.x1 && r1.y1 == r2.y1);
|
||||
}
|
||||
|
||||
internal int32_t
|
||||
hit_check(int32_t x, int32_t y, int32_t x0, int32_t y0, int32_t x1, int32_t y1){
|
||||
internal i32
|
||||
hit_check(i32 x, i32 y, i32 x0, i32 y0, i32 x1, i32 y1){
|
||||
return(x >= x0 && x < x1 && y >= y0 && y < y1);
|
||||
}
|
||||
|
||||
internal int32_t
|
||||
hit_check(int32_t x, int32_t y, i32_Rect rect){
|
||||
internal i32
|
||||
hit_check(i32 x, i32 y, i32_Rect rect){
|
||||
return(hit_check(x, y, rect.x0, rect.y0, rect.x1, rect.y1));
|
||||
}
|
||||
|
||||
|
@ -833,26 +836,40 @@ get_inner_rect(f32_Rect outer, f32 margin){
|
|||
return(r);
|
||||
}
|
||||
|
||||
internal int32_t
|
||||
internal i32
|
||||
rect_height(i32_Rect rect){
|
||||
return(rect.y1 - rect.y0);
|
||||
}
|
||||
|
||||
internal i32
|
||||
rect_width(i32_Rect rect){
|
||||
return(rect.x1 - rect.x0);
|
||||
}
|
||||
|
||||
internal i32
|
||||
fits_inside(i32_Rect rect, i32_Rect outer){
|
||||
return(rect.x0 >= outer.x0 && rect.x1 <= outer.x1 && rect.y0 >= outer.y0 && rect.y1 <= outer.y1);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
interval_overlap(float a0, float a1, float b0, float b1){
|
||||
if ((a0 <= b0 && b0 < a1) || (b0 <= a0 && a0 < b1)){
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
internal i32
|
||||
interval_overlap(f32 a0, f32 a1, f32 b0, f32 b1){
|
||||
return(a0 < b1 && b0 < a1);
|
||||
}
|
||||
|
||||
static int32_t
|
||||
rect_opverlap(f32_Rect a, f32_Rect b){
|
||||
if (interval_overlap(a.x0, a.x1, b.x0, b.x1) &&
|
||||
interval_overlap(a.y0, a.y1, b.y0, b.y1)){
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
internal i32
|
||||
rect_overlap(f32_Rect a, f32_Rect b){
|
||||
return(interval_overlap(a.x0, a.x1, b.x0, b.x1) &&
|
||||
interval_overlap(a.y0, a.y1, b.y0, b.y1));
|
||||
}
|
||||
|
||||
internal f32
|
||||
rect_height(f32_Rect rect){
|
||||
return(rect.y1 - rect.y0);
|
||||
}
|
||||
|
||||
internal f32
|
||||
rect_width(f32_Rect rect){
|
||||
return(rect.x1 - rect.x0);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 07.02.2019
|
||||
*
|
||||
* Memory bank wrapper for heap
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
internal void
|
||||
memory_bank_init(Memory_Bank *mem_bank){
|
||||
heap_init(&mem_bank->heap);
|
||||
mem_bank->first = 0;
|
||||
mem_bank->last = 0;
|
||||
mem_bank->total_memory_size = 0;
|
||||
}
|
||||
|
||||
internal void*
|
||||
memory_bank_allocate(Heap *heap, Memory_Bank *mem_bank, i32 size){
|
||||
void *ptr = heap_allocate(&mem_bank->heap, size);
|
||||
if (ptr == 0){
|
||||
i32 alloc_size = clamp_bottom(4096, size*4 + sizeof(Memory_Header));
|
||||
void *new_block = heap_allocate(heap, alloc_size);
|
||||
if (new_block != 0){
|
||||
Memory_Header *header = (Memory_Header*)new_block;
|
||||
sll_push(mem_bank->first, mem_bank->last, header);
|
||||
mem_bank->total_memory_size += alloc_size;
|
||||
heap_extend(&mem_bank->heap, header + 1, alloc_size - sizeof(*header));
|
||||
ptr = heap_allocate(&mem_bank->heap, size);
|
||||
}
|
||||
}
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
internal void
|
||||
memory_bank_free(Memory_Bank *mem_bank, void *ptr){
|
||||
heap_free(&mem_bank->heap, ptr);
|
||||
}
|
||||
|
||||
internal void
|
||||
memory_bank_free_all(Heap *heap, Memory_Bank *mem_bank){
|
||||
for (Memory_Header *header = mem_bank->first, *next = 0;
|
||||
header != 0;
|
||||
header = next){
|
||||
next = header->next;
|
||||
heap_free(heap, header);
|
||||
}
|
||||
mem_bank->total_memory_size = 0;
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 07.02.2019
|
||||
*
|
||||
* Memory bank wrapper for heap
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#if !defined(FRED_MEMORY_BANK_H)
|
||||
#define FRED_MEMORY_BANK_H
|
||||
|
||||
struct Memory_Header{
|
||||
Memory_Header *next;
|
||||
};
|
||||
|
||||
struct Memory_Bank{
|
||||
Heap heap;
|
||||
Memory_Header *first;
|
||||
Memory_Header *last;
|
||||
umem total_memory_size;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
||||
|
456
4ed_undo.cpp
456
4ed_undo.cpp
|
@ -1,456 +0,0 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 24.03.2018
|
||||
*
|
||||
* Undo
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
internal void
|
||||
undo_stack_grow_string(Heap *heap, Edit_Stack *stack, i32 extra_size){
|
||||
i32 old_max = stack->max;
|
||||
u8 *old_str = stack->strings;
|
||||
i32 new_max = old_max*2 + extra_size;
|
||||
u8 *new_str = heap_array(heap, u8, new_max);
|
||||
memcpy(new_str, old_str, sizeof(*new_str)*old_max);
|
||||
heap_free(heap, old_str);
|
||||
stack->strings = new_str;
|
||||
stack->max = new_max;
|
||||
}
|
||||
|
||||
internal void
|
||||
undo_stack_grow_edits(Heap *heap, Edit_Stack *stack){
|
||||
i32 old_max = stack->edit_max;
|
||||
Edit_Step *old_eds = stack->edits;
|
||||
i32 new_max = old_max*2 + 2;
|
||||
Edit_Step *new_eds = heap_array(heap, Edit_Step, new_max);
|
||||
memcpy(new_eds, old_eds, sizeof(*new_eds)*old_max);
|
||||
heap_free(heap, old_eds);
|
||||
stack->edits = new_eds;
|
||||
stack->edit_max = new_max;
|
||||
}
|
||||
|
||||
internal void
|
||||
child_stack_grow_string(Heap *heap, Small_Edit_Stack *stack, i32 extra_size){
|
||||
i32 old_max = stack->max;
|
||||
u8 *old_str = stack->strings;
|
||||
i32 new_max = old_max*2 + extra_size;
|
||||
u8 *new_str = heap_array(heap, u8, new_max);
|
||||
memcpy(new_str, old_str, sizeof(*new_str)*old_max);
|
||||
heap_free(heap, old_str);
|
||||
stack->strings = new_str;
|
||||
stack->max = new_max;
|
||||
}
|
||||
|
||||
internal void
|
||||
child_stack_grow_edits(Heap *heap, Small_Edit_Stack *stack, i32 amount){
|
||||
i32 old_max = stack->edit_max;
|
||||
Buffer_Edit *old_eds = stack->edits;
|
||||
i32 new_max = old_max*2 + amount;
|
||||
Buffer_Edit *new_eds = heap_array(heap, Buffer_Edit, new_max);
|
||||
memcpy(new_eds, old_eds, sizeof(*new_eds)*new_max);
|
||||
heap_free(heap, old_eds);
|
||||
stack->edits = new_eds;
|
||||
stack->edit_max = new_max;
|
||||
}
|
||||
|
||||
internal i32
|
||||
undo_children_push(Heap *heap, Small_Edit_Stack *children, Buffer_Edit *edits, i32 edit_count, u8 *strings, i32 string_size){
|
||||
i32 result = children->edit_count;
|
||||
if (children->edit_count + edit_count > children->edit_max){
|
||||
child_stack_grow_edits(heap, children, edit_count);
|
||||
}
|
||||
|
||||
if (children->size + string_size > children->max){
|
||||
child_stack_grow_string(heap, children, string_size);
|
||||
}
|
||||
|
||||
memcpy(children->edits + children->edit_count, edits, edit_count*sizeof(Buffer_Edit));
|
||||
memcpy(children->strings + children->size, strings, string_size);
|
||||
|
||||
Buffer_Edit *edit = children->edits + children->edit_count;
|
||||
i32 start_pos = children->size;
|
||||
for (i32 i = 0; i < edit_count; ++i, ++edit){
|
||||
edit->str_start += start_pos;
|
||||
}
|
||||
|
||||
children->edit_count += edit_count;
|
||||
children->size += string_size;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal Edit_Step*
|
||||
file_post_undo(Heap *heap, Editing_File *file, Edit_Step step, b32 do_merge, b32 can_merge){
|
||||
if (step.type == ED_NORMAL){
|
||||
file->state.undo.redo.size = 0;
|
||||
file->state.undo.redo.edit_count = 0;
|
||||
}
|
||||
|
||||
Edit_Stack *undo = &file->state.undo.undo;
|
||||
Edit_Step *result = 0;
|
||||
|
||||
if (step.child_count == 0){
|
||||
if (step.edit.end - step.edit.start + undo->size > undo->max){
|
||||
undo_stack_grow_string(heap, undo, step.edit.end - step.edit.start);
|
||||
}
|
||||
|
||||
Buffer_Edit inv;
|
||||
buffer_invert_edit(&file->state.buffer, step.edit, &inv, (char*)undo->strings, &undo->size, undo->max);
|
||||
|
||||
Edit_Step inv_step = {};
|
||||
inv_step.edit = inv;
|
||||
inv_step.can_merge = (b8)can_merge;
|
||||
inv_step.type = ED_UNDO;
|
||||
|
||||
b32 did_merge = 0;
|
||||
if (do_merge && undo->edit_count > 0){
|
||||
Edit_Step prev = undo->edits[undo->edit_count-1];
|
||||
if (prev.can_merge && inv_step.edit.len == 0 && prev.edit.len == 0){
|
||||
if (prev.edit.end == inv_step.edit.start){
|
||||
did_merge = 1;
|
||||
inv_step.edit.start = prev.edit.start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (did_merge){
|
||||
result = undo->edits + (undo->edit_count-1);
|
||||
*result = inv_step;
|
||||
}
|
||||
else{
|
||||
if (undo->edit_count == undo->edit_max){
|
||||
undo_stack_grow_edits(heap, undo);
|
||||
}
|
||||
|
||||
result = undo->edits + (undo->edit_count++);
|
||||
*result = inv_step;
|
||||
}
|
||||
}
|
||||
else{
|
||||
Edit_Step inv_step = {};
|
||||
inv_step.type = ED_UNDO;
|
||||
inv_step.first_child = step.inverse_first_child;
|
||||
inv_step.inverse_first_child = step.first_child;
|
||||
inv_step.special_type = step.special_type;
|
||||
inv_step.child_count = step.inverse_child_count;
|
||||
inv_step.inverse_child_count = step.child_count;
|
||||
|
||||
if (undo->edit_count == undo->edit_max){
|
||||
undo_stack_grow_edits(heap, undo);
|
||||
}
|
||||
result = undo->edits + (undo->edit_count++);
|
||||
*result = inv_step;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
undo_stack_pop(Edit_Stack *stack){
|
||||
if (stack->edit_count > 0){
|
||||
Edit_Step *edit = stack->edits + (--stack->edit_count);
|
||||
if (edit->child_count == 0){
|
||||
stack->size -= edit->edit.len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
file_post_redo(Heap *heap, Editing_File *file, Edit_Step step){
|
||||
Edit_Stack *redo = &file->state.undo.redo;
|
||||
|
||||
if (step.child_count == 0){
|
||||
if (step.edit.end - step.edit.start + redo->size > redo->max){
|
||||
undo_stack_grow_string(heap, redo, step.edit.end - step.edit.start);
|
||||
}
|
||||
|
||||
Buffer_Edit inv;
|
||||
buffer_invert_edit(&file->state.buffer, step.edit, &inv, (char*)redo->strings, &redo->size, redo->max);
|
||||
|
||||
Edit_Step inv_step = {};
|
||||
inv_step.edit = inv;
|
||||
inv_step.type = ED_REDO;
|
||||
|
||||
if (redo->edit_count == redo->edit_max){
|
||||
undo_stack_grow_edits(heap, redo);
|
||||
}
|
||||
redo->edits[redo->edit_count++] = inv_step;
|
||||
}
|
||||
else{
|
||||
Edit_Step inv_step = {};
|
||||
inv_step.type = ED_REDO;
|
||||
inv_step.first_child = step.inverse_first_child;
|
||||
inv_step.inverse_first_child = step.first_child;
|
||||
inv_step.special_type = step.special_type;
|
||||
inv_step.child_count = step.inverse_child_count;
|
||||
inv_step.inverse_child_count = step.child_count;
|
||||
|
||||
if (redo->edit_count == redo->edit_max){
|
||||
undo_stack_grow_edits(heap, redo);
|
||||
}
|
||||
redo->edits[redo->edit_count++] = inv_step;
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
file_post_history_block(Editing_File *file, i32 pos){
|
||||
Assert(file->state.undo.history_head_block < pos);
|
||||
Assert(pos < file->state.undo.history.edit_count);
|
||||
|
||||
Edit_Step *history = file->state.undo.history.edits;
|
||||
Edit_Step *step = history + file->state.undo.history_head_block;
|
||||
step->next_block = pos;
|
||||
step = history + pos;
|
||||
step->prev_block = file->state.undo.history_head_block;
|
||||
file->state.undo.history_head_block = pos;
|
||||
++file->state.undo.history_block_count;
|
||||
}
|
||||
|
||||
internal void
|
||||
file_unpost_history_block(Editing_File *file){
|
||||
Assert(file->state.undo.history_block_count > 1);
|
||||
--file->state.undo.history_block_count;
|
||||
Edit_Step *old_head = file->state.undo.history.edits + file->state.undo.history_head_block;
|
||||
file->state.undo.history_head_block = old_head->prev_block;
|
||||
}
|
||||
|
||||
internal Edit_Step*
|
||||
file_post_history(Heap *heap, Editing_File *file, Edit_Step step, b32 do_merge, b32 can_merge){
|
||||
Edit_Stack *history = &file->state.undo.history;
|
||||
Edit_Step *result = 0;
|
||||
|
||||
local_persist Edit_Type reverse_types[4];
|
||||
if (reverse_types[ED_UNDO] == 0){
|
||||
reverse_types[ED_NORMAL] = ED_REVERSE_NORMAL;
|
||||
reverse_types[ED_REVERSE_NORMAL] = ED_NORMAL;
|
||||
reverse_types[ED_UNDO] = ED_REDO;
|
||||
reverse_types[ED_REDO] = ED_UNDO;
|
||||
}
|
||||
|
||||
if (step.child_count == 0){
|
||||
if (step.edit.end - step.edit.start + history->size > history->max){
|
||||
undo_stack_grow_string(heap, history, step.edit.end - step.edit.start);
|
||||
}
|
||||
|
||||
Buffer_Edit inv;
|
||||
buffer_invert_edit(&file->state.buffer, step.edit, &inv,
|
||||
(char*)history->strings, &history->size, history->max);
|
||||
|
||||
Edit_Step inv_step = {};
|
||||
inv_step.edit = inv;
|
||||
inv_step.can_merge = (b8)can_merge;
|
||||
inv_step.type = reverse_types[step.type];
|
||||
|
||||
b32 did_merge = 0;
|
||||
if (do_merge && history->edit_count > 0){
|
||||
Edit_Step prev = history->edits[history->edit_count-1];
|
||||
if (prev.can_merge && inv_step.edit.len == 0 && prev.edit.len == 0){
|
||||
if (prev.edit.end == inv_step.edit.start){
|
||||
did_merge = 1;
|
||||
inv_step.edit.start = prev.edit.start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (did_merge){
|
||||
result = history->edits + (history->edit_count-1);
|
||||
}
|
||||
else{
|
||||
if (history->edit_count == history->edit_max){
|
||||
undo_stack_grow_edits(heap, history);
|
||||
}
|
||||
result = history->edits + (history->edit_count++);
|
||||
}
|
||||
|
||||
*result = inv_step;
|
||||
}
|
||||
else{
|
||||
Edit_Step inv_step = {};
|
||||
inv_step.type = reverse_types[step.type];
|
||||
inv_step.first_child = step.inverse_first_child;
|
||||
inv_step.inverse_first_child = step.first_child;
|
||||
inv_step.special_type = step.special_type;
|
||||
inv_step.inverse_child_count = step.child_count;
|
||||
inv_step.child_count = step.inverse_child_count;
|
||||
|
||||
if (history->edit_count == history->edit_max){
|
||||
undo_stack_grow_edits(heap, history);
|
||||
}
|
||||
result = history->edits + (history->edit_count++);
|
||||
*result = inv_step;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
file_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step step, u8 *str, History_Mode history_mode){
|
||||
if (!file->state.undo.undo.edits) return;
|
||||
Heap *heap = &mem->heap;
|
||||
|
||||
b32 can_merge = 0, do_merge = 0;
|
||||
switch (step.type){
|
||||
case ED_NORMAL:
|
||||
{
|
||||
if (step.edit.len == 1 && str && char_is_alpha_numeric(*str)){
|
||||
can_merge = 1;
|
||||
}
|
||||
if (step.edit.len == 1 && str && (can_merge || char_is_whitespace(*str))){
|
||||
do_merge = 1;
|
||||
}
|
||||
|
||||
if (history_mode != hist_forward){
|
||||
file_post_history(heap, file, step, do_merge, can_merge);
|
||||
}
|
||||
|
||||
file_post_undo(heap, file, step, do_merge, can_merge);
|
||||
}break;
|
||||
|
||||
case ED_REVERSE_NORMAL:
|
||||
{
|
||||
if (history_mode != hist_forward){
|
||||
file_post_history(heap, file, step, do_merge, can_merge);
|
||||
}
|
||||
|
||||
undo_stack_pop(&file->state.undo.undo);
|
||||
|
||||
b32 restore_redos = 0;
|
||||
Edit_Step *redo_end = 0;
|
||||
|
||||
if (history_mode == hist_backward && file->state.undo.edit_history_cursor > 0){
|
||||
restore_redos = 1;
|
||||
redo_end = file->state.undo.history.edits + (file->state.undo.edit_history_cursor - 1);
|
||||
}
|
||||
else if (history_mode == hist_forward && file->state.undo.history.edit_count > 0){
|
||||
restore_redos = 1;
|
||||
redo_end = file->state.undo.history.edits + (file->state.undo.history.edit_count - 1);
|
||||
}
|
||||
|
||||
if (restore_redos){
|
||||
Edit_Step *redo_start = redo_end;
|
||||
i32 steps_of_redo = 0;
|
||||
i32 strings_of_redo = 0;
|
||||
{
|
||||
i32 undo_count = 0;
|
||||
while (redo_start->type == ED_REDO || redo_start->type == ED_UNDO){
|
||||
if (redo_start->type == ED_REDO){
|
||||
if (undo_count > 0){
|
||||
--undo_count;
|
||||
}
|
||||
else{
|
||||
++steps_of_redo;
|
||||
strings_of_redo += redo_start->edit.len;
|
||||
}
|
||||
}
|
||||
else{
|
||||
++undo_count;
|
||||
}
|
||||
--redo_start;
|
||||
}
|
||||
}
|
||||
|
||||
if (redo_start < redo_end){
|
||||
++redo_start;
|
||||
++redo_end;
|
||||
|
||||
if (file->state.undo.redo.edit_count + steps_of_redo > file->state.undo.redo.edit_max)
|
||||
undo_stack_grow_edits(heap, &file->state.undo.redo);
|
||||
|
||||
if (file->state.undo.redo.size + strings_of_redo > file->state.undo.redo.max)
|
||||
undo_stack_grow_string(heap, &file->state.undo.redo, strings_of_redo);
|
||||
|
||||
u8 *str_src = file->state.undo.history.strings + redo_end->edit.str_start;
|
||||
u8 *str_dest_base = file->state.undo.redo.strings;
|
||||
i32 str_redo_pos = file->state.undo.redo.size + strings_of_redo;
|
||||
|
||||
Edit_Step *edit_src = redo_end;
|
||||
Edit_Step *edit_dest = file->state.undo.redo.edits + file->state.undo.redo.edit_count + steps_of_redo;
|
||||
|
||||
{
|
||||
i32 undo_count = 0;
|
||||
for (i32 i = 0; i < steps_of_redo;){
|
||||
--edit_src;
|
||||
str_src -= edit_src->edit.len;
|
||||
if (edit_src->type == ED_REDO){
|
||||
if (undo_count > 0){
|
||||
--undo_count;
|
||||
}
|
||||
else{
|
||||
++i;
|
||||
|
||||
--edit_dest;
|
||||
*edit_dest = *edit_src;
|
||||
|
||||
str_redo_pos -= edit_dest->edit.len;
|
||||
edit_dest->edit.str_start = str_redo_pos;
|
||||
|
||||
memcpy(str_dest_base + str_redo_pos, str_src, edit_dest->edit.len);
|
||||
}
|
||||
}
|
||||
else{
|
||||
++undo_count;
|
||||
}
|
||||
}
|
||||
Assert(undo_count == 0);
|
||||
}
|
||||
|
||||
file->state.undo.redo.size += strings_of_redo;
|
||||
file->state.undo.redo.edit_count += steps_of_redo;
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
||||
case ED_UNDO:
|
||||
{
|
||||
if (history_mode != hist_forward){
|
||||
file_post_history(heap, file, step, do_merge, can_merge);
|
||||
}
|
||||
file_post_redo(heap, file, step);
|
||||
undo_stack_pop(&file->state.undo.undo);
|
||||
}break;
|
||||
|
||||
case ED_REDO:
|
||||
{
|
||||
if (step.edit.len == 1 && str && char_is_alpha_numeric(*str)) can_merge = 1;
|
||||
if (step.edit.len == 1 && str && (can_merge || char_is_whitespace(*str))) do_merge = 1;
|
||||
|
||||
if (history_mode != hist_forward){
|
||||
file_post_history(heap, file, step, do_merge, can_merge);
|
||||
}
|
||||
|
||||
file_post_undo(heap, file, step, do_merge, can_merge);
|
||||
undo_stack_pop(&file->state.undo.redo);
|
||||
}break;
|
||||
}
|
||||
|
||||
if (history_mode != hist_forward){
|
||||
if (step.type == ED_UNDO || step.type == ED_REDO){
|
||||
if (file->state.undo.current_block_normal){
|
||||
file_post_history_block(file, file->state.undo.history.edit_count - 1);
|
||||
file->state.undo.current_block_normal = 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (!file->state.undo.current_block_normal){
|
||||
file_post_history_block(file, file->state.undo.history.edit_count - 1);
|
||||
file->state.undo.current_block_normal = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (file->state.undo.history_head_block == file->state.undo.history.edit_count){
|
||||
file_unpost_history_block(file);
|
||||
file->state.undo.current_block_normal = !file->state.undo.current_block_normal;
|
||||
}
|
||||
}
|
||||
|
||||
if (history_mode == hist_normal){
|
||||
file->state.undo.edit_history_cursor = file->state.undo.history.edit_count;
|
||||
}
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
70
4ed_undo.h
70
4ed_undo.h
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 24.01.2018
|
||||
*
|
||||
* Buffer types
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#if !defined(FRED_UNDO_H)
|
||||
#define FRED_UNDO_H
|
||||
|
||||
enum Edit_Type{
|
||||
ED_NORMAL,
|
||||
ED_REVERSE_NORMAL,
|
||||
ED_UNDO,
|
||||
ED_REDO,
|
||||
};
|
||||
|
||||
struct Edit_Step{
|
||||
Edit_Type type;
|
||||
union{
|
||||
struct{
|
||||
b32 can_merge;
|
||||
Buffer_Edit edit;
|
||||
i32 next_block;
|
||||
i32 prev_block;
|
||||
};
|
||||
struct{
|
||||
i32 first_child;
|
||||
i32 inverse_first_child;
|
||||
i32 inverse_child_count;
|
||||
i32 special_type;
|
||||
};
|
||||
};
|
||||
i32 child_count;
|
||||
};
|
||||
|
||||
struct Edit_Stack{
|
||||
u8 *strings;
|
||||
i32 size, max;
|
||||
|
||||
Edit_Step *edits;
|
||||
i32 edit_count, edit_max;
|
||||
};
|
||||
|
||||
struct Small_Edit_Stack{
|
||||
u8 *strings;
|
||||
i32 size, max;
|
||||
|
||||
Buffer_Edit *edits;
|
||||
i32 edit_count, edit_max;
|
||||
};
|
||||
|
||||
struct Undo_Data{
|
||||
Edit_Stack undo;
|
||||
Edit_Stack redo;
|
||||
Edit_Stack history;
|
||||
Small_Edit_Stack children;
|
||||
|
||||
i32 history_block_count, history_head_block;
|
||||
i32 edit_history_cursor;
|
||||
b32 current_block_normal;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
400
4ed_view.cpp
400
4ed_view.cpp
|
@ -11,29 +11,37 @@
|
|||
|
||||
internal i32
|
||||
view_get_map(View *view){
|
||||
if (view->transient.ui_mode){
|
||||
return(view->transient.ui_map_id);
|
||||
if (view->ui_mode){
|
||||
return(view->ui_map_id);
|
||||
}
|
||||
else{
|
||||
return(view->transient.file_data.file->settings.base_map_id);
|
||||
return(view->file_data.file->settings.base_map_id);
|
||||
}
|
||||
}
|
||||
|
||||
internal i32
|
||||
view_get_index(Live_Views *live_set, View *view){
|
||||
return((i32)(view - live_set->views));
|
||||
}
|
||||
|
||||
internal i32
|
||||
view_get_id(Live_Views *live_set, View *view){
|
||||
return((i32)(view - live_set->views) + 1);
|
||||
}
|
||||
|
||||
internal View*
|
||||
live_set_alloc_view(Heap *heap, Lifetime_Allocator *lifetime_allocator, Live_Views *live_set){
|
||||
Assert(live_set->count < live_set->max);
|
||||
++live_set->count;
|
||||
|
||||
View *result = live_set->free_sentinel.transient.next;
|
||||
Assert((i32)(result - live_set->views) == result->persistent.id);
|
||||
View *result = live_set->free_sentinel.next;
|
||||
result->next->prev = result->prev;
|
||||
result->prev->next = result->next;
|
||||
block_zero_struct(result);
|
||||
|
||||
result->transient.next->transient.prev = result->transient.prev;
|
||||
result->transient.prev->transient.next = result->transient.next;
|
||||
block_zero_struct(&result->transient);
|
||||
|
||||
result->transient.in_use = true;
|
||||
init_query_set(&result->transient.query_set);
|
||||
result->transient.lifetime_object = lifetime_alloc_object(heap, lifetime_allocator, DynamicWorkspace_View, result);
|
||||
result->in_use = true;
|
||||
init_query_set(&result->query_set);
|
||||
result->lifetime_object = lifetime_alloc_object(heap, lifetime_allocator, DynamicWorkspace_View, result);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
@ -43,85 +51,83 @@ live_set_free_view(Heap *heap, Lifetime_Allocator *lifetime_allocator, Live_View
|
|||
Assert(live_set->count > 0);
|
||||
--live_set->count;
|
||||
|
||||
if (view->transient.ui_control.items != 0){
|
||||
heap_free(heap, view->transient.ui_control.items);
|
||||
if (view->ui_control.items != 0){
|
||||
heap_free(heap, view->ui_control.items);
|
||||
}
|
||||
|
||||
view->transient.next = live_set->free_sentinel.transient.next;
|
||||
view->transient.prev = &live_set->free_sentinel;
|
||||
live_set->free_sentinel.transient.next = view;
|
||||
view->transient.next->transient.prev = view;
|
||||
view->transient.in_use = false;
|
||||
view->next = live_set->free_sentinel.next;
|
||||
view->prev = &live_set->free_sentinel;
|
||||
live_set->free_sentinel.next = view;
|
||||
view->next->prev = view;
|
||||
view->in_use = false;
|
||||
|
||||
lifetime_free_object(heap, lifetime_allocator, view->transient.lifetime_object);
|
||||
lifetime_free_object(heap, lifetime_allocator, view->lifetime_object);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
// TODO(allen): Switch over to using an i32 for these.
|
||||
internal f32
|
||||
internal File_Edit_Positions
|
||||
view_get_edit_pos(View *view){
|
||||
return(view->edit_pos_);
|
||||
}
|
||||
|
||||
internal void
|
||||
view_set_edit_pos(View *view, File_Edit_Positions edit_pos){
|
||||
view->edit_pos_ = edit_pos;
|
||||
view->file_data.file->state.edit_pos_most_recent = edit_pos;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal i32
|
||||
view_width(View *view){
|
||||
i32_Rect file_rect = view->transient.file_region;
|
||||
f32 result = (f32)(file_rect.x1 - file_rect.x0);
|
||||
return (result);
|
||||
return(rect_width(view->file_region));
|
||||
}
|
||||
|
||||
internal f32
|
||||
internal i32
|
||||
view_height(View *view){
|
||||
i32_Rect file_rect = view->transient.file_region;
|
||||
f32 result = (f32)(file_rect.y1 - file_rect.y0);
|
||||
return (result);
|
||||
return(rect_height(view->file_region));
|
||||
}
|
||||
|
||||
internal Vec2
|
||||
view_get_cursor_xy(View *view){
|
||||
Full_Cursor *cursor = 0;
|
||||
if (view->transient.file_data.show_temp_highlight){
|
||||
cursor = &view->transient.file_data.temp_highlight;
|
||||
internal Vec2_i32
|
||||
view_get_cursor_xy(System_Functions *system, View *view){
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
||||
Full_Cursor cursor = file_compute_cursor(system, view->file_data.file, seek_pos(edit_pos.cursor_pos));
|
||||
Vec2_i32 result = {};
|
||||
if (view->file_data.file->settings.unwrapped_lines){
|
||||
result = V2i32((i32)cursor.unwrapped_x, (i32)cursor.unwrapped_y);
|
||||
}
|
||||
else{
|
||||
cursor = &view->transient.edit_pos.cursor;
|
||||
}
|
||||
Vec2 result = V2(cursor->wrapped_x, cursor->wrapped_y);
|
||||
if (view->transient.file_data.file->settings.unwrapped_lines){
|
||||
result.x = cursor->unwrapped_x;
|
||||
result.y = cursor->unwrapped_y;
|
||||
result = V2i32((i32)cursor.wrapped_x, (i32)cursor.wrapped_y);
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal Cursor_Limits
|
||||
view_cursor_limits(View *view){
|
||||
i32 line_height = view->line_height;
|
||||
i32 visible_height = view_height(view);
|
||||
Cursor_Limits limits = {};
|
||||
|
||||
f32 line_height = (f32)view->transient.line_height;
|
||||
f32 visible_height = view_height(view);
|
||||
|
||||
limits.max = visible_height - line_height*3.f;
|
||||
limits.min = line_height * 2;
|
||||
|
||||
limits.max = visible_height - line_height*3;
|
||||
limits.min = line_height*2;
|
||||
if (limits.max - limits.min <= line_height){
|
||||
if (visible_height >= line_height){
|
||||
limits.max = visible_height - line_height;
|
||||
limits.min = -line_height;
|
||||
}
|
||||
else{
|
||||
limits.max = visible_height;
|
||||
limits.min = -line_height;
|
||||
}
|
||||
limits.min = 0;
|
||||
}
|
||||
|
||||
limits.max = (limits.max > 0)?(limits.max):(0);
|
||||
limits.min = (limits.min > 0)?(limits.min):(0);
|
||||
|
||||
limits.delta = clamp_top(line_height*3.f, (limits.max - limits.min)*.5f);
|
||||
|
||||
limits.max = clamp_bottom(0, limits.max);
|
||||
limits.min = clamp(0, limits.min, limits.max);
|
||||
limits.delta = clamp_top(line_height*5, (limits.max - limits.min + 1)/2);
|
||||
return(limits);
|
||||
}
|
||||
|
||||
internal i32
|
||||
view_compute_max_target_y_from_bottom_y(View *view, f32 max_item_y){
|
||||
i32 line_height = view->transient.line_height;
|
||||
i32 line_height = view->line_height;
|
||||
f32 height = clamp_bottom((f32)line_height, view_height(view));
|
||||
f32 max_target_y = clamp_bottom(0.f, max_item_y - height*0.5f);
|
||||
return(ceil32(max_target_y));
|
||||
|
@ -129,8 +135,8 @@ view_compute_max_target_y_from_bottom_y(View *view, f32 max_item_y){
|
|||
|
||||
internal i32
|
||||
view_compute_max_target_y(View *view){
|
||||
i32 line_height = view->transient.line_height;
|
||||
Editing_File *file = view->transient.file_data.file;
|
||||
i32 line_height = view->line_height;
|
||||
Editing_File *file = view->file_data.file;
|
||||
Gap_Buffer *buffer = &file->state.buffer;
|
||||
i32 lowest_line = buffer->line_count;
|
||||
if (!file->settings.unwrapped_lines){
|
||||
|
@ -142,8 +148,8 @@ view_compute_max_target_y(View *view){
|
|||
internal u32
|
||||
view_lock_flags(View *view){
|
||||
u32 result = AccessOpen;
|
||||
File_Viewing_Data *data = &view->transient.file_data;
|
||||
if (view->transient.ui_mode){
|
||||
File_Viewing_Data *data = &view->file_data;
|
||||
if (view->ui_mode){
|
||||
result |= AccessHidden;
|
||||
}
|
||||
if (data->file_locked || (data->file && data->file->settings.read_only)){
|
||||
|
@ -155,64 +161,58 @@ view_lock_flags(View *view){
|
|||
////////////////////////////////
|
||||
|
||||
internal b32
|
||||
view_move_view_to_cursor(View *view, GUI_Scroll_Vars *scroll, b32 center_view){
|
||||
b32 result = 0;
|
||||
f32 max_x = view_width(view);
|
||||
view_move_view_to_cursor(System_Functions *system, View *view, GUI_Scroll_Vars *scroll){
|
||||
b32 result = false;
|
||||
i32 max_x = view_width(view);
|
||||
i32 max_y = view_compute_max_target_y(view);
|
||||
|
||||
Vec2 cursor = view_get_cursor_xy(view);
|
||||
Vec2_i32 cursor = view_get_cursor_xy(system, view);
|
||||
|
||||
GUI_Scroll_Vars scroll_vars = *scroll;
|
||||
i32 target_x = scroll_vars.target_x;
|
||||
i32 target_y = scroll_vars.target_y;
|
||||
|
||||
Cursor_Limits limits = view_cursor_limits(view);
|
||||
|
||||
if (cursor.y > target_y + limits.max){
|
||||
if (center_view){
|
||||
target_y = round32(cursor.y - limits.max*.5f);
|
||||
}
|
||||
else{
|
||||
target_y = ceil32(cursor.y - limits.max + limits.delta);
|
||||
}
|
||||
target_y = cursor.y - limits.max + limits.delta;
|
||||
}
|
||||
if (cursor.y < target_y + limits.min){
|
||||
if (center_view){
|
||||
target_y = round32(cursor.y - limits.max*.5f);
|
||||
}
|
||||
else{
|
||||
target_y = floor32(cursor.y - limits.delta - limits.min);
|
||||
}
|
||||
target_y = cursor.y - limits.delta - limits.min;
|
||||
}
|
||||
|
||||
target_y = clamp(0, target_y, max_y);
|
||||
|
||||
if (cursor.x >= target_x + max_x){
|
||||
target_x = ceil32(cursor.x - max_x/2);
|
||||
target_x = cursor.x - max_x/2;
|
||||
}
|
||||
else if (cursor.x < target_x){
|
||||
target_x = floor32(Max(0, cursor.x - max_x/2));
|
||||
target_x = clamp_bottom(0, cursor.x - max_x/2);
|
||||
}
|
||||
|
||||
if (target_x != scroll_vars.target_x || target_y != scroll_vars.target_y){
|
||||
scroll->target_x = target_x;
|
||||
scroll->target_y = target_y;
|
||||
result = 1;
|
||||
result = true;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal b32
|
||||
view_move_cursor_to_view(System_Functions *system, View *view, GUI_Scroll_Vars scroll, Full_Cursor *cursor, f32 preferred_x){
|
||||
i32 line_height = view->transient.line_height;
|
||||
f32 old_cursor_y = cursor->wrapped_y;
|
||||
Editing_File *file = view->transient.file_data.file;
|
||||
view_move_cursor_to_view(System_Functions *system, View *view, GUI_Scroll_Vars scroll, i32 *pos_in_out, f32 preferred_x){
|
||||
Editing_File *file = view->file_data.file;
|
||||
Full_Cursor cursor = file_compute_cursor(system, file, seek_pos(*pos_in_out));
|
||||
|
||||
i32 line_height = view->line_height;
|
||||
f32 old_cursor_y = 0.f;
|
||||
if (file->settings.unwrapped_lines){
|
||||
old_cursor_y = cursor->unwrapped_y;
|
||||
old_cursor_y = cursor.unwrapped_y;
|
||||
}
|
||||
else{
|
||||
old_cursor_y = cursor.wrapped_y;
|
||||
}
|
||||
f32 cursor_y = old_cursor_y;
|
||||
f32 target_y = scroll.target_y + view->transient.widget_height;
|
||||
f32 target_y = scroll.target_y + view->widget_height;
|
||||
|
||||
Cursor_Limits limits = view_cursor_limits(view);
|
||||
|
||||
|
@ -232,77 +232,87 @@ view_move_cursor_to_view(System_Functions *system, View *view, GUI_Scroll_Vars s
|
|||
cursor_y -= line_height;
|
||||
}
|
||||
Buffer_Seek seek = seek_xy(preferred_x, cursor_y, false, file->settings.unwrapped_lines);
|
||||
*cursor = file_compute_cursor(system, file, seek, false);
|
||||
cursor = file_compute_cursor(system, file, seek);
|
||||
*pos_in_out = cursor.pos;
|
||||
result = true;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal b32
|
||||
view_has_unwrapped_lines(View *view){
|
||||
return(view->file_data.file->settings.unwrapped_lines);
|
||||
}
|
||||
|
||||
internal void
|
||||
view_set_cursor(View *view, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapped_lines){
|
||||
edit_pos_set_cursor(&view->transient.edit_pos, cursor, set_preferred_x, unwrapped_lines);
|
||||
GUI_Scroll_Vars scroll = view->transient.edit_pos.scroll;
|
||||
if (view_move_view_to_cursor(view, &scroll, 0)){
|
||||
view->transient.edit_pos.scroll = scroll;
|
||||
view_set_preferred_x(View *view, Full_Cursor cursor){
|
||||
if (view_has_unwrapped_lines(view)){
|
||||
view->preferred_x = cursor.unwrapped_x;
|
||||
}
|
||||
else{
|
||||
view->preferred_x = cursor.wrapped_x;
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
view_set_preferred_x_to_current_position(System_Functions *system, View *view){
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
||||
Full_Cursor cursor = file_compute_cursor(system, view->file_data.file, seek_pos(edit_pos.cursor_pos));
|
||||
view_set_preferred_x(view, cursor);
|
||||
}
|
||||
|
||||
internal void
|
||||
view_set_cursor(System_Functions *system, View *view, Full_Cursor cursor, b32 set_preferred_x){
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
||||
file_edit_positions_set_cursor(&edit_pos, cursor.pos);
|
||||
if (set_preferred_x){
|
||||
view_set_preferred_x(view, cursor);
|
||||
}
|
||||
view_set_edit_pos(view, edit_pos);
|
||||
GUI_Scroll_Vars scroll = edit_pos.scroll;
|
||||
if (view_move_view_to_cursor(system, view, &scroll)){
|
||||
edit_pos.scroll = scroll;
|
||||
view_set_edit_pos(view, edit_pos);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
view_set_scroll(System_Functions *system, View *view, GUI_Scroll_Vars scroll){
|
||||
edit_pos_set_scroll(&view->transient.edit_pos, scroll);
|
||||
Full_Cursor cursor = view->transient.edit_pos.cursor;
|
||||
if (view_move_cursor_to_view(system, view, view->transient.edit_pos.scroll, &cursor, view->transient.edit_pos.preferred_x)){
|
||||
view->transient.edit_pos.cursor = cursor;
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
||||
file_edit_positions_set_scroll(&edit_pos, scroll);
|
||||
view_set_edit_pos(view, edit_pos);
|
||||
i32 pos = edit_pos.cursor_pos;
|
||||
if (view_move_cursor_to_view(system, view, edit_pos.scroll, &pos, view->preferred_x)){
|
||||
Full_Cursor cursor = file_compute_cursor(system, view->file_data.file, seek_pos(pos));
|
||||
edit_pos.cursor_pos = cursor.pos;
|
||||
view_set_edit_pos(view, edit_pos);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
view_set_cursor_and_scroll(View *view, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapped_lines, GUI_Scroll_Vars scroll){
|
||||
File_Edit_Positions *edit_pos = &view->transient.edit_pos;
|
||||
edit_pos_set_cursor(edit_pos, cursor, set_preferred_x, unwrapped_lines);
|
||||
edit_pos_set_scroll(edit_pos, scroll);
|
||||
edit_pos->last_set_type = EditPos_None;
|
||||
}
|
||||
|
||||
internal Relative_Scrolling
|
||||
view_get_relative_scrolling(View *view){
|
||||
Vec2 cursor = view_get_cursor_xy(view);
|
||||
Relative_Scrolling result = {};
|
||||
result.scroll_y = cursor.y - view->transient.edit_pos.scroll.scroll_y;
|
||||
result.target_y = cursor.y - view->transient.edit_pos.scroll.target_y;
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
view_set_relative_scrolling(View *view, Relative_Scrolling scrolling){
|
||||
Vec2 cursor = view_get_cursor_xy(view);
|
||||
view->transient.edit_pos.scroll.scroll_y = cursor.y - scrolling.scroll_y;
|
||||
view->transient.edit_pos.scroll.target_y = round32(clamp_bottom(0.f, cursor.y - scrolling.target_y));
|
||||
view_set_cursor_and_scroll(View *view, Full_Cursor cursor, b32 set_preferred_x, GUI_Scroll_Vars scroll){
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
||||
file_edit_positions_set_cursor(&edit_pos, cursor.pos);
|
||||
if (set_preferred_x){
|
||||
view_set_preferred_x(view, cursor);
|
||||
}
|
||||
file_edit_positions_set_scroll(&edit_pos, scroll);
|
||||
edit_pos.last_set_type = EditPos_None;
|
||||
view_set_edit_pos(view, edit_pos);
|
||||
}
|
||||
|
||||
internal void
|
||||
view_cursor_move(System_Functions *system, View *view, i32 pos){
|
||||
Editing_File *file = view->transient.file_data.file;
|
||||
Editing_File *file = view->file_data.file;
|
||||
Assert(file != 0);
|
||||
Full_Cursor cursor = file_compute_cursor(system, file, seek_pos(pos), 0);
|
||||
view_set_cursor(view, cursor, true, file->settings.unwrapped_lines);
|
||||
view->transient.file_data.show_temp_highlight = false;
|
||||
}
|
||||
|
||||
internal void
|
||||
view_set_temp_highlight(System_Functions *system, View *view, i32 pos, i32 end_pos){
|
||||
Editing_File *file = view->transient.file_data.file;
|
||||
Assert(file != 0);
|
||||
view->transient.file_data.temp_highlight = file_compute_cursor(system, file, seek_pos(pos), 0);
|
||||
view->transient.file_data.temp_highlight_end_pos = end_pos;
|
||||
view->transient.file_data.show_temp_highlight = true;
|
||||
view_set_cursor(view, view->transient.file_data.temp_highlight, 0, file->settings.unwrapped_lines);
|
||||
Full_Cursor cursor = file_compute_cursor(system, file, seek_pos(pos));
|
||||
view_set_cursor(system, view, cursor, true);
|
||||
}
|
||||
|
||||
internal void
|
||||
view_post_paste_effect(View *view, f32 seconds, i32 start, i32 size, u32 color){
|
||||
Editing_File *file = view->transient.file_data.file;
|
||||
Editing_File *file = view->file_data.file;
|
||||
file->state.paste_effect.start = start;
|
||||
file->state.paste_effect.end = start + size;
|
||||
file->state.paste_effect.color = color;
|
||||
|
@ -316,23 +326,22 @@ internal void
|
|||
view_set_file(System_Functions *system, Models *models, View *view, Editing_File *file){
|
||||
Assert(file != 0);
|
||||
|
||||
Editing_File *old_file = view->transient.file_data.file;
|
||||
Editing_File *old_file = view->file_data.file;
|
||||
if (old_file != 0){
|
||||
file_touch(&models->working_set, old_file);
|
||||
edit_pos_push(old_file, view->transient.edit_pos);
|
||||
file_edit_positions_push(old_file, view_get_edit_pos(view));
|
||||
}
|
||||
|
||||
block_zero(&view->transient.file_data, sizeof(view->transient.file_data));
|
||||
view->transient.file_data.file = file;
|
||||
block_zero(&view->file_data, sizeof(view->file_data));
|
||||
view->file_data.file = file;
|
||||
|
||||
view->transient.edit_pos = edit_pos_pop(file);
|
||||
File_Edit_Positions edit_pos = file_edit_positions_pop(file);
|
||||
view_set_edit_pos(view, edit_pos);
|
||||
view->mark = edit_pos.cursor_pos;
|
||||
view_set_preferred_x_to_current_position(system, view);
|
||||
|
||||
Font_Pointers font = system->font.get_pointers_by_id(file->settings.font_id);
|
||||
view->transient.line_height = font.metrics->height;
|
||||
|
||||
if (view->transient.edit_pos.cursor.line == 0){
|
||||
view_cursor_move(system, view, 0);
|
||||
}
|
||||
view->line_height = font.metrics->height;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
@ -344,7 +353,7 @@ file_is_viewed(Layout *layout, Editing_File *file){
|
|||
panel != 0;
|
||||
panel = layout_get_next_open_panel(layout, panel)){
|
||||
View *view = panel->view;
|
||||
if (view->transient.file_data.file == file){
|
||||
if (view->file_data.file == file){
|
||||
is_viewed = true;
|
||||
break;
|
||||
}
|
||||
|
@ -355,22 +364,14 @@ file_is_viewed(Layout *layout, Editing_File *file){
|
|||
internal void
|
||||
adjust_views_looking_at_file_to_new_cursor(System_Functions *system, Models *models, Editing_File *file){
|
||||
Layout *layout = &models->layout;
|
||||
|
||||
for (Panel *panel = layout_get_first_open_panel(layout);
|
||||
panel != 0;
|
||||
panel = layout_get_next_open_panel(layout, panel)){
|
||||
View *view = panel->view;
|
||||
if (view->transient.file_data.file == file){
|
||||
if (!view->transient.file_data.show_temp_highlight){
|
||||
i32 pos = view->transient.edit_pos.cursor.pos;
|
||||
Full_Cursor cursor = file_compute_cursor(system, file, seek_pos(pos), 0);
|
||||
view_set_cursor(view, cursor, 1, file->settings.unwrapped_lines);
|
||||
}
|
||||
else{
|
||||
i32 pos = view->transient.file_data.temp_highlight.pos;
|
||||
i32 end = view->transient.file_data.temp_highlight_end_pos;
|
||||
view_set_temp_highlight(system, view, pos, end);
|
||||
}
|
||||
if (view->file_data.file == file){
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
||||
Full_Cursor cursor = file_compute_cursor(system, file, seek_pos(edit_pos.cursor_pos));
|
||||
view_set_cursor(system, view, cursor, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -383,13 +384,12 @@ file_full_remeasure(System_Functions *system, Models *models, Editing_File *file
|
|||
adjust_views_looking_at_file_to_new_cursor(system, models, file);
|
||||
|
||||
Layout *layout = &models->layout;
|
||||
|
||||
for (Panel *panel = layout_get_first_open_panel(layout);
|
||||
panel != 0;
|
||||
panel = layout_get_next_open_panel(layout, panel)){
|
||||
View *view = panel->view;
|
||||
if (view->transient.file_data.file == file){
|
||||
view->transient.line_height = font.metrics->height;
|
||||
if (view->file_data.file == file){
|
||||
view->line_height = font.metrics->height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -476,9 +476,7 @@ finalize_color(Theme *theme_data, u32 color){
|
|||
}
|
||||
|
||||
internal void
|
||||
get_visual_markers(Partition *arena, Dynamic_Workspace *workspace,
|
||||
Range range, Buffer_ID buffer_id, i32 view_index,
|
||||
Theme *theme_data){
|
||||
get_visual_markers(Partition *arena, Dynamic_Workspace *workspace, Range range, Buffer_ID buffer_id, i32 view_index, Theme *theme_data){
|
||||
View_ID view_id = view_index + 1;
|
||||
for (Managed_Buffer_Markers_Header *node = workspace->buffer_markers_list.first;
|
||||
node != 0;
|
||||
|
@ -549,8 +547,9 @@ get_visual_markers(Partition *arena, Dynamic_Workspace *workspace,
|
|||
if (range_b.first > range_b.one_past_last){
|
||||
Swap(i32, range_b.first, range_b.one_past_last);
|
||||
}
|
||||
if (!((range.min - range_b.max <= 0) &&
|
||||
(range.max - range_b.min >= 0))) continue;
|
||||
if (!((range.min - range_b.max <= 0) && (range.max - range_b.min >= 0))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Render_Marker *render_marker = push_array(arena, Render_Marker, 1);
|
||||
render_marker->type = type;
|
||||
|
@ -775,7 +774,7 @@ internal void
|
|||
render_loaded_file_in_view__inner(Models *models, Render_Target *target, View *view,
|
||||
i32_Rect rect, Full_Cursor render_cursor, Range on_screen_range,
|
||||
Buffer_Render_Item *items, i32 item_count){
|
||||
Editing_File *file = view->transient.file_data.file;
|
||||
Editing_File *file = view->file_data.file;
|
||||
Partition *part = &models->mem.part;
|
||||
Style *style = &models->styles.styles[0];
|
||||
|
||||
|
@ -794,7 +793,7 @@ render_loaded_file_in_view__inner(Models *models, Render_Target *target, View *v
|
|||
{
|
||||
Lifetime_Object *lifetime_object = file->lifetime_object;
|
||||
Buffer_ID buffer_id = file->id.id;
|
||||
i32 view_index = view->persistent.id;
|
||||
i32 view_index = view_get_index(&models->live_set, view);
|
||||
Theme *theme_data = &style->theme;
|
||||
|
||||
get_visual_markers(part, &lifetime_object->workspace, on_screen_range, buffer_id, view_index, theme_data);
|
||||
|
@ -970,7 +969,7 @@ render_loaded_file_in_view__inner(Models *models, Render_Target *target, View *v
|
|||
char_color = ghost_color;
|
||||
}
|
||||
|
||||
if (view->transient.file_data.show_whitespace && highlight_color == 0 && codepoint_is_whitespace(item->codepoint)){
|
||||
if (view->file_data.show_whitespace && highlight_color == 0 && codepoint_is_whitespace(item->codepoint)){
|
||||
highlight_this_color = style->theme.colors[Stag_Highlight_White];
|
||||
}
|
||||
else{
|
||||
|
@ -1170,16 +1169,48 @@ do_core_render(Application_Links *app){
|
|||
Range on_screen_range = models->render_range;
|
||||
Buffer_Render_Item *items = models->render_items;
|
||||
i32 item_count = models->render_item_count;
|
||||
render_loaded_file_in_view__inner(models, target, view,
|
||||
rect, render_cursor, on_screen_range,
|
||||
items, item_count);
|
||||
render_loaded_file_in_view__inner(models, target, view, rect, render_cursor, on_screen_range, items, item_count);
|
||||
}
|
||||
|
||||
internal Full_Cursor
|
||||
view_get_render_cursor(System_Functions *system, View *view, f32 scroll_y){
|
||||
Full_Cursor result = {};
|
||||
Editing_File *file = view->file_data.file;
|
||||
if (file->settings.unwrapped_lines){
|
||||
result = file_compute_cursor_hint(system, file, seek_unwrapped_xy(0, scroll_y, false));
|
||||
}
|
||||
else{
|
||||
result = file_compute_cursor(system, file, seek_wrapped_xy(0, scroll_y, false));
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal Full_Cursor
|
||||
view_get_render_cursor(System_Functions *system, View *view){
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
||||
f32 scroll_y = edit_pos.scroll.scroll_y;
|
||||
// NOTE(allen): For now we will temporarily adjust scroll_y to try
|
||||
// to prevent the view moving around until floating sections are added
|
||||
// to the gui system.
|
||||
scroll_y += view->widget_height;
|
||||
return(view_get_render_cursor(system, view, scroll_y));
|
||||
}
|
||||
|
||||
internal Full_Cursor
|
||||
view_get_render_cursor_target(System_Functions *system, View *view){
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
||||
f32 scroll_y = (f32)edit_pos.scroll.target_y;
|
||||
// NOTE(allen): For now we will temporarily adjust scroll_y to try
|
||||
// to prevent the view moving around until floating sections are added
|
||||
// to the gui system.
|
||||
scroll_y += view->widget_height;
|
||||
return(view_get_render_cursor(system, view, scroll_y));
|
||||
}
|
||||
|
||||
internal void
|
||||
render_loaded_file_in_view(System_Functions *system, View *view, Models *models,
|
||||
i32_Rect rect, b32 is_active, Render_Target *target){
|
||||
Editing_File *file = view->transient.file_data.file;
|
||||
i32 line_height = view->transient.line_height;
|
||||
render_loaded_file_in_view(System_Functions *system, View *view, Models *models, i32_Rect rect, b32 is_active, Render_Target *target){
|
||||
Editing_File *file = view->file_data.file;
|
||||
i32 line_height = view->line_height;
|
||||
|
||||
f32 max_x = (f32)file->settings.display_width;
|
||||
i32 max_y = rect.y1 - rect.y0 + line_height;
|
||||
|
@ -1202,23 +1233,21 @@ render_loaded_file_in_view(System_Functions *system, View *view, Models *models,
|
|||
Face_ID font_id = file->settings.font_id;
|
||||
Font_Pointers font = system->font.get_pointers_by_id(font_id);
|
||||
|
||||
f32 scroll_x = view->transient.edit_pos.scroll.scroll_x;
|
||||
f32 scroll_y = view->transient.edit_pos.scroll.scroll_y;
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
||||
f32 scroll_x = edit_pos.scroll.scroll_x;
|
||||
f32 scroll_y = edit_pos.scroll.scroll_y;
|
||||
|
||||
// NOTE(allen): For now we will temporarily adjust scroll_y to try
|
||||
// to prevent the view moving around until floating sections are added
|
||||
// to the gui system.
|
||||
scroll_y += view->transient.widget_height;
|
||||
scroll_y += view->widget_height;
|
||||
|
||||
Full_Cursor render_cursor = {};
|
||||
if (!file->settings.unwrapped_lines){
|
||||
render_cursor = file_compute_cursor(system, file, seek_wrapped_xy(0, scroll_y, 0), true);
|
||||
}
|
||||
else{
|
||||
render_cursor = file_compute_cursor(system, file, seek_unwrapped_xy(0, scroll_y, 0), true);
|
||||
}
|
||||
Full_Cursor render_cursor = view_get_render_cursor(system, view);
|
||||
|
||||
view->transient.edit_pos.scroll_i = render_cursor.pos;
|
||||
#if 0
|
||||
// TODO(allen): do(eliminate scroll_i nonsense)
|
||||
view->edit_pos_.scroll_i = render_cursor.pos;
|
||||
#endif
|
||||
|
||||
i32 item_count = 0;
|
||||
i32 end_pos = 0;
|
||||
|
@ -1297,13 +1326,14 @@ render_loaded_file_in_view(System_Functions *system, View *view, Models *models,
|
|||
////////////////////////////////
|
||||
|
||||
if (models->render_caller != 0){
|
||||
View_ID view_id = view_get_id(&models->live_set, view);
|
||||
models->render_view = view;
|
||||
models->render_rect = rect;
|
||||
models->render_cursor = render_cursor;
|
||||
models->render_range = on_screen_range;
|
||||
models->render_items = items;
|
||||
models->render_item_count = item_count;
|
||||
models->render_caller(&models->app_links, view->persistent.id + 1, on_screen_range, do_core_render);
|
||||
models->render_caller(&models->app_links, view_id, on_screen_range, do_core_render);
|
||||
models->render_view = 0;
|
||||
}
|
||||
else{
|
||||
|
|
71
4ed_view.h
71
4ed_view.h
|
@ -12,24 +12,13 @@
|
|||
#if !defined(FRED_VIEW_H)
|
||||
#define FRED_VIEW_H
|
||||
|
||||
struct View_Persistent{
|
||||
i32 id;
|
||||
Coroutine_Head *coroutine;
|
||||
};
|
||||
|
||||
struct File_Viewing_Data{
|
||||
Editing_File *file;
|
||||
|
||||
Full_Cursor temp_highlight;
|
||||
i32 temp_highlight_end_pos;
|
||||
b32 show_temp_highlight;
|
||||
|
||||
b32 show_whitespace;
|
||||
b32 file_locked;
|
||||
};
|
||||
global File_Viewing_Data null_file_viewing_data = {};
|
||||
|
||||
struct View_Transient{
|
||||
struct View{
|
||||
struct View *next;
|
||||
struct View *prev;
|
||||
struct Panel *panel;
|
||||
|
@ -42,36 +31,31 @@ struct View_Transient{
|
|||
i32_Rect file_region;
|
||||
|
||||
i32_Rect scroll_region;
|
||||
File_Edit_Positions edit_pos;
|
||||
File_Edit_Positions edit_pos_;
|
||||
i32 mark;
|
||||
f32 preferred_x;
|
||||
|
||||
i32 temp_view_top_left_pos;
|
||||
i32 temp_view_top_left_target_pos;
|
||||
|
||||
b32 ui_mode;
|
||||
UI_Quit_Function_Type *ui_quit;
|
||||
UI_Control ui_control;
|
||||
GUI_Scroll_Vars ui_scroll;
|
||||
Vec2_i32 prev_target;
|
||||
i32 ui_map_id;
|
||||
|
||||
b32 hide_scrollbar;
|
||||
b32 hide_file_bar;
|
||||
|
||||
b32 changed_context_in_step;
|
||||
|
||||
// misc
|
||||
|
||||
// TODO(allen): Can we burn line_height to the ground now?
|
||||
// It's what I've always wanted!!!! :D
|
||||
i32 line_height;
|
||||
|
||||
// TODO(allen): Do I still use mode?
|
||||
Query_Set query_set;
|
||||
f32 widget_height;
|
||||
|
||||
b32 reinit_scrolling;
|
||||
};
|
||||
|
||||
struct View{
|
||||
// TODO(allen): Why is this this way?
|
||||
View_Persistent persistent;
|
||||
View_Transient transient;
|
||||
};
|
||||
|
||||
struct Live_Views{
|
||||
|
@ -82,9 +66,9 @@ struct Live_Views{
|
|||
};
|
||||
|
||||
struct Cursor_Limits{
|
||||
f32 min;
|
||||
f32 max;
|
||||
f32 delta;
|
||||
i32 min;
|
||||
i32 max;
|
||||
i32 delta;
|
||||
};
|
||||
|
||||
enum{
|
||||
|
@ -114,32 +98,6 @@ struct Shift_Information{
|
|||
i32 amount;
|
||||
};
|
||||
|
||||
struct Edit_Spec{
|
||||
u8 *str;
|
||||
Edit_Step step;
|
||||
};
|
||||
|
||||
struct Relative_Scrolling{
|
||||
f32 scroll_x;
|
||||
f32 scroll_y;
|
||||
f32 target_x;
|
||||
f32 target_y;
|
||||
};
|
||||
|
||||
struct Cursor_Fix_Descriptor{
|
||||
b32 is_batch;
|
||||
union{
|
||||
struct{
|
||||
Buffer_Edit *batch;
|
||||
i32 batch_size;
|
||||
};
|
||||
struct{
|
||||
i32 start, end;
|
||||
i32 shift_amount;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
struct File_Bar{
|
||||
f32 pos_x;
|
||||
f32 pos_y;
|
||||
|
@ -196,13 +154,6 @@ enum{
|
|||
FileCreateFlag_ReadOnly = 1,
|
||||
};
|
||||
|
||||
typedef i32 History_Mode;
|
||||
enum{
|
||||
hist_normal,
|
||||
hist_backward,
|
||||
hist_forward
|
||||
};
|
||||
|
||||
struct Render_Marker{
|
||||
Marker_Visual_Type type;
|
||||
u32 color;
|
||||
|
|
105
4ed_view_ui.cpp
105
4ed_view_ui.cpp
|
@ -47,15 +47,14 @@ global_const Style_Color_Edit colors_to_edit[] = {
|
|||
};
|
||||
|
||||
internal Input_Process_Result
|
||||
do_step_file_view(System_Functions *system, View *view, Models *models, i32_Rect rect, b32 is_active, f32 dt, GUI_Scroll_Vars scroll, i32 max_y){
|
||||
scroll.target_y = clamp(0, scroll.target_y, max_y);
|
||||
|
||||
do_step_file_view(System_Functions *system, Models *models, View *view, i32_Rect rect, b32 is_active, f32 dt, GUI_Scroll_Vars scroll, i32 max_y){
|
||||
Input_Process_Result result = {};
|
||||
scroll.target_y = clamp(0, scroll.target_y, max_y);
|
||||
result.scroll = scroll;
|
||||
|
||||
i32 line_height = view->transient.line_height;
|
||||
i32 line_height = view->line_height;
|
||||
|
||||
if (!view->transient.hide_file_bar){
|
||||
if (!view->hide_file_bar){
|
||||
i32_Rect top_bar_rect = {};
|
||||
top_bar_rect.x0 = rect.x0;
|
||||
top_bar_rect.y0 = rect.y0;
|
||||
|
@ -63,70 +62,37 @@ do_step_file_view(System_Functions *system, View *view, Models *models, i32_Rect
|
|||
top_bar_rect.y1 = rect.y0 + line_height + 2;
|
||||
rect.y0 = top_bar_rect.y1;
|
||||
}
|
||||
view->file_region = rect;
|
||||
|
||||
i32 bar_count = 0;
|
||||
for (Query_Slot *slot = view->transient.query_set.used_slot;
|
||||
for (Query_Slot *slot = view->query_set.used_slot;
|
||||
slot != 0;
|
||||
slot = slot->next, ++bar_count);
|
||||
view->transient.widget_height = (f32)bar_count*(view->transient.line_height + 2);
|
||||
view->widget_height = (f32)bar_count*(view->line_height + 2);
|
||||
|
||||
Editing_File *file = view->transient.file_data.file;
|
||||
|
||||
if (!view->transient.ui_mode){
|
||||
view->transient.file_region = rect;
|
||||
|
||||
if (view->transient.reinit_scrolling){
|
||||
view->transient.reinit_scrolling = false;
|
||||
result.is_animating = true;
|
||||
|
||||
i32 target_x = 0;
|
||||
i32 target_y = 0;
|
||||
if (file_is_ready(file)){
|
||||
Vec2 cursor = view_get_cursor_xy(view);
|
||||
|
||||
f32 width = view_width(view);
|
||||
f32 height = view_height(view);
|
||||
|
||||
if (cursor.x >= target_x + width){
|
||||
target_x = round32(cursor.x - width*.35f);
|
||||
}
|
||||
|
||||
target_y = clamp_bottom(0, floor32(cursor.y - height*.5f));
|
||||
}
|
||||
|
||||
result.scroll.target_y = target_y;
|
||||
result.scroll.scroll_y = (f32)target_y;
|
||||
result.scroll.prev_target_y = -1000;
|
||||
|
||||
result.scroll.target_x = target_x;
|
||||
result.scroll.scroll_x = (f32)target_x;
|
||||
result.scroll.prev_target_x = -1000;
|
||||
}
|
||||
}
|
||||
Editing_File *file = view->file_data.file;
|
||||
|
||||
// TODO(allen): do(eliminate the built in paste_effect)
|
||||
if (!file->is_loading && file->state.paste_effect.seconds_down > 0.f){
|
||||
file->state.paste_effect.seconds_down -= dt;
|
||||
result.is_animating = true;
|
||||
}
|
||||
|
||||
{
|
||||
GUI_Scroll_Vars scroll_vars = result.scroll;
|
||||
b32 is_new_target = (scroll_vars.target_x != scroll_vars.prev_target_x ||
|
||||
scroll_vars.target_y != scroll_vars.prev_target_y);
|
||||
|
||||
f32 target_x = (f32)scroll_vars.target_x;
|
||||
f32 target_y = (f32)scroll_vars.target_y;
|
||||
|
||||
if (models->scroll_rule(target_x, target_y, &scroll_vars.scroll_x, &scroll_vars.scroll_y, (view->persistent.id) + 1, is_new_target, dt)){
|
||||
result.is_animating = true;
|
||||
}
|
||||
|
||||
scroll_vars.prev_target_x = scroll_vars.target_x;
|
||||
scroll_vars.prev_target_y = scroll_vars.target_y;
|
||||
|
||||
result.scroll = scroll_vars;
|
||||
// NOTE(allen): call scroll rule hook
|
||||
b32 is_new_target = (result.scroll.target_x != view->prev_target.x ||
|
||||
result.scroll.target_y != view->prev_target.y);
|
||||
|
||||
f32 target_x = (f32)result.scroll.target_x;
|
||||
f32 target_y = (f32)result.scroll.target_y;
|
||||
|
||||
View_ID view_id = view_get_id(&models->live_set, view);
|
||||
if (models->scroll_rule(target_x, target_y, &result.scroll.scroll_x, &result.scroll.scroll_y, view_id, is_new_target, dt)){
|
||||
result.is_animating = true;
|
||||
}
|
||||
|
||||
view->prev_target.x = result.scroll.target_x;
|
||||
view->prev_target.y = result.scroll.target_y;
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
@ -183,12 +149,15 @@ draw_file_bar(System_Functions *system, Render_Target *target, View *view, Model
|
|||
intbar_draw_string(system, target, &bar, lit(" loading"), base_color);
|
||||
}
|
||||
else{
|
||||
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
||||
Full_Cursor cursor = file_compute_cursor(system, view->file_data.file, seek_pos(edit_pos.cursor_pos));
|
||||
|
||||
char bar_space[526];
|
||||
String bar_text = make_fixed_width_string(bar_space);
|
||||
append_ss (&bar_text, lit(" L#"));
|
||||
append_int_to_str(&bar_text, view->transient.edit_pos.cursor.line);
|
||||
append_int_to_str(&bar_text, cursor.line);
|
||||
append_ss (&bar_text, lit(" C#"));
|
||||
append_int_to_str(&bar_text, view->transient.edit_pos.cursor.character);
|
||||
append_int_to_str(&bar_text, cursor.character);
|
||||
|
||||
append_ss(&bar_text, lit(" -"));
|
||||
|
||||
|
@ -245,10 +214,10 @@ get_margin_color(Style *style, i32 level){
|
|||
internal void
|
||||
do_render_file_view(System_Functions *system, View *view, Models *models, GUI_Scroll_Vars *scroll, View *active, i32_Rect rect, b32 is_active, Render_Target *target){
|
||||
|
||||
Editing_File *file = view->transient.file_data.file;
|
||||
Editing_File *file = view->file_data.file;
|
||||
Assert(file != 0);
|
||||
|
||||
i32 line_height = view->transient.line_height;
|
||||
i32 line_height = view->line_height;
|
||||
Style *style = &models->styles.styles[0];
|
||||
Face_ID font_id = file->settings.font_id;
|
||||
char font_name_space[256];
|
||||
|
@ -256,7 +225,7 @@ do_render_file_view(System_Functions *system, View *view, Models *models, GUI_Sc
|
|||
font_name.size = system->font.get_name_by_id(font_id, font_name.str, font_name.memory_size);
|
||||
Font_Pointers font = system->font.get_pointers_by_id(font_id);
|
||||
|
||||
if (!view->transient.hide_file_bar){
|
||||
if (!view->hide_file_bar){
|
||||
i32_Rect top_bar_rect = {};
|
||||
top_bar_rect.x0 = rect.x0;
|
||||
top_bar_rect.y0 = rect.y0;
|
||||
|
@ -267,7 +236,7 @@ do_render_file_view(System_Functions *system, View *view, Models *models, GUI_Sc
|
|||
}
|
||||
|
||||
i32 bar_count = 0;
|
||||
for (Query_Slot *slot = view->transient.query_set.used_slot;
|
||||
for (Query_Slot *slot = view->query_set.used_slot;
|
||||
slot != 0;
|
||||
slot = slot->next, ++bar_count){
|
||||
i32_Rect query_bar_rect = {};
|
||||
|
@ -285,10 +254,10 @@ do_render_file_view(System_Functions *system, View *view, Models *models, GUI_Sc
|
|||
x = ceil32(draw_string(system, target, font_id, slot->query_bar->prompt, x, y, text2_color));
|
||||
draw_string(system, target, font_id, slot->query_bar->string, x, y, text1_color);
|
||||
}
|
||||
view->transient.widget_height = (f32)bar_count*(view->transient.line_height + 2);
|
||||
view->widget_height = (f32)bar_count*(view->line_height + 2);
|
||||
|
||||
draw_push_clip(target, rect);
|
||||
if (!view->transient.ui_mode){
|
||||
if (!view->ui_mode){
|
||||
if (file_is_ready(file)){
|
||||
render_loaded_file_in_view(system, view, models, rect, is_active, target);
|
||||
}
|
||||
|
@ -296,9 +265,9 @@ do_render_file_view(System_Functions *system, View *view, Models *models, GUI_Sc
|
|||
else{
|
||||
f32_Rect rect_f32 = f32R(rect);
|
||||
|
||||
i32 item_count = view->transient.ui_control.count;
|
||||
UI_Item *item = view->transient.ui_control.items;
|
||||
GUI_Scroll_Vars ui_scroll = view->transient.ui_scroll;
|
||||
i32 item_count = view->ui_control.count;
|
||||
UI_Item *item = view->ui_control.items;
|
||||
GUI_Scroll_Vars ui_scroll = view->ui_scroll;
|
||||
for (i32 i = 0; i < item_count; ++i, item += 1){
|
||||
|
||||
f32_Rect item_rect = f32R(item->rectangle);
|
||||
|
@ -319,7 +288,7 @@ do_render_file_view(System_Functions *system, View *view, Models *models, GUI_Sc
|
|||
}break;
|
||||
}
|
||||
|
||||
if (rect_opverlap(item_rect, rect_f32)){
|
||||
if (rect_overlap(item_rect, rect_f32)){
|
||||
switch (item->type){
|
||||
case UIType_Option:
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue