4.0.26 bug fix list completed

This commit is contained in:
Allen Webster 2018-05-06 19:47:22 -07:00
parent 4915ed36fd
commit a6f525a900
26 changed files with 739 additions and 382 deletions

View File

@ -624,6 +624,8 @@ DOC_SEE(buffer_add_markers)
*/
TYPEDEF void* Marker_Handle;
TYPEDEF void Marker_Delete_Callback(struct Application_Links *app, Marker_Handle handle, void *user_data, uint32_t user_data_size);
/*
DOC(A four corner axis aligned rectangle, with integer coordinates.)
*/
@ -822,6 +824,15 @@ STRUCT User_Input{
Generic_Command command;
};
/*
DOC(Data is used for passing and returing pointer size pairs.)
*/
STRUCT Data{
/* DOC(A pointer to the data.) */
uint8_t *data;
/* DOC(The size of the data in bytes.) */
uint64_t size;
};
/* DOC(Hook_IDs name the various hooks in 4coder, these hooks use the Hook_Function signature.)
DOC_SEE(Hook_Function) */
@ -922,6 +933,7 @@ ENUM(int32_t, Map_ID){
mapid_nomap
};
/*
DOC(Describes a unit of information for setting up key bindings. A unit can set a key binding, switch the active map, set the inherited map, or set a hook.)
*/

View File

@ -192,6 +192,86 @@ seek_matching_token_backwards(Cpp_Token_Array tokens, Cpp_Token *token, Cpp_Toke
static Cpp_Token*
find_anchor_token(Application_Links *app, Buffer_Summary *buffer, Cpp_Token_Array tokens, int32_t line_start, int32_t tab_width, int32_t *current_indent_out){
#if 1
// NOTE(allen): New implementation of find_anchor_token (4.0.26) revert if it is a problem.
Cpp_Token *token = 0;
if (tokens.count > 0){
Cpp_Token *first_invalid_token = get_first_token_at_line(app, buffer, tokens, line_start);
if (first_invalid_token <= tokens.tokens){
token = tokens.tokens;
}
else{
int32_t stack[256];
int32_t top = -1;
Cpp_Token *token_it = tokens.tokens;
int32_t highest_checked_line_number = -1;
for (; token_it < first_invalid_token; ++token_it){
int32_t line_number = buffer_get_line_number(app, buffer, token_it->start);
if (highest_checked_line_number < line_number){
highest_checked_line_number = line_number;
if (top == -1){
token = token_it;
}
}
switch (token_it->type){
case CPP_TOKEN_BRACE_OPEN:
case CPP_TOKEN_BRACKET_OPEN:
case CPP_TOKEN_PARENTHESE_OPEN:
{
top += 1;
stack[top] = token_it->type;
}break;
case CPP_TOKEN_PARENTHESE_CLOSE:
{
for (;top >= 0;){
int32_t index = top;
top -= 1;
if (stack[index] == CPP_TOKEN_PARENTHESE_OPEN){
break;
}
}
}break;
case CPP_TOKEN_BRACE_CLOSE:
{
for (;top >= 0;){
int32_t index = top;
if (stack[index] == CPP_TOKEN_PARENTHESE_OPEN){
break;
}
top -= 1;
if (stack[index] == CPP_TOKEN_BRACE_OPEN){
break;
}
}
}break;
case CPP_TOKEN_BRACKET_CLOSE:
{
for (;top >= 0;){
int32_t index = top;
if (stack[index] == CPP_TOKEN_PARENTHESE_OPEN ||
stack[index] == CPP_TOKEN_BRACE_OPEN){
break;
}
top -= 1;
if (stack[index] == CPP_TOKEN_BRACKET_OPEN){
break;
}
}
}break;
}
}
}
}
return(token);
#else
// NOTE(allen): Old (4.0.25) implementation of find_anchor_token.
Cpp_Token *token = 0;
if (tokens.count != 0){
@ -229,10 +309,10 @@ find_anchor_token(Application_Links *app, Buffer_Summary *buffer, Cpp_Token_Arra
if (start_token->type == CPP_TOKEN_PARENTHESE_OPEN){
if (start_token == tokens.tokens){
found_safe_start_position = 1;
found_safe_start_position = true;
}
else{
token = start_token-1;
token = start_token - 1;
}
}
else{
@ -286,6 +366,7 @@ find_anchor_token(Application_Links *app, Buffer_Summary *buffer, Cpp_Token_Arra
}
return(token);
#endif
}
struct Indent_Parse_State{

View File

@ -32,7 +32,7 @@ write_character_parameter(Application_Links *app, uint8_t *character, uint32_t l
next_cursor_marker.pos = character_pos_to_pos(app, &view, &buffer, view.cursor.character_pos);
next_cursor_marker.lean_right = true;
Marker_Handle handle = buffer_add_markers(app, &buffer, 1);
Marker_Handle handle = buffer_add_markers(app, &buffer, 1, 0, 0, 0);
buffer_set_markers(app, &buffer, handle, 0, 1, &next_cursor_marker);
buffer_replace_range(app, &buffer, pos, pos, (char*)character, length);
@ -218,10 +218,25 @@ move_vertical(Application_Links *app, float line_multiplier){
uint32_t access = AccessProtected;
View_Summary view = get_active_view(app, access);
float new_y = get_view_y(&view) + line_multiplier*view.line_height;
float delta_y = line_multiplier*view.line_height;
float new_y = get_view_y(&view) + delta_y;
float x = view.preferred_x;
view_set_cursor(app, &view, seek_xy(x, new_y, 0, view.unwrapped_lines), 0);
float actual_new_y = get_view_y(&view);
if (actual_new_y < new_y){
i32_Rect file_region = view.file_region;
int32_t height = file_region.y1 - file_region.y0;
int32_t full_scroll_y = (int32_t)actual_new_y - height/2;
if (view.scroll_vars.target_y < full_scroll_y){
GUI_Scroll_Vars new_scroll_vars = view.scroll_vars;
new_scroll_vars.target_y += (int32_t)delta_y;
if (new_scroll_vars.target_y > full_scroll_y){
new_scroll_vars.target_y = full_scroll_y;
}
view_set_scroll(app, &view, new_scroll_vars);
}
}
}
CUSTOM_COMMAND_SIG(move_up)
@ -381,7 +396,7 @@ CUSTOM_DOC("Seeks the cursor to the end of the visual line.")
y = view.cursor.unwrapped_y;
}
view_set_cursor(app, &view, seek_xy(100000.f, y, 1, view.unwrapped_lines), 1);
view_set_cursor(app, &view, seek_xy(max_f32, y, 1, view.unwrapped_lines), 1);
}
CUSTOM_COMMAND_SIG(seek_whitespace_up_end_line)

View File

@ -21,7 +21,7 @@ TYPE: 'internal-for-default-system'
enum Default_Maps{
default_code_map,
default_maps_count
default_maps_count,
};
//

View File

@ -302,13 +302,22 @@ CUSTOM_DOC("Swaps the line under the cursor with the line above it, and moves th
Temp_Memory temp = begin_temp_memory(part);
int32_t length = next_line_pos - prev_line_pos;
char *swap = push_array(part, char, length);
char *swap = push_array(part, char, length + 1);
int32_t first_len = next_line_pos - this_line_pos;
if (buffer_read_range(app, &buffer, this_line_pos, next_line_pos, swap) &&
buffer_read_range(app, &buffer, prev_line_pos, this_line_pos, swap + first_len)){
buffer_replace_range(app, &buffer, prev_line_pos, next_line_pos, swap, length);
view_set_cursor(app, &view, seek_line_char(prev_line, 1), true);
if (buffer_read_range(app, &buffer, this_line_pos, next_line_pos, swap)){
if (first_len == 0 || swap[first_len - 1] != '\n'){
swap[first_len] = '\n';
first_len += 1;
// NOTE(allen): Don't increase "length" because then we will be including
// the original newline and addignt this new one, making the file longer
// which shouldn't be possible for this command!
}
if (buffer_read_range(app, &buffer, prev_line_pos, this_line_pos, swap + first_len)){
buffer_replace_range(app, &buffer, prev_line_pos, next_line_pos, swap, length);
view_set_cursor(app, &view, seek_line_char(prev_line, 1), true);
}
}
end_temp_memory(temp);
@ -322,7 +331,6 @@ CUSTOM_DOC("Moves down to the next line of actual text, regardless of line wrapp
if (!view.exists){
return;
}
int32_t next_line = view.cursor.line + 1;
view_set_cursor(app, &view, seek_line_char(next_line, 1), true);
}
@ -339,9 +347,15 @@ CUSTOM_DOC("Swaps the line under the cursor with the line below it, and moves th
return;
}
move_down_textual(app);
move_line_up(app);
move_down_textual(app);
int32_t next_line = view.cursor.line + 1;
Full_Cursor new_cursor = {0};
if (view_compute_cursor(app, &view, seek_line_char(next_line, 1), &new_cursor)){
if (new_cursor.line == next_line){
view_set_cursor(app, &view, seek_pos(new_cursor.pos), true);
move_line_up(app);
move_down_textual(app);
}
}
}
CUSTOM_COMMAND_SIG(duplicate_line)
@ -377,6 +391,15 @@ CUSTOM_DOC("Delete the line the on which the cursor sits.")
Temp_Memory temp = begin_temp_memory(part);
int32_t start = buffer_get_line_start(app, &buffer, view.cursor.line);
int32_t end = buffer_get_line_end(app, &buffer, view.cursor.line) + 1;
if (end > buffer.size){
end = buffer.size;
}
if (start == end || buffer_get_char(app, &buffer, end - 1) != '\n'){
start -= 1;
if (start < 0){
start = 0;
}
}
buffer_replace_range(app, &buffer, start, end, 0, 0);
@ -471,10 +494,12 @@ CUSTOM_DOC("Reads a token or word under the cursor and lists all locations of st
char space[512];
String str = get_token_or_word_under_pos(app, &buffer, view.cursor.pos, space, sizeof(space) - 1);
str.str[str.size] = 0;
change_active_panel(app);
list_all_locations_of_type_definition_parameters(app, str.str);
if (str.size > 0){
str.str[str.size] = 0;
change_active_panel(app);
list_all_locations_of_type_definition_parameters(app, str.str);
}
}

View File

@ -17,8 +17,9 @@ struct Application_Links;
#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_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_ADD_MARKERS_SIG(n) Marker_Handle n(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count)
#define BUFFER_ADD_MARKERS_SIG(n) Marker_Handle n(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count, Marker_Delete_Callback *callback, void *user_data, uint32_t user_data_size)
#define GET_BUFFER_BY_MARKER_HANDLE_SIG(n) Buffer_Summary n(Application_Links *app, Marker_Handle marker, Access_Flag access)
#define GET_USER_DATA_BY_MARKER_HANDLE_SIG(n) Data n(Application_Links *app, Marker_Handle marker)
#define BUFFER_SET_MARKERS_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers)
#define BUFFER_GET_MARKERS_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *markers_out)
#define BUFFER_REMOVE_MARKERS_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker)
@ -104,6 +105,7 @@ typedef BUFFER_COMPUTE_CURSOR_SIG(Buffer_Compute_Cursor_Function);
typedef BUFFER_BATCH_EDIT_SIG(Buffer_Batch_Edit_Function);
typedef BUFFER_ADD_MARKERS_SIG(Buffer_Add_Markers_Function);
typedef GET_BUFFER_BY_MARKER_HANDLE_SIG(Get_Buffer_By_Marker_Handle_Function);
typedef GET_USER_DATA_BY_MARKER_HANDLE_SIG(Get_User_Data_By_Marker_Handle_Function);
typedef BUFFER_SET_MARKERS_SIG(Buffer_Set_Markers_Function);
typedef BUFFER_GET_MARKERS_SIG(Buffer_Get_Markers_Function);
typedef BUFFER_REMOVE_MARKERS_SIG(Buffer_Remove_Markers_Function);
@ -191,6 +193,7 @@ Buffer_Compute_Cursor_Function *buffer_compute_cursor;
Buffer_Batch_Edit_Function *buffer_batch_edit;
Buffer_Add_Markers_Function *buffer_add_markers;
Get_Buffer_By_Marker_Handle_Function *get_buffer_by_marker_handle;
Get_User_Data_By_Marker_Handle_Function *get_user_data_by_marker_handle;
Buffer_Set_Markers_Function *buffer_set_markers;
Buffer_Get_Markers_Function *buffer_get_markers;
Buffer_Remove_Markers_Function *buffer_remove_markers;
@ -277,6 +280,7 @@ Buffer_Compute_Cursor_Function *buffer_compute_cursor_;
Buffer_Batch_Edit_Function *buffer_batch_edit_;
Buffer_Add_Markers_Function *buffer_add_markers_;
Get_Buffer_By_Marker_Handle_Function *get_buffer_by_marker_handle_;
Get_User_Data_By_Marker_Handle_Function *get_user_data_by_marker_handle_;
Buffer_Set_Markers_Function *buffer_set_markers_;
Buffer_Get_Markers_Function *buffer_get_markers_;
Buffer_Remove_Markers_Function *buffer_remove_markers_;
@ -371,6 +375,7 @@ app_links->buffer_compute_cursor_ = Buffer_Compute_Cursor;\
app_links->buffer_batch_edit_ = Buffer_Batch_Edit;\
app_links->buffer_add_markers_ = Buffer_Add_Markers;\
app_links->get_buffer_by_marker_handle_ = Get_Buffer_By_Marker_Handle;\
app_links->get_user_data_by_marker_handle_ = Get_User_Data_By_Marker_Handle;\
app_links->buffer_set_markers_ = Buffer_Set_Markers;\
app_links->buffer_get_markers_ = Buffer_Get_Markers;\
app_links->buffer_remove_markers_ = Buffer_Remove_Markers;\
@ -455,8 +460,9 @@ static inline bool32 buffer_read_range(Application_Links *app, Buffer_Summary *b
static inline 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 inline 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 inline 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 inline Marker_Handle buffer_add_markers(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count){return(app->buffer_add_markers(app, buffer, marker_count));}
static inline Marker_Handle buffer_add_markers(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count, Marker_Delete_Callback *callback, void *user_data, uint32_t user_data_size){return(app->buffer_add_markers(app, buffer, marker_count, callback, user_data, user_data_size));}
static inline Buffer_Summary get_buffer_by_marker_handle(Application_Links *app, Marker_Handle marker, Access_Flag access){return(app->get_buffer_by_marker_handle(app, marker, access));}
static inline Data get_user_data_by_marker_handle(Application_Links *app, Marker_Handle marker){return(app->get_user_data_by_marker_handle(app, marker));}
static inline bool32 buffer_set_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers){return(app->buffer_set_markers(app, buffer, marker, first_marker_index, marker_count, source_markers));}
static inline bool32 buffer_get_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *markers_out){return(app->buffer_get_markers(app, buffer, marker, first_marker_index, marker_count, markers_out));}
static inline bool32 buffer_remove_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker){return(app->buffer_remove_markers(app, buffer, marker));}
@ -541,8 +547,9 @@ static inline bool32 buffer_read_range(Application_Links *app, Buffer_Summary *b
static inline 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 inline 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 inline 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 inline Marker_Handle buffer_add_markers(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count){return(app->buffer_add_markers_(app, buffer, marker_count));}
static inline Marker_Handle buffer_add_markers(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count, Marker_Delete_Callback *callback, void *user_data, uint32_t user_data_size){return(app->buffer_add_markers_(app, buffer, marker_count, callback, user_data, user_data_size));}
static inline Buffer_Summary get_buffer_by_marker_handle(Application_Links *app, Marker_Handle marker, Access_Flag access){return(app->get_buffer_by_marker_handle_(app, marker, access));}
static inline Data get_user_data_by_marker_handle(Application_Links *app, Marker_Handle marker){return(app->get_user_data_by_marker_handle_(app, marker));}
static inline bool32 buffer_set_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers){return(app->buffer_set_markers_(app, buffer, marker, first_marker_index, marker_count, source_markers));}
static inline bool32 buffer_get_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *markers_out){return(app->buffer_get_markers_(app, buffer, marker, first_marker_index, marker_count, markers_out));}
static inline bool32 buffer_remove_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker){return(app->buffer_remove_markers_(app, buffer, marker));}

View File

@ -215,74 +215,74 @@ int32_t line_number;
};
static Command_Metadata fcoder_metacmd_table[194] = {
{ PROC_LINKS(allow_mouse, 0), "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 232 },
{ 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:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 667 },
{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 678 },
{ PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 657 },
{ 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:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 748 },
{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 759 },
{ PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 738 },
{ PROC_LINKS(backspace_char, 0), "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 81 },
{ PROC_LINKS(backspace_word, 0), "backspace_word", 14, "Delete characters between the cursor position and the first alphanumeric boundary to the left.", 94, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 147 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 528 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 543 },
{ 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:\\work\\4ed\\code\\4coder_build_commands.cpp", 46, 203 },
{ 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:\\work\\4ed\\code\\4coder_build_commands.cpp", 46, 169 },
{ PROC_LINKS(center_view, 0), "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 136 },
{ 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:\\work\\4ed\\code\\4coder_default_framework.h", 47, 125 },
{ 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:\\work\\4ed\\code\\4coder_default_framework.h", 47, 143 },
{ 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:\\work\\4ed\\code\\4coder_build_commands.cpp", 46, 225 },
{ PROC_LINKS(clean_all_lines, 0), "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 460 },
{ PROC_LINKS(clean_all_lines, 0), "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 475 },
{ PROC_LINKS(click_set_cursor, 0), "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 190 },
{ PROC_LINKS(click_set_mark, 0), "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 203 },
{ 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:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 188 },
{ PROC_LINKS(close_build_panel, 0), "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "C:\\work\\4ed\\code\\4coder_build_commands.cpp", 46, 219 },
{ PROC_LINKS(close_panel, 0), "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 536 },
{ PROC_LINKS(close_panel, 0), "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 551 },
{ PROC_LINKS(copy, 0), "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "C:\\work\\4ed\\code\\4coder_clipboard.cpp", 41, 52 },
{ PROC_LINKS(cursor_mark_swap, 0), "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 109 },
{ PROC_LINKS(cut, 0), "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "C:\\work\\4ed\\code\\4coder_clipboard.cpp", 41, 61 },
{ PROC_LINKS(decrease_face_size, 0), "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 629 },
{ PROC_LINKS(decrease_line_wrap, 0), "decrease_line_wrap", 18, "Decrases the current buffer's width for line wrapping.", 54, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 606 },
{ PROC_LINKS(decrease_face_size, 0), "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 644 },
{ PROC_LINKS(decrease_line_wrap, 0), "decrease_line_wrap", 18, "Decrases the current buffer's width for line wrapping.", 54, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 621 },
{ PROC_LINKS(delete_char, 0), "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 63 },
{ 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:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 492 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1076 },
{ PROC_LINKS(delete_line, 0), "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 369 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1091 },
{ PROC_LINKS(delete_line, 0), "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 383 },
{ PROC_LINKS(delete_range, 0), "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 121 },
{ PROC_LINKS(delete_word, 0), "delete_word", 11, "Delete characters between the cursor position and the first alphanumeric boundary to the right.", 95, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 167 },
{ PROC_LINKS(duplicate_line, 0), "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 347 },
{ PROC_LINKS(eol_dosify, 0), "eol_dosify", 10, "Puts the buffer in DOS line ending mode.", 40, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 659 },
{ PROC_LINKS(eol_nixify, 0), "eol_nixify", 10, "Puts the buffer in NIX line ending mode.", 40, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 667 },
{ PROC_LINKS(duplicate_line, 0), "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 361 },
{ PROC_LINKS(eol_dosify, 0), "eol_dosify", 10, "Puts the buffer in DOS line ending mode.", 40, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 674 },
{ PROC_LINKS(eol_nixify, 0), "eol_nixify", 10, "Puts the buffer in NIX line ending mode.", 40, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 682 },
{ 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:\\work\\4ed\\code\\4coder_system_command.cpp", 46, 30 },
{ PROC_LINKS(execute_arbitrary_command, 0), "execute_arbitrary_command", 25, "Execute a 'long form' command.", 30, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 750 },
{ PROC_LINKS(execute_arbitrary_command, 0), "execute_arbitrary_command", 25, "Execute a 'long form' command.", 30, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 775 },
{ 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:\\work\\4ed\\code\\4coder_system_command.cpp", 46, 14 },
{ PROC_LINKS(exit_4coder, 0), "exit_4coder", 11, "Attempts to close 4coder.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 675 },
{ PROC_LINKS(goto_beginning_of_file, 0), "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 401 },
{ PROC_LINKS(goto_end_of_file, 0), "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 408 },
{ PROC_LINKS(exit_4coder, 0), "exit_4coder", 11, "Attempts to close 4coder.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 690 },
{ PROC_LINKS(goto_beginning_of_file, 0), "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 416 },
{ PROC_LINKS(goto_end_of_file, 0), "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 423 },
{ 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:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 100 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 562 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 544 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 586 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 568 },
{ 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:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 24 },
{ 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:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 45 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 388 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 360 },
{ PROC_LINKS(goto_line, 0), "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 685 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 412 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 384 },
{ PROC_LINKS(goto_line, 0), "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 700 },
{ 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:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 64 },
{ 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:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 82 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 513 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 483 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 537 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 507 },
{ 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:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 73 },
{ 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:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 91 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 529 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 499 },
{ PROC_LINKS(hide_filebar, 0), "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 569 },
{ PROC_LINKS(hide_scrollbar, 0), "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 555 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 553 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 523 },
{ PROC_LINKS(hide_filebar, 0), "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 584 },
{ PROC_LINKS(hide_scrollbar, 0), "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 570 },
{ PROC_LINKS(highlight_next_scope_absolute, 0), "highlight_next_scope_absolute", 29, "Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.", 102, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 368 },
{ PROC_LINKS(highlight_prev_scope_absolute, 0), "highlight_prev_scope_absolute", 29, "Finds the first scope started by '{' before the cursor and puts the cursor and mark on the '{' and '}'.", 103, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 387 },
{ PROC_LINKS(highlight_surrounding_scope, 0), "highlight_surrounding_scope", 27, "Finds the scope enclosed by '{' '}' surrounding the cursor and puts the cursor and mark on the '{' and '}'.", 107, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 346 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 537 },
{ PROC_LINKS(increase_face_size, 0), "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 617 },
{ PROC_LINKS(increase_line_wrap, 0), "increase_line_wrap", 18, "Increases the current buffer's width for line wrapping.", 55, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 595 },
{ PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1255 },
{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1231 },
{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1237 },
{ PROC_LINKS(interactive_open_or_new, 0), "interactive_open_or_new", 23, "Interactively opens or creates a new file.", 42, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1243 },
{ PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1249 },
{ PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1273 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 562 },
{ PROC_LINKS(increase_face_size, 0), "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 632 },
{ PROC_LINKS(increase_line_wrap, 0), "increase_line_wrap", 18, "Increases the current buffer's width for line wrapping.", 55, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 610 },
{ PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1270 },
{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1246 },
{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1252 },
{ PROC_LINKS(interactive_open_or_new, 0), "interactive_open_or_new", 23, "Interactively opens or creates a new file.", 42, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1258 },
{ PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1264 },
{ PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1288 },
{ PROC_LINKS(kill_rect, 0), "kill_rect", 9, "Delete characters in a rectangular region. Range testing is done by unwrapped-xy coordinates.", 93, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 31 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 151 },
{ 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:\\work\\4ed\\code\\4coder_function_list.cpp", 45, 348 },
@ -292,122 +292,122 @@ static Command_Metadata fcoder_metacmd_table[194] = {
{ 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:\\work\\4ed\\code\\4coder_search.cpp", 38, 792 },
{ 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:\\work\\4ed\\code\\4coder_search.cpp", 38, 834 },
{ 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:\\work\\4ed\\code\\4coder_search.cpp", 38, 840 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 454 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 466 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 477 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 489 },
{ 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:\\work\\4ed\\code\\4coder_search.cpp", 38, 712 },
{ 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:\\work\\4ed\\code\\4coder_search.cpp", 38, 732 },
{ 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:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 408 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1184 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1199 },
{ PROC_LINKS(miblo_decrement_basic, 0), "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 119 },
{ PROC_LINKS(miblo_decrement_time_stamp, 0), "miblo_decrement_time_stamp", 26, "Decrement a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 392 },
{ PROC_LINKS(miblo_decrement_time_stamp_minute, 0), "miblo_decrement_time_stamp_minute", 33, "Decrement a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 404 },
{ PROC_LINKS(miblo_increment_basic, 0), "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 103 },
{ PROC_LINKS(miblo_increment_time_stamp, 0), "miblo_increment_time_stamp", 26, "Increment a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 386 },
{ PROC_LINKS(miblo_increment_time_stamp_minute, 0), "miblo_increment_time_stamp_minute", 33, "Increment a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 398 },
{ PROC_LINKS(move_down, 0), "move_down", 9, "Moves the cursor down one line.", 31, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 233 },
{ PROC_LINKS(move_down_10, 0), "move_down_10", 12, "Moves the cursor down ten lines.", 32, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 245 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 318 },
{ PROC_LINKS(move_left, 0), "move_left", 9, "Moves the cursor one character to the left.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 286 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 330 },
{ PROC_LINKS(move_down, 0), "move_down", 9, "Moves the cursor down one line.", 31, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 248 },
{ PROC_LINKS(move_down_10, 0), "move_down_10", 12, "Moves the cursor down ten lines.", 32, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 260 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 327 },
{ PROC_LINKS(move_left, 0), "move_left", 9, "Moves the cursor one character to the left.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 301 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 338 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 271 },
{ PROC_LINKS(move_right, 0), "move_right", 10, "Moves the cursor one character to the right.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 295 },
{ PROC_LINKS(move_up, 0), "move_up", 7, "Moves the cursor up one line.", 29, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 227 },
{ PROC_LINKS(move_up_10, 0), "move_up_10", 10, "Moves the cursor up ten lines.", 30, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 239 },
{ PROC_LINKS(move_right, 0), "move_right", 10, "Moves the cursor one character to the right.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 310 },
{ PROC_LINKS(move_up, 0), "move_up", 7, "Moves the cursor up one line.", 29, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 242 },
{ PROC_LINKS(move_up_10, 0), "move_up_10", 10, "Moves the cursor up ten lines.", 30, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 254 },
{ PROC_LINKS(multi_line_edit, 0), "multi_line_edit", 15, "Begin multi-line mode. In multi-line mode characters are inserted at every line between the mark and cursor. All characters are inserted at the same character offset into the line. This mode uses line_char coordinates.", 221, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 122 },
{ 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:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 117 },
{ 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:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 132 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 600 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 585 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 624 },
{ 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:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 609 },
{ 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:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 165 },
{ 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:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 180 },
{ PROC_LINKS(open_color_tweaker, 0), "open_color_tweaker", 18, "Opens the 4coder colors and fonts selector menu.", 48, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1279 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 634 },
{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file, displaying it in the other view.", 127, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 651 },
{ PROC_LINKS(open_long_braces, 0), "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 513 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 529 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 521 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 707 },
{ PROC_LINKS(open_color_tweaker, 0), "open_color_tweaker", 18, "Opens the 4coder colors and fonts selector menu.", 48, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1294 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 659 },
{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file, displaying it in the other view.", 127, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 676 },
{ PROC_LINKS(open_long_braces, 0), "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 538 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 554 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 546 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 732 },
{ PROC_LINKS(open_panel_hsplit, 0), "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 170 },
{ PROC_LINKS(open_panel_vsplit, 0), "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 161 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 276 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 267 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 291 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 282 },
{ PROC_LINKS(paste, 0), "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "C:\\work\\4ed\\code\\4coder_clipboard.cpp", 41, 70 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 391 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 414 },
{ 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:\\work\\4ed\\code\\4coder_clipboard.cpp", 41, 108 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 398 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 421 },
{ 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:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 486 },
{ 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:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 575 },
{ 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:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 601 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 997 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1018 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1012 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1033 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 240 },
{ PROC_LINKS(redo, 0), "redo", 4, "Advances forewards through the undo history.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1225 },
{ PROC_LINKS(redo, 0), "redo", 4, "Advances forewards through the undo history.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1240 },
{ PROC_LINKS(reload_current_project, 0), "reload_current_project", 22, "If a project file has already been loaded, reloads the same file. Useful for when the project configuration is changed.", 120, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 479 },
{ PROC_LINKS(remap_interactive, 0), "remap_interactive", 17, "Switch to a named key binding map.", 34, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 743 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1142 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1157 },
{ PROC_LINKS(rename_parameter, 0), "rename_parameter", 16, "If the cursor is found to be on the name of a function parameter in the signature of a function definition, all occurences within the scope of the function will be replaced with a new provided string.", 200, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 387 },
{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1261 },
{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1276 },
{ PROC_LINKS(replace_all_occurrences, 0), "replace_all_occurrences", 23, "Queries the user for two strings, and replaces all occurrences of the first string with the second string in all open buffers.", 126, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 773 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 894 },
{ PROC_LINKS(reverse_search, 0), "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 865 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 883 },
{ PROC_LINKS(save, 0), "save", 4, "Saves the current buffer.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1267 },
{ PROC_LINKS(save_all_dirty_buffers, 0), "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1041 },
{ PROC_LINKS(save_to_query, 0), "save_to_query", 13, "Queries the user for a name and saves the contents of the current buffer, altering the buffer's name too.", 105, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1102 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 909 },
{ PROC_LINKS(reverse_search, 0), "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 880 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 898 },
{ PROC_LINKS(save, 0), "save", 4, "Saves the current buffer.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1282 },
{ PROC_LINKS(save_all_dirty_buffers, 0), "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1056 },
{ PROC_LINKS(save_to_query, 0), "save_to_query", 13, "Queries the user for a name and saves the contents of the current buffer, altering the buffer's name too.", 105, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1117 },
{ 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:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 751 },
{ PROC_LINKS(search, 0), "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 858 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 872 },
{ PROC_LINKS(search, 0), "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 873 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 887 },
{ PROC_LINKS(seek_alphanumeric_left, 0), "seek_alphanumeric_left", 22, "Seek left for boundary between alphanumeric characters and non-alphanumeric characters.", 87, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 128 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 136 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 132 },
{ PROC_LINKS(seek_alphanumeric_right, 0), "seek_alphanumeric_right", 23, "Seek right for boundary between alphanumeric characters and non-alphanumeric characters.", 88, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 124 },
{ PROC_LINKS(seek_beginning_of_line, 0), "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 361 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 339 },
{ PROC_LINKS(seek_end_of_line, 0), "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 374 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 350 },
{ PROC_LINKS(seek_beginning_of_line, 0), "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 376 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 354 },
{ PROC_LINKS(seek_end_of_line, 0), "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 389 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 365 },
{ PROC_LINKS(seek_token_left, 0), "seek_token_left", 15, "Seek left for the next beginning of a token.", 44, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 112 },
{ PROC_LINKS(seek_token_right, 0), "seek_token_right", 16, "Seek right for the next end of a token.", 39, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 108 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 120 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 116 },
{ PROC_LINKS(seek_whitespace_down, 0), "seek_whitespace_down", 20, "Seeks the cursor down to the next blank line.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 328 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 394 },
{ PROC_LINKS(seek_whitespace_down, 0), "seek_whitespace_down", 20, "Seeks the cursor down to the next blank line.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 343 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 409 },
{ PROC_LINKS(seek_whitespace_left, 0), "seek_whitespace_left", 20, "Seek left for the next boundary between whitespace and non-whitespace.", 70, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 104 },
{ PROC_LINKS(seek_whitespace_right, 0), "seek_whitespace_right", 21, "Seek right for the next boundary between whitespace and non-whitespace.", 71, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 100 },
{ PROC_LINKS(seek_whitespace_up, 0), "seek_whitespace_up", 18, "Seeks the cursor up to the next blank line.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 317 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 387 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 304 },
{ PROC_LINKS(seek_whitespace_up, 0), "seek_whitespace_up", 18, "Seeks the cursor up to the next blank line.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 332 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 402 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 319 },
{ PROC_LINKS(set_bindings_choose, 0), "set_bindings_choose", 19, "Remap keybindings using the 'choose' mapping rule.", 50, "C:\\work\\4ed\\code\\4coder_remapping_commands.cpp", 50, 49 },
{ PROC_LINKS(set_bindings_default, 0), "set_bindings_default", 20, "Remap keybindings using the 'default' mapping rule.", 51, "C:\\work\\4ed\\code\\4coder_remapping_commands.cpp", 50, 63 },
{ PROC_LINKS(set_bindings_mac_default, 0), "set_bindings_mac_default", 24, "Remap keybindings using the 'mac-default' mapping rule.", 55, "C:\\work\\4ed\\code\\4coder_remapping_commands.cpp", 50, 77 },
{ PROC_LINKS(set_mark, 0), "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 100 },
{ 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:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 658 },
{ PROC_LINKS(show_filebar, 0), "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 562 },
{ PROC_LINKS(show_scrollbar, 0), "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 548 },
{ PROC_LINKS(show_filebar, 0), "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 577 },
{ PROC_LINKS(show_scrollbar, 0), "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 563 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 187 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 211 },
{ PROC_LINKS(suppress_mouse, 0), "suppress_mouse", 14, "Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.", 83, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 226 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 731 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 440 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 420 },
{ PROC_LINKS(toggle_filebar, 0), "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 576 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 756 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 455 },
{ 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:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 435 },
{ PROC_LINKS(toggle_filebar, 0), "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 591 },
{ 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:\\work\\4ed\\code\\4coder_default_framework.h", 47, 244 },
{ PROC_LINKS(toggle_line_wrap, 0), "toggle_line_wrap", 16, "Toggles the current buffer's line wrapping status.", 50, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 585 },
{ PROC_LINKS(toggle_line_wrap, 0), "toggle_line_wrap", 16, "Toggles the current buffer's line wrapping status.", 50, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 600 },
{ PROC_LINKS(toggle_mouse, 0), "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 238 },
{ PROC_LINKS(toggle_show_whitespace, 0), "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 652 },
{ PROC_LINKS(toggle_virtual_whitespace, 0), "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 641 },
{ PROC_LINKS(undo, 0), "undo", 4, "Advances backwards through the undo history.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1219 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 721 },
{ PROC_LINKS(toggle_show_whitespace, 0), "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 667 },
{ PROC_LINKS(toggle_virtual_whitespace, 0), "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 656 },
{ PROC_LINKS(undo, 0), "undo", 4, "Advances backwards through the undo history.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1234 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 746 },
{ 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:\\work\\4ed\\code\\4coder_search.cpp", 38, 863 },
{ 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:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 690 },
{ PROC_LINKS(write_block, 0), "write_block", 11, "At the cursor, insert a block comment.", 38, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 584 },
{ 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:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 771 },
{ PROC_LINKS(write_block, 0), "write_block", 11, "At the cursor, insert a block comment.", 38, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 609 },
{ PROC_LINKS(write_character, 0), "write_character", 15, "Inserts whatever character was used to trigger this command.", 60, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 47 },
{ PROC_LINKS(write_explicit_enum_flags, 0), "write_explicit_enum_flags", 25, "If the cursor is found to be on the '{' of an enum definition, the values of the enum will be filled in to give each a unique power of 2 value, starting from 1. Existing values are overwritten.", 194, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 709 },
{ PROC_LINKS(write_explicit_enum_values, 0), "write_explicit_enum_values", 26, "If the cursor is found to be on the '{' of an enum definition, the values of the enum will be filled in sequentially starting from zero. Existing values are overwritten.", 170, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 703 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 572 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 578 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 566 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 597 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 603 },
{ 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:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 591 },
{ PROC_LINKS(write_underscore, 0), "write_underscore", 16, "Inserts an underscore.", 22, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 56 },
{ PROC_LINKS(write_zero_struct, 0), "write_zero_struct", 17, "At the cursor, insert a ' = {0};'.", 34, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 590 },
{ PROC_LINKS(write_zero_struct, 0), "write_zero_struct", 17, "At the cursor, insert a ' = {0};'.", 34, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 615 },
};
static int32_t fcoder_metacmd_ID_allow_mouse = 0;
static int32_t fcoder_metacmd_ID_auto_tab_line_at_cursor = 1;

View File

@ -5,6 +5,33 @@
#if !defined(FCODER_HELPER_H)
#define FCODER_HELPER_H
#define dll_remove(n) (n)->next->prev=(n)->prev,(n)->prev->next=(n)->next
#define zdll_push_back_(f,l,n) if(f==0){n->next=n->prev=0;f=l=n;}else{n->prev=l;n->next=0;l->next=n;l=n;}
#define zdll_push_back(f,l,n) do{ zdll_push_back_((f),(l),(n)) }while(0)
#define zdll_remove_front_(f,l,n) if(f==l){f=l=0;}else{f=f->next;f->prev=0;}
#define zdll_remove_back_(f,l,n) if(f==l){f=l=0;}else{l=l->prev;l->next=0;}
#define zdll_remove_(f,l,n) if(f==n){zdll_remove_front_(f,l,n);}else if(l==n){zdll_remove_back_(f,l,n);}else{dll_remove(n);}
#define zdll_remove(f,l,n) do{ zdll_remove_((f),(l),(n)) }while(0)
#define Member(S,m) (((S*)0)->m)
#define PtrDif(a,b) ((uint8_t*)(a) - (uint8_t*)(b))
#define PtrAsInt(a) PtrDif(a,0)
#define OffsetOfMember(S,m) PtrAsInt(&Member(S,m))
#define CastFromMember(S,m,ptr) (S*)( (uint8_t*)(ptr) - OffsetOfMember(S,m) )
inline float
hexfloat(uint32_t x){
union{
uint32_t x;
float f;
} c;
c.x = x;
return(c.f);
}
static const float max_f32 = hexfloat(0x7f800000);
#include "4coder_seek_types.h"
#include "4coder_lib/4coder_utf8.h"

View File

@ -22,23 +22,25 @@ TYPE: 'drop-in-command-pack'
#include "4coder_jumping.h"
static uint32_t
binary_search(uint32_t *array, uint32_t count, uint32_t x){
binary_search(uint32_t *array, int32_t stride, int32_t count, uint32_t x){
uint8_t *raw = (uint8_t*)array;
uint32_t i = 0;
uint32_t first = 0;
uint32_t last = count;
if (first < last){
for (;;){
i = (first + last)/2;
if (array[i] < x){
uint32_t k = *(uint32_t*)(raw + stride*i);
if (k < x){
first = i;
}
else if (array[i] > x){
else if (k > x){
last = i;
}
else{ // NOTE(allen): array[i] == x
break;
}
if (first+1 >= last){
if (first + 1 >= last){
i = first;
break;
}
@ -51,51 +53,94 @@ enum Jump_Location_Flag{
JumpFlag_IsSubJump = 0x1,
};
struct Marker_List{
uint32_t *handle_starts;
Marker_Handle *handles;
uint32_t *jump_line_numbers;
uint32_t *jump_flags;
uint32_t handle_count;
uint32_t handle_max;
int32_t jump_max;
int32_t jump_count;
struct Sticky_Jump_Destination_Array{
uint32_t first_jump_index;
Marker_Handle handle;
};
struct Sticky_Jump_Source{
uint32_t line_number;
uint32_t flags;
};
struct Marker_List{
Sticky_Jump_Destination_Array *dst;
int32_t dst_count;
int32_t dst_max;
Sticky_Jump_Source *jumps;
int32_t jump_count;
int32_t jump_max;
int32_t previous_size;
};
static Sticky_Jump_Destination_Array
make_sticky_jump_destination_array(uint32_t first_jump_index, Marker_Handle handle){
Sticky_Jump_Destination_Array r;
r.first_jump_index = first_jump_index;
r.handle = handle;
return(r);
}
static Sticky_Jump_Source
make_sticky_jump_source(uint32_t line_number, uint32_t flags){
Sticky_Jump_Source r;
r.line_number = line_number;
r.flags = flags;
return(r);
}
static void
double_dst_max(General_Memory *general, Marker_List *list){
uint32_t new_dst_max = list->dst_max*2;
list->dst = gen_realloc_array(general, Sticky_Jump_Destination_Array, list->dst, list->dst_max, new_dst_max);
list->dst_max = new_dst_max;
}
static void
double_jump_max(General_Memory *general, Marker_List *list){
uint32_t new_jump_max = list->jump_max*2;
list->jump_line_numbers = gen_realloc_array(general, uint32_t, list->jump_line_numbers, list->jump_max, new_jump_max);
list->jump_flags = gen_realloc_array(general, uint32_t, list->jump_flags, list->jump_max, new_jump_max);
list->jumps = gen_realloc_array(general, Sticky_Jump_Source, list->jumps, list->jump_max, new_jump_max);
list->jump_max = new_jump_max;
}
static void
double_handle_max(General_Memory *general, Marker_List *list){
uint32_t new_handle_max = list->handle_max*2;
list->handle_starts = gen_realloc_array(general, uint32_t, list->handle_starts, list->handle_max, new_handle_max);
list->handles = gen_realloc_array(general, Marker_Handle, list->handles, list->handle_max, new_handle_max);
list->handle_max = new_handle_max;
marker_list_remove_references(Marker_List *list, Marker_Handle handle){
int32_t count = list->dst_count;
Sticky_Jump_Destination_Array *dst = list->dst;
for (int32_t i = 0; i < count; ++i, ++dst){
if (dst->handle == handle){
dst->handle = 0;
}
}
}
static void
sticky_jump_markers_cleanup(Application_Links *app, Marker_Handle handle, void *user_data, uint32_t user_data_size){
if (user_data_size == sizeof(Marker_List*)){
Marker_List *list = *(Marker_List**)user_data;
marker_list_remove_references(list, handle);
}
}
// TODO(allen): what to do when a push returns 0?
static Marker_List
make_marker_list(Application_Links *app, Partition *part, General_Memory *general, int32_t buffer_id){
static void
init_marker_list(Application_Links *app, Partition *part, General_Memory *general, int32_t buffer_id,
Marker_List *list){
Buffer_Summary buffer = get_buffer(app, buffer_id, AccessAll);
Marker_List list = {0};
Temp_Memory temp = begin_temp_memory(part);
ID_Based_Jump_Location *location_list = (ID_Based_Jump_Location*)partition_current(part);
uint32_t location_count = 0;
list.handle_max = 64;
list.handle_starts = gen_array(general, uint32_t, list.handle_max);
list.handles = gen_array(general, Marker_Handle, list.handle_max);
list->dst_max = 64;
list->dst = gen_array(general, Sticky_Jump_Destination_Array, list->dst_max);
list.jump_max = 64;
list.jump_line_numbers = gen_array(general, uint32_t, list.jump_max);
list.jump_flags = gen_array(general, uint32_t, list.jump_max);
list->jump_max = 64;
list->jumps = gen_array(general, Sticky_Jump_Source, list->jump_max);
list->previous_size = buffer.size;
uint32_t prev_jump_count = 0;
for (int32_t this_jump_line = 1;; ++this_jump_line){
@ -122,30 +167,30 @@ make_marker_list(Application_Links *app, Partition *part, General_Memory *genera
if (output_jump){
Buffer_Summary jump_buffer = {0};
if (open_file(app, &jump_buffer, location.file.str, location.file.size, false, true)){
ID_Based_Jump_Location id_location = {0};
end_temp_memory(temp_name);
id_location.buffer_id = jump_buffer.buffer_id;
id_location.line = location.line;
id_location.column = location.column;
if (id_location.buffer_id != 0){
if (jump_buffer.buffer_id != 0){
ID_Based_Jump_Location id_location = {0};
id_location.buffer_id = jump_buffer.buffer_id;
id_location.line = location.line;
id_location.column = location.column;
if (location_count > 0){
ID_Based_Jump_Location *prev_parsed_loc = &location_list[location_count-1];
if (prev_parsed_loc->buffer_id != id_location.buffer_id){
Buffer_Summary location_buffer = get_buffer(app, prev_parsed_loc->buffer_id, AccessAll);
if (location_buffer.exists){
if (list.handle_count >= list.handle_max){
double_handle_max(general, &list);
if (list->dst_count >= list->dst_max){
double_dst_max(general, list);
}
Marker_Handle new_handle = buffer_add_markers(app, &location_buffer, location_count);
Marker_Handle new_handle = buffer_add_markers(app, &location_buffer, location_count,
sticky_jump_markers_cleanup, &list, sizeof(list));
list.handle_starts[list.handle_count] = prev_jump_count;
list.handles[list.handle_count] = new_handle;
++list.handle_count;
list->dst[list->dst_count] = make_sticky_jump_destination_array(prev_jump_count, new_handle);
++list->dst_count;
prev_jump_count = list.jump_count;
prev_jump_count = list->jump_count;
Marker *markers = push_array(part, Marker, location_count);
for (uint32_t i = 0; i < location_count; ++i){
@ -170,18 +215,17 @@ make_marker_list(Application_Links *app, Partition *part, General_Memory *genera
*new_id_location = id_location;
++location_count;
if (list.jump_count >= list.jump_max){
double_jump_max(general, &list);
if (list->jump_count >= list->jump_max){
double_jump_max(general, list);
}
list.jump_line_numbers[list.jump_count] = this_jump_line;
uint32_t flags = 0;
if (is_sub_error){
flags |= JumpFlag_IsSubJump;
}
list.jump_flags[list.jump_count] = flags;
++list.jump_count;
list->jumps[list->jump_count] = make_sticky_jump_source(this_jump_line, flags);
++list->jump_count;
}
}
else{
@ -194,17 +238,16 @@ make_marker_list(Application_Links *app, Partition *part, General_Memory *genera
ID_Based_Jump_Location *prev_parsed_loc = &location_list[location_count-1];
Buffer_Summary location_buffer = get_buffer(app, prev_parsed_loc->buffer_id, AccessAll);
if (list.handle_count >= list.handle_max){
double_handle_max(general, &list);
if (list->dst_count >= list->dst_max){
double_dst_max(general, list);
}
Marker_Handle new_handle = buffer_add_markers(app, &location_buffer, location_count);
Marker_Handle new_handle = buffer_add_markers(app, &location_buffer, location_count,
sticky_jump_markers_cleanup, &list, sizeof(list));
list->dst[list->dst_count] = make_sticky_jump_destination_array(prev_jump_count, new_handle);
++list->dst_count;
list.handle_starts[list.handle_count] = prev_jump_count;
list.handles[list.handle_count] = new_handle;
++list.handle_count;
prev_jump_count = list.jump_count;
prev_jump_count = list->jump_count;
Marker *markers = push_array(part, Marker, location_count);
for (uint32_t i = 0; i < location_count; ++i){
@ -224,78 +267,52 @@ make_marker_list(Application_Links *app, Partition *part, General_Memory *genera
}
end_temp_memory(temp);
return(list);
}
static void
free_marker_list(General_Memory *general, Marker_List list){
general_memory_free(general, list.handle_starts);
general_memory_free(general, list.handles);
general_memory_free(general, list.jump_line_numbers);
general_memory_free(general, list.dst);
general_memory_free(general, list.jumps);
}
struct Marker_List_Slot{
struct Marker_List_Node{
Marker_List_Node *next;
Marker_List_Node *prev;
Marker_List list;
int32_t buffer_id;
};
static Marker_List_Slot *marker_list_slots = 0;
static uint32_t marker_list_slot_count = 0;
static uint32_t marker_list_slot_max = 0;
static Marker_List_Node *marker_list_first = 0;
static Marker_List_Node *marker_list_last = 0;
static void
delete_marker_list(Marker_List_Node *node){
zdll_remove(marker_list_first, marker_list_last, node);
}
static void
delete_marker_list(Marker_List *list){
delete_marker_list(CastFromMember(Marker_List_Node, list, list));
}
static Marker_List*
set_marker_list_for_buffer(int32_t buffer_id, Marker_List *list){
Marker_List *result = 0;
General_Memory *general = &global_general;
bool32 found_slot = false;
for (uint32_t i = 0; i < marker_list_slot_count; ++i){
if (buffer_id == marker_list_slots[i].buffer_id){
if (list != 0){
marker_list_slots[i].list = *list;
result = &marker_list_slots[i].list;
}
else{
void *dst = marker_list_slots+i;
void *src = marker_list_slots+i+1;
size_t amount = (marker_list_slot_count-i-1)*sizeof(Marker_List_Slot);
memmove(dst, src, amount);
--marker_list_slot_count;
}
found_slot = true;
break;
}
}
if (!found_slot && list != 0){
if (marker_list_slot_count >= marker_list_slot_max){
if (marker_list_slots == 0){
uint32_t new_max = 64;
marker_list_slots = gen_array(general, Marker_List_Slot, new_max);
marker_list_slot_max = new_max;
}
else{
uint32_t new_max = 2*marker_list_slot_max;
marker_list_slots = gen_realloc_array(general, Marker_List_Slot, marker_list_slots, marker_list_slot_count, new_max);
marker_list_slot_max = new_max;
}
}
marker_list_slots[marker_list_slot_count].buffer_id = buffer_id;
marker_list_slots[marker_list_slot_count].list = *list;
result = &marker_list_slots[marker_list_slot_count].list;
++marker_list_slot_count;
}
make_new_marker_list_for_buffer(General_Memory *general, int32_t buffer_id){
Marker_List_Node *new_node = gen_array(general, Marker_List_Node, 1);
zdll_push_back(marker_list_first, marker_list_last, new_node);
new_node->buffer_id = buffer_id;
memset(&new_node->list, 0, sizeof(new_node->list));
Marker_List *result = &new_node->list;
return(result);
}
static Marker_List*
get_marker_list_for_buffer(int32_t buffer_id){
get_marker_list_for_buffer(General_Memory *general, int32_t buffer_id){
Marker_List *result = 0;
for (uint32_t i = 0; i < marker_list_slot_count; ++i){
if (buffer_id == marker_list_slots[i].buffer_id){
result = &marker_list_slots[i].list;
for (Marker_List_Node *node = marker_list_first;
node != 0;
node = node->next){
if (buffer_id == node->buffer_id){
result = &node->list;
break;
}
}
@ -304,10 +321,18 @@ get_marker_list_for_buffer(int32_t buffer_id){
static Marker_List*
get_or_make_list_for_buffer(Application_Links *app, Partition *part, General_Memory *general, int32_t buffer_id){
Marker_List *result = get_marker_list_for_buffer(buffer_id);
Marker_List *result = get_marker_list_for_buffer(general, buffer_id);
if (result != 0){
Buffer_Summary buffer = get_buffer(app, buffer_id, AccessAll);
// TODO(allen): When buffers get an "edit sequence number" use that instead.
if (result->previous_size != buffer.size){
delete_marker_list(result);
result = 0;
}
}
if (result == 0){
Marker_List new_list = make_marker_list(app, part, general, buffer_id);
result = set_marker_list_for_buffer(buffer_id, &new_list);
result = make_new_marker_list_for_buffer(general, buffer_id);
init_marker_list(app, part, general, buffer_id, result);
}
return(result);
}
@ -316,14 +341,13 @@ static bool32
get_jump_from_list(Application_Links *app, Marker_List *list, int32_t index, ID_Pos_Jump_Location *location){
bool32 result = false;
if (index >= 0 && index < list->jump_count){
uint32_t handle_index = binary_search(list->handle_starts, list->handle_count, index);
uint32_t handle_start = list->handle_starts[handle_index];
uint32_t marker_index = index - handle_start;
Marker_Handle handle = list->handles[handle_index];
Buffer_Summary buffer = get_buffer_by_marker_handle(app, handle, AccessAll);
uint32_t handle_index = binary_search(&list->dst->first_jump_index, sizeof(*list->dst), list->dst_count, index);
Sticky_Jump_Destination_Array destinations = list->dst[handle_index];
uint32_t marker_index = index - destinations.first_jump_index;
Buffer_Summary buffer = get_buffer_by_marker_handle(app, destinations.handle, AccessAll);
if (buffer.exists){
Marker marker;
buffer_get_markers(app, &buffer, handle, marker_index, 1, &marker);
buffer_get_markers(app, &buffer, destinations.handle, marker_index, 1, &marker);
location->buffer_id = buffer.buffer_id;
location->pos = marker.pos;
result = true;
@ -335,8 +359,8 @@ get_jump_from_list(Application_Links *app, Marker_List *list, int32_t index, ID_
static int32_t
get_index_exact_from_list(Marker_List *list, int32_t line){
int32_t result = -1;
uint32_t jump_index = binary_search(list->jump_line_numbers, list->jump_count, line);
if (list->jump_line_numbers[jump_index] == (uint32_t)line){
uint32_t jump_index = binary_search(&list->jumps->line_number, sizeof(*list->jumps), list->jump_count, line);
if (list->jumps[jump_index].line_number == (uint32_t)line){
result = jump_index;
}
return(result);
@ -344,15 +368,15 @@ get_index_exact_from_list(Marker_List *list, int32_t line){
static int32_t
get_index_nearest_from_list(Marker_List *list, int32_t line){
int32_t result = binary_search(list->jump_line_numbers, list->jump_count, line);
int32_t result = binary_search(&list->jumps->line_number, sizeof(*list->jumps), list->jump_count, line);
return(result);
}
static int32_t
get_line_from_list(Marker_List *list, int32_t index){
int32_t result = 0;
if (index >= 0 && index < list->jump_count){
result = list->jump_line_numbers[index];
if (0 <= index && index < list->jump_count){
result = list->jumps[index].line_number;
}
return(result);
}
@ -428,7 +452,7 @@ goto_jump_in_order(Application_Links *app, Marker_List *list, View_Summary *jump
}
static bool32
skip_this_jump(ID_Based_Jump_Location prev, ID_Pos_Jump_Location location){
jump_is_repeat(ID_Based_Jump_Location prev, ID_Pos_Jump_Location location){
bool32 skip = false;
if (prev.buffer_id == location.buffer_id && prev.line == location.pos){
skip = true;
@ -444,10 +468,10 @@ goto_next_filtered_jump(Application_Links *app, Marker_List *list, View_Summary
ID_Pos_Jump_Location location = {0};
if (get_jump_from_list(app, list, list_index, &location)){
bool32 skip_this = false;
if (skip_repeats && skip_this_jump(prev_location, location)){
if (skip_repeats && jump_is_repeat(prev_location, location)){
skip_this = true;
}
else if (skip_sub_errors && (list->jump_flags[list_index] & JumpFlag_IsSubJump)){
else if (skip_sub_errors && (list->jumps[list_index].flags & JumpFlag_IsSubJump)){
skip_this = true;
}
@ -618,14 +642,16 @@ CUSTOM_DOC("If the buffer in the active view is writable, inserts a character, o
OPEN_FILE_HOOK_SIG(default_end_file);
OPEN_FILE_HOOK_SIG(end_file_close_jump_list){
Marker_List *list = get_marker_list_for_buffer(buffer_id);
General_Memory *general = &global_general;
Marker_List *list = get_marker_list_for_buffer(general, buffer_id);
if (list != 0){
free_marker_list(&global_general, *list);
set_marker_list_for_buffer(buffer_id, 0);
free_marker_list(general, *list);
delete_marker_list(list);
}
default_end_file(app, buffer_id);
return(0);
}

View File

@ -48,6 +48,15 @@ ms_style_verify(String line, int32_t left_paren_pos, int32_t right_paren_pos){
String number = substr(line, left_paren_pos + 1, right_paren_pos - left_paren_pos - 2);
if (!str_is_int_s(number)){
result = false;
int32_t comma_pos = find_s_char(number, 0, ',');
if (comma_pos < number.size){
String sub_number0 = substr(number, 0, comma_pos);
String sub_number1 = substr(number, comma_pos, number.size - comma_pos - 1);
if (str_is_int_s(sub_number0) && str_is_int_s(sub_number1)){
result = true;
}
}
}
}
return(result);

View File

@ -473,7 +473,7 @@ COMMAND_DECL(reopen){
++vptr_count;
}
file_free(system, general, file);
file_free(system, &models->app_links, general, file);
init_normal_file(system, models, buffer, size, file);
for (i32 i = 0; i < vptr_count; ++i){
@ -1417,7 +1417,7 @@ App_Init_Sig(app_init){
}
file->settings.never_kill = true;
file->settings.unimportant = true;
file_set_unimportant(file, true);
file->settings.unwrapped_lines = true;
if (init_files[i].ptr){
@ -1583,9 +1583,7 @@ App_Step_Sig(app_step){
Editing_File *file = working_set_contains_canon(working_set, canon.name);
if (file != 0){
if (file->state.ignore_behind_os == 0){
if (!file->settings.unimportant){
}
file_set_dirty_flag(file, DirtyState_UnloadedChanges);
}
else if (file->state.ignore_behind_os == 1){
file->state.ignore_behind_os = 2;

View File

@ -325,7 +325,7 @@ DOC_SEE(Command_Line_Interface_Flag)
// NOTE(allen): If we have an output file, prepare it for child proc output.
if (file != 0){
edit_clear(system, models, file);
file->settings.unimportant = true;
file_set_unimportant(file, true);
}
// NOTE(allen): If we have an output file and we need to bring it up in a new view, do so.
@ -792,10 +792,13 @@ DOC_SEE(Buffer_Batch_Edit_Type)
}
API_EXPORT Marker_Handle
Buffer_Add_Markers(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count)
Buffer_Add_Markers(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count, Marker_Delete_Callback *callback, void *user_data, uint32_t user_data_size)
/*
DOC_PARAM(buffer, The buffer on which to add the new markers.)
DOC_PARAM(marker_count, How many markers to be stored in the new marker array.)
DOC_PARAM(callback, A callback that will be called if the buffer closes with these markers still attached.)
DOC_PARAM(user_data, A pointer to data that will be passed to the callback on close. The data will be copied so you do not need to manage it's lifetime.)
DOC_RETURN(user_data_size, The size of the data pointed to by user_data in bytes.)
DOC_RETURN(If this call succeeds it returns a handle to the new markers. If it fails it returns a null handle.)
DOC(This call makes an allocation of markers for the specified buffer. The newly allocated markers are not immediately activated. To activate a marker use buffer_set_markers to give the marker a value. The markers will remain allocated on the buffer until buffer_remove_markers is called or until the buffer is killed.)
DOC_SEE(Marker)
@ -806,7 +809,8 @@ DOC_SEE(Marker)
Marker_Handle result = 0;
if (file != 0){
result = allocate_markers_state(&models->mem.general, file, marker_count);
result = allocate_markers_state(&models->mem.general, file, marker_count,
callback, user_data, user_data_size);
}
return(result);
@ -819,11 +823,28 @@ DOC_PARAM(marker, The marker handle to query.)
DOC_PARAM(access, The access parameter determines what levels of protection this call can access.)
DOC_SEE(Marker)
*/{
Buffer_ID buffer_id = get_buffer_id_from_marker_handle(marker);
Buffer_Summary buffer = Get_Buffer(app, buffer_id, access);
Buffer_Summary buffer = {0};
if (marker != 0){
Buffer_ID buffer_id = get_buffer_id_from_marker_handle(marker);
buffer = Get_Buffer(app, buffer_id, access);
}
return(buffer);
}
API_EXPORT Data
Get_User_Data_By_Marker_Handle(Application_Links *app, Marker_Handle marker)
/*
DOC_PARAM(marker, The marker thandle to query.)
DOC_RETURN(Returns a data struct containing the user data passed in to buffer_add_markers, or a zero struct if the handle is null.)
DOC_SEE(Marker)
*/{
Data data = {0};
if (marker != 0){
data = get_user_data_from_marker_handle(marker);
}
return(data);
}
API_EXPORT bool32
Buffer_Set_Markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers)
/*
@ -1127,11 +1148,11 @@ DOC_SEE(Buffer_Setting_ID)
case BufferSetting_Unimportant:
{
if (value){
file->settings.unimportant = true;
if (value != 0){
file_set_unimportant(file, true);
}
else{
file->settings.unimportant = false;
file_set_unimportant(file, false);
}
}break;

View File

@ -162,6 +162,18 @@ inline u32 round_up_pot_u32(u32 x){
#define min_u32 ((u32)0)
#define min_u64 ((u64)0)
inline f32
hexfloat_f32(u32 x){
union{
u32 x;
f32 f;
} c;
c.x = x;
return(c.f);
}
global_const f32 max_f32 = hexfloat_f32(0x7f800000);
#define Bit_0 (1 << 0)
#define Bit_1 (1 << 1)
#define Bit_2 (1 << 2)

View File

@ -367,6 +367,29 @@ edit_clear(System_Functions *system, Models *models, Editing_File *file){
if (models->hook_end_file != 0){
models->hook_end_file(&models->app_links, file->id.id);
}
b32 no_views_see_file = true;
Editing_Layout *layout = &models->layout;
for (Panel *panel = layout->used_sentinel.next;
panel != &layout->used_sentinel;
panel = panel->next){
View *view = panel->view;
if (view->transient.file_data.file == file){
Full_Cursor cursor = {0};
cursor.line = 1;
cursor.character = 1;
cursor.wrap_line = 1;
view_set_cursor(view, cursor, true, file->settings.unwrapped_lines);
no_views_see_file = false;
}
}
if (no_views_see_file){
memset(file->state.edit_pos_space, 0, sizeof(file->state.edit_pos_space));
file->state.edit_poss_count = 0;
}
edit_single(system, models, file,
0, buffer_size(&file->state.buffer), 0, 0);
}

View File

@ -27,11 +27,14 @@ init_file_markers_state(Editing_File_Markers *markers){
}
internal void
clear_file_markers_state(General_Memory *general, Editing_File_Markers *markers){
clear_file_markers_state(Application_Links *app, General_Memory *general, Editing_File_Markers *markers){
Marker_Array *sentinel = &markers->sentinel;
for (Marker_Array *marker_array = sentinel->next;
marker_array != sentinel;
marker_array = sentinel->next){
if (marker_array->callback != 0){
marker_array->callback(app, marker_array, marker_array + 1, marker_array->user_data_size);
}
dll_remove(marker_array);
general_memory_free(general, marker_array);
}
@ -42,10 +45,12 @@ clear_file_markers_state(General_Memory *general, Editing_File_Markers *markers)
}
internal void*
allocate_markers_state(General_Memory *general, Editing_File *file, u32 new_array_max){
u32 memory_size = sizeof(Marker_Array) + sizeof(Marker)*new_array_max;
allocate_markers_state(General_Memory *general, Editing_File *file, u32 new_array_max,
Marker_Delete_Callback *callback, void *user_data, u32 user_data_size){
u32 rounded_user_data_size = l_round_up_u32(user_data_size, 8);
u32 memory_size = sizeof(Marker_Array) + rounded_user_data_size + sizeof(Marker)*new_array_max;
memory_size = l_round_up_u32(memory_size, KB(4));
u32 real_max = (memory_size - sizeof(Marker_Array))/sizeof(Marker);
u32 real_max = (memory_size - sizeof(Marker_Array) - rounded_user_data_size)/sizeof(Marker);
Marker_Array *array = (Marker_Array*)general_memory_allocate(general, memory_size);
dll_insert_back(&file->markers.sentinel, array);
@ -53,6 +58,10 @@ allocate_markers_state(General_Memory *general, Editing_File *file, u32 new_arra
array->count = 0;
array->sim_max = new_array_max;
array->max = real_max;
array->callback = callback;
array->user_data_size = user_data_size;
array->rounded_user_data_size = rounded_user_data_size;
memcpy(array + 1, user_data, user_data_size);
++file->markers.array_count;
@ -66,59 +75,82 @@ get_buffer_id_from_marker_handle(void *handle){
return(result.id);
}
internal Data
get_user_data_from_marker_handle(void *handle){
Marker_Array *markers = (Marker_Array*)handle;
Data data;
data.data = (u8*)markers + 1;
data.size = markers->user_data_size;
return(data);
}
internal b32
markers_set(Editing_File *file, void *handle, u32 first_index, u32 count, Marker *source){
Assert(file != 0);
b32 result = false;
if (handle != 0){
Marker_Array *markers = (Marker_Array*)handle;
if (markers->buffer_id.id == file->id.id){
if (first_index + count <= markers->sim_max){
u32 new_count = first_index + count;
if (new_count > markers->count){
file->markers.marker_count += new_count - markers->count;
markers->count = new_count;
}
Marker *dst = MarkerArrayBase(markers);
memcpy(dst + first_index, source, sizeof(Marker)*count);
result = true;
}
}
if (handle == 0){
return(false);
}
return(result);
Marker_Array *markers = (Marker_Array*)handle;
if (markers->buffer_id.id != file->id.id){
return(false);
}
if (first_index + count > markers->sim_max){
return(false);
}
u32 new_count = first_index + count;
if (new_count > markers->count){
file->markers.marker_count += new_count - markers->count;
markers->count = new_count;
}
Marker *dst = MarkerArrayBase(markers);
memcpy(dst + first_index, source, sizeof(Marker)*count);
return(true);
}
internal b32
markers_get(Editing_File *file, void *handle, u32 first_index, u32 count, Marker *output){
Assert(file != 0);
b32 result = false;
if (handle != 0){
Marker_Array *markers = (Marker_Array*)handle;
if (markers->buffer_id.id == file->id.id){
if (first_index + count <= markers->count){
Marker *src = MarkerArrayBase(markers);
memcpy(output, src + first_index, sizeof(Marker)*count);
result = true;
}
}
if (handle == 0){
return(false);
}
return(result);
Marker_Array *markers = (Marker_Array*)handle;
if (markers->buffer_id.id != file->id.id){
return(false);
}
if (first_index + count > markers->count){
return(false);
}
Marker *src = MarkerArrayBase(markers);
memcpy(output, src + first_index, sizeof(Marker)*count);
return(true);
}
internal b32
markers_free(General_Memory *general, Editing_File *file, void *handle){
Assert(file != 0);
b32 result = false;
if (handle != 0){
Marker_Array *markers = (Marker_Array*)handle;
if (markers->buffer_id.id == file->id.id){
dll_remove(markers);
file->markers.marker_count -= markers->count;
--file->markers.array_count;
general_memory_free(general, markers);
}
if (handle == 0){
return(false);
}
return(result);
Marker_Array *markers = (Marker_Array*)handle;
if (markers->buffer_id.id != file->id.id){
return(false);
}
dll_remove(markers);
file->markers.marker_count -= markers->count;
--file->markers.array_count;
general_memory_free(general, markers);
return(true);
}
////////////////////////////////
@ -269,6 +301,14 @@ file_is_ready(Editing_File *file){
return(result);
}
inline void
file_set_unimportant(Editing_File *file, b32 val){
if (val){
file->state.dirty = DirtyState_UpToDate;
}
file->settings.unimportant = (b8)(val != false);
}
inline void
file_set_to_loading(Editing_File *file){
memset(&file->state, 0, sizeof(file->state));
@ -540,24 +580,32 @@ file_allocate_metadata_as_needed(General_Memory *general, Gap_Buffer *buffer, vo
inline void
file_allocate_character_starts_as_needed(General_Memory *general, Editing_File *file){
file_allocate_metadata_as_needed(general, &file->state.buffer, (void**)&file->state.character_starts, &file->state. character_start_max, file->state.buffer.line_count, sizeof(i32));
file_allocate_metadata_as_needed(general,
&file->state.buffer, (void**)&file->state.character_starts,
&file->state.character_start_max, file->state.buffer.line_count + 1, sizeof(i32));
}
internal void
file_allocate_indents_as_needed(General_Memory *general, Editing_File *file, i32 min_last_index){
i32 min_amount = min_last_index + 1;
file_allocate_metadata_as_needed(general, &file->state.buffer, (void**)&file->state.line_indents, &file->state.line_indent_max, min_amount, sizeof(f32));
file_allocate_metadata_as_needed(general,
&file->state.buffer, (void**)&file->state.line_indents,
&file->state.line_indent_max, min_amount, sizeof(f32));
}
inline void
file_allocate_wraps_as_needed(General_Memory *general, Editing_File *file){
file_allocate_metadata_as_needed(general, &file->state.buffer, (void**)&file->state.wrap_line_index, &file->state.wrap_max, file->state.buffer.line_count, sizeof(f32));
file_allocate_metadata_as_needed(general,
&file->state.buffer, (void**)&file->state.wrap_line_index,
&file->state.wrap_max, file->state.buffer.line_count + 1, sizeof(f32));
}
inline void
file_allocate_wrap_positions_as_needed(General_Memory *general, Editing_File *file, i32 min_last_index){
i32 min_amount = min_last_index + 1;
file_allocate_metadata_as_needed(general, &file->state.buffer, (void**)&file->state.wrap_positions, &file->state.wrap_position_max, min_amount, sizeof(f32));
file_allocate_metadata_as_needed(general,
&file->state.buffer, (void**)&file->state.wrap_positions,
&file->state.wrap_position_max, min_amount, sizeof(f32));
}
////////////////////////////////
@ -644,7 +692,7 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File *
}
internal void
file_free(System_Functions *system, General_Memory *general, Editing_File *file){
file_free(System_Functions *system, Application_Links *app, General_Memory *general, Editing_File *file){
if (file->state.still_lexing){
system->cancel_job(BACKGROUND_THREADS, file->state.lex_job);
if (file->state.swap_array.tokens){
@ -656,6 +704,8 @@ file_free(System_Functions *system, General_Memory *general, Editing_File *file)
general_memory_free(general, file->state.token_array.tokens);
}
clear_file_markers_state(app, general, &file->markers);
Gap_Buffer *buffer = &file->state.buffer;
if (buffer->data){
general_memory_free(general, buffer->data);

View File

@ -40,12 +40,18 @@ union Buffer_Slot_ID{
};
struct Marker_Array{
Marker_Array *next, *prev;
Marker_Array *next;
Marker_Array *prev;
Buffer_Slot_ID buffer_id;
u32 count, sim_max, max;
u32 count;
u32 sim_max;
u32 max;
Marker_Delete_Callback *callback;
u32 user_data_size;
u32 rounded_user_data_size;
};
#define MarkerArrayBase(array) (Marker*)((u8*)(array) + sizeof(Marker_Array))
#define MarkerArrayBase(a) (Marker*)((u8*)(a) + sizeof(Marker_Array) + ((Marker_Array*)(a))->rounded_user_data_size)
struct Editing_File_Markers{
Marker_Array sentinel;

View File

@ -533,7 +533,7 @@ kill_file_and_update_views(System_Functions *system, Models *models, Editing_Fil
if (file->canon.name.size != 0){
buffer_unbind_file(system, working_set, file);
}
file_free(system, &models->mem.general, file);
file_free(system, &models->app_links, &models->mem.general, file);
working_set_free_file(&models->mem.general, working_set, file);
File_Node *used = &working_set->used_sentinel;

View File

@ -918,12 +918,12 @@ step_view(System_Functions *system, View *view, Models *models, View *active_vie
if (emit_this_file){
String message = {0};
switch (file_ptr->state.dirty){
case DirtyState_UnloadedChanges:
case DirtyState_UnsavedChanges:
{
message = lit(" *");
}break;
case DirtyState_UnsavedChanges:
case DirtyState_UnloadedChanges:
{
message = lit(" !");
}break;

View File

@ -108,7 +108,6 @@ working_set_free_file(General_Memory *general, Working_Set *working_set, Editin
}
file->is_dummy = 1;
clear_file_markers_state(general, &file->markers);
dll_remove(&file->node);
dll_insert(&working_set->free_sentinel, &file->node);
--working_set->file_count;

View File

@ -440,10 +440,11 @@ main(int argc, char **argv){
test_list.part = &test_list_part;
// NOTE(allen): Tests
push_test(&test_list, "test_load_FONT_COURIER_NEW_28_c.4id");
generate_token_tests(part, &test_list, GenFlag_DoAll);
//push_test(&test_list, "test_load_FONT_COURIER_NEW_28_c.4id");
push_test(&test_list, "test_load_rome_txt.4id");
//generate_token_tests(part, &test_list, GenFlag_DoAll);
//generate_token_tests(part, &test_list, GenFlag_OutputTestNames);
generate_dupline_tests(part, &test_list, GenFlag_DoAll);
//generate_dupline_tests(part, &test_list, GenFlag_DoAll);
//generate_dupline_tests(part, &test_list, GenFlag_OutputTestNames);
// NOTE(allen): Generate the run test script

View File

@ -105,6 +105,8 @@ init_coroutine_system(Coroutine *root, Coroutine_System *sys){
root->type = CoroutineType_Root;
system_init_cv(&root->cv);
system_acquire_lock(&sys->lock);
}
internal void

View File

@ -328,53 +328,80 @@ Sys_Post_Clipboard_Sig(system_post_clipboard){
}
internal b32
win32_read_clipboard_contents(){
win32_read_clipboard_contents(void){
Partition *scratch = &shared_vars.scratch;
Temp_Memory temp = begin_temp_memory(scratch);
b32 result = false;
if (IsClipboardFormatAvailable(CF_UNICODETEXT)){
result = true;
b32 has_text = false;
b32 has_unicode = IsClipboardFormatAvailable(CF_UNICODETEXT);
if (!has_unicode){
has_text = IsClipboardFormatAvailable(CF_TEXT);
}
b32 can_read = has_unicode || has_text;
if (can_read){
if (OpenClipboard(win32vars.window_handle)){
HANDLE clip_data = GetClipboardData(CF_UNICODETEXT);
if (clip_data != 0){
Partition *scratch = &shared_vars.scratch;
Temp_Memory temp = begin_temp_memory(scratch);
u16 *clip_16 = (u16*)GlobalLock(clip_data);
if (clip_16 != 0){
u32 clip_16_len = 0;
for(;clip_16[clip_16_len];++clip_16_len);
b32 error = false;
u32 clip_8_len = (u32)utf16_to_utf8_minimal_checking(win32vars.clip_buffer, win32vars.clip_max-1, clip_16, clip_16_len, &error);
for (;clip_8_len >= win32vars.clip_max && !error;){
system_memory_free(win32vars.clip_buffer, win32vars.clip_max);
win32vars.clip_max = l_round_up_u32(clip_8_len, KB(4));
win32vars.clip_buffer = (u8*)system_memory_allocate(win32vars.clip_max);
result = true;
HANDLE clip_data = 0;
i32 contents_length = 0;
if (has_unicode){
clip_data = GetClipboardData(CF_UNICODETEXT);
if (clip_data != 0){
u16 *clip_16 = (u16*)GlobalLock(clip_data);
if (clip_16 != 0){
u32 clip_16_len = 0;
for(;clip_16[clip_16_len];++clip_16_len);
clip_8_len = (u32)utf16_to_utf8_minimal_checking(win32vars.clip_buffer, win32vars.clip_max - 1, clip_16, clip_16_len, &error);
}
if (clip_8_len < win32vars.clip_max && !error){
win32vars.clip_buffer[clip_8_len] = 0;
b32 error = false;
u32 clip_8_len = (u32)utf16_to_utf8_minimal_checking(win32vars.clip_buffer, win32vars.clip_max-1, clip_16, clip_16_len, &error);
win32vars.clipboard_contents = make_string_cap(win32vars.clip_buffer, clip_8_len, win32vars.clip_max);
for (;clip_8_len >= win32vars.clip_max && !error;){
system_memory_free(win32vars.clip_buffer, win32vars.clip_max);
win32vars.clip_max = l_round_up_u32(clip_8_len + 1, KB(4));
win32vars.clip_buffer = (u8*)system_memory_allocate(win32vars.clip_max);
clip_8_len = (u32)utf16_to_utf8_minimal_checking(win32vars.clip_buffer, win32vars.clip_max - 1, clip_16, clip_16_len, &error);
}
if (clip_8_len < win32vars.clip_max && !error){
win32vars.clip_buffer[clip_8_len] = 0;
contents_length = clip_8_len + 1;
}
}
GlobalUnlock(clip_data);
}
if (win32vars.clipboard_contents.str){
win32vars.clipboard_contents.size = str_size((char*)win32vars.clipboard_contents.str);
}
end_temp_memory(temp);
}
else{
clip_data = GetClipboardData(CF_TEXT);
if (clip_data != 0){
char *clip_ascii = (char*)GlobalLock(clip_data);
if (clip_ascii != 0){
u32 clip_ascii_len = 0;
for(;clip_ascii[clip_ascii_len];++clip_ascii_len);
if (clip_ascii_len >= win32vars.clip_max){
system_memory_free(win32vars.clip_buffer, win32vars.clip_max);
win32vars.clip_max = l_round_up_u32(clip_ascii_len + 1, KB(4));
win32vars.clip_buffer = (u8*)system_memory_allocate(win32vars.clip_max);
}
memcpy(win32vars.clip_buffer, clip_ascii, clip_ascii_len + 1);
contents_length = clip_ascii_len + 1;
}
}
}
if (contents_length > 0){
win32vars.clipboard_contents = make_string_cap(win32vars.clip_buffer, contents_length - 1, win32vars.clip_max);
}
GlobalUnlock(clip_data);
CloseClipboard();
}
}
end_temp_memory(temp);
return(result);
}
@ -1566,16 +1593,23 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
}
// NOTE(allen): Frame Clipboard Input
win32vars.clipboard_contents = null_string;
memset(&win32vars.clipboard_contents, 0, sizeof(win32vars.clipboard_contents));
if (win32vars.clipboard_sequence != 0){
DWORD new_number = GetClipboardSequenceNumber();
if (new_number != win32vars.clipboard_sequence){
win32vars.clipboard_sequence = new_number;
if (win32vars.next_clipboard_is_self){
win32vars.next_clipboard_is_self = 0;
win32vars.next_clipboard_is_self = false;
win32vars.clipboard_sequence = new_number;
}
else{
win32_read_clipboard_contents();
b32 got_contents = false;
for (i32 R = 0; R < 4; ++R){
if (win32_read_clipboard_contents()){
win32vars.clipboard_sequence = new_number;
got_contents = true;
break;
}
}
}
}
}

View File

@ -1,6 +1,10 @@
extensions = ".c.cpp.h.m.bat.sh.4coder.txt.4is";
extensions = ".c.cpp.h.m.bat.sh.4coder.txt";
open_recursively = true;
fkey_command_win[1] = {"build_tests.bat" , "*compilation*" , true , true };
fkey_command_win[2] = {"generate_tests.bat" , "*compilation*" , true , true };
fkey_command_win[3] = {"run_regression_tests.bat" , "*test*" , false, true };
fkey_command_win[1] = {"echo build: x64 & build.bat", "*compilation*" , true , true };
fkey_command_win[2] = {"build_site.bat" , "*site*" , false, true };
fkey_command_win[3] = {"build_string.bat" , "*compilation*" , true , true };
@ -11,10 +15,6 @@ fkey_command_win[7] = {"build_tests.bat" , "*compilation*" , true ,
fkey_command_win[8] = {"generate_tests.bat" , "*compilation*" , true , true };
fkey_command_win[12] = {"package.bat" , "*package*" , false, true };
fkey_command_win[1] = {"build_tests.bat" , "*compilation*" , true , true };
fkey_command_win[2] = {"generate_tests.bat" , "*compilation*" , true , true };
fkey_command_win[3] = {"run_regression_tests.bat" , "*test*" , false, true };
fkey_command_linux[1] = {"echo build: x64 & ./build.sh", "*compilation*" , true , true };
fkey_command_linux[2] = {"build_site.sh" , "*site*" , false, true };
fkey_command_linux[3] = {"build_string.sh" , "*compilation*" , true , true };

View File

@ -7,15 +7,5 @@ pushd ..\build
set build=%cd%
popd
pushd %run_path%
%build%\4ed -T %data_path%\test_load_FONT_COURIER_NEW_28_c.4id
%build%\4ed -T %data_path%\gentest_capstress1.4id
%build%\4ed -T %data_path%\gentest_capstress2.4id
%build%\4ed -T %data_path%\gentest_capstress3.4id
%build%\4ed -T %data_path%\gentest_capstress4.4id
%build%\4ed -T %data_path%\gentest_capstress5.4id
%build%\4ed -T %data_path%\gentest_dupline0_0.4id
%build%\4ed -T %data_path%\gentest_dupline0_1.4id
%build%\4ed -T %data_path%\gentest_dupline1_0.4id
%build%\4ed -T %data_path%\gentest_dupline1_1.4id
%build%\4ed -T %data_path%\gentest_dupline_readonly.4id
%build%\4ed -T %data_path%\test_load_rome_txt.4id
popd

View File

@ -41,7 +41,6 @@ The following bindings apply in all situations.
\ITEM \STYLE{code} <ctrl H> \END If a project file has already been loaded, reloads the same file. Useful for when the project configuration is changed.
\ITEM \STYLE{code} <ctrl S> \END Saves all buffers marked dirty (showing the '*' indicator).
\ITEM \STYLE{code} <alt c> \END Opens the 4coder colors and fonts selector menu.
\ITEM \STYLE{code} <alt d> \END Opens a debug view for internal use.
\ITEM \STYLE{code} <alt .> \END If the special build panel is open, makes the build panel the active panel.
\ITEM \STYLE{code} <alt ,> \END If the special build panel is open, closes it.
\ITEM \STYLE{code} <alt n> \END 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.
@ -51,7 +50,7 @@ The following bindings apply in all situations.
\ITEM \STYLE{code} <alt z> \END Queries for an output buffer name and system command, runs the system command as a CLI and prints the output to the specified buffer.
\ITEM \STYLE{code} <alt Z> \END If the command execute_any_cli has already been used, this will execute a CLI reusing the most recent buffer name and command.
\ITEM \STYLE{code} <alt x> \END Execute a 'long form' command.
\ITEM \STYLE{code} <alt s> \END Sets the current view to show it's scrollbar.
\ITEM \STYLE{code} <alt W> \END Sets the current view to show it's scrollbar.
\ITEM \STYLE{code} <alt w> \END Sets the current view to hide it's scrollbar.
\ITEM \STYLE{code} <alt b> \END Toggles the visibility status of the current view's filebar.
\ITEM \STYLE{code} <alt @> \END Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.
@ -94,6 +93,8 @@ The following bindings apply in general text files and most apply in code files,
\ITEM \STYLE{code} <down> \END Moves the cursor down one line.
\ITEM \STYLE{code} <end> \END Seeks the cursor to the end of the visual line.
\ITEM \STYLE{code} <home> \END Seeks the cursor to the beginning of the visual line.
\ITEM \STYLE{code} <ctrl page up> \END Sets the cursor to the beginning of the file.
\ITEM \STYLE{code} <ctrl page down> \END Sets the cursor to the end of the file.
\ITEM \STYLE{code} <page up> \END Scrolls the view up one view height and moves the cursor up one view height.
\ITEM \STYLE{code} <page down> \END Scrolls the view down one view height and moves the cursor down one view height.
\ITEM \STYLE{code} <ctrl right> \END Seek right for the next boundary between whitespace and non-whitespace.
@ -129,6 +130,7 @@ The following bindings apply in general text files and most apply in code files,
\ITEM \STYLE{code} <alt q> \END Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.
\ITEM \STYLE{code} <ctrl r> \END Begins an incremental search up through the current buffer for a user specified string.
\ITEM \STYLE{code} <ctrl s> \END Saves the current buffer.
\ITEM \STYLE{code} <alt s> \END Queries the user for a name and saves the contents of the current buffer, altering the buffer's name too.
\ITEM \STYLE{code} <ctrl t> \END Begins an incremental search down through the current buffer for the word or token under the cursor.
\ITEM \STYLE{code} <ctrl T> \END Reads a token or word under the cursor and lists all exact case-sensitive mathces in all open buffers.
\ITEM \STYLE{code} <ctrl u> \END Converts all ascii text in the range between the cursor and the mark to uppercase.
@ -203,7 +205,6 @@ The following bindings apply in all situations.
\ITEM \STYLE{code} <cmnd H> \END If a project file has already been loaded, reloads the same file. Useful for when the project configuration is changed.
\ITEM \STYLE{code} <cmnd S> \END Saves all buffers marked dirty (showing the '*' indicator).
\ITEM \STYLE{code} <ctrl c> \END Opens the 4coder colors and fonts selector menu.
\ITEM \STYLE{code} <ctrl d> \END Opens a debug view for internal use.
\ITEM \STYLE{code} <ctrl .> \END If the special build panel is open, makes the build panel the active panel.
\ITEM \STYLE{code} <ctrl ,> \END If the special build panel is open, closes it.
\ITEM \STYLE{code} <ctrl n> \END If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.
@ -213,7 +214,7 @@ The following bindings apply in all situations.
\ITEM \STYLE{code} <ctrl z> \END Queries for an output buffer name and system command, runs the system command as a CLI and prints the output to the specified buffer.
\ITEM \STYLE{code} <ctrl Z> \END If the command execute_any_cli has already been used, this will execute a CLI reusing the most recent buffer name and command.
\ITEM \STYLE{code} <ctrl x> \END Execute a 'long form' command.
\ITEM \STYLE{code} <ctrl s> \END Sets the current view to show it's scrollbar.
\ITEM \STYLE{code} <ctrl W> \END Sets the current view to show it's scrollbar.
\ITEM \STYLE{code} <ctrl w> \END Sets the current view to hide it's scrollbar.
\ITEM \STYLE{code} <ctrl b> \END Toggles the visibility status of the current view's filebar.
\ITEM \STYLE{code} <ctrl @> \END Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.
@ -257,6 +258,8 @@ The following bindings apply in general text files and most apply in code files,
\ITEM \STYLE{code} <down> \END Moves the cursor down one line.
\ITEM \STYLE{code} <end> \END Seeks the cursor to the end of the visual line.
\ITEM \STYLE{code} <home> \END Seeks the cursor to the beginning of the visual line.
\ITEM \STYLE{code} <ctrl page up> \END Sets the cursor to the beginning of the file.
\ITEM \STYLE{code} <ctrl page down> \END Sets the cursor to the end of the file.
\ITEM \STYLE{code} <page up> \END Scrolls the view up one view height and moves the cursor up one view height.
\ITEM \STYLE{code} <page down> \END Scrolls the view down one view height and moves the cursor down one view height.
\ITEM \STYLE{code} <cmnd right> \END Seek right for the next boundary between whitespace and non-whitespace.
@ -289,6 +292,7 @@ The following bindings apply in general text files and most apply in code files,
\ITEM \STYLE{code} <cmnd Q> \END Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.
\ITEM \STYLE{code} <cmnd r> \END Begins an incremental search up through the current buffer for a user specified string.
\ITEM \STYLE{code} <cmnd s> \END Saves the current buffer.
\ITEM \STYLE{code} <ctrl s> \END Queries the user for a name and saves the contents of the current buffer, altering the buffer's name too.
\ITEM \STYLE{code} <cmnd t> \END Begins an incremental search down through the current buffer for the word or token under the cursor.
\ITEM \STYLE{code} <cmnd T> \END Reads a token or word under the cursor and lists all exact case-sensitive mathces in all open buffers.
\ITEM \STYLE{code} <cmnd u> \END Converts all ascii text in the range between the cursor and the mark to uppercase.

View File

@ -0,0 +1,15 @@
basewait 1
key P MDFR_CTRL
key o MDFR_CTRL
type 1 rome.txt
key key_newline MDFR_NONE
key key_page_down MDFR_CTRL
key key_newline MDFR_NONE
key key_newline MDFR_NONE
wait 20
type 0 Hello World!
wait 2
exit
key y MDFR_NONE