Character positioning by line relative layout iteration

master
Allen Webster 2019-09-02 11:59:36 -07:00
parent 1346813108
commit aaec0cc3c8
56 changed files with 3033 additions and 8468 deletions

View File

@ -41,6 +41,16 @@ STRUCT Buffer_Point{
Vec2 pixel_shift;
};
STRUCT Line_Shift_Vertical{
i64 line;
f32 y_delta;
};
STRUCT Line_Shift_Character{
i64 line;
i64 character_delta;
};
ENUM(u32, Child_Process_Set_Target_Flags){
ChildProcessSet_FailIfBufferAlreadyAttachedToAProcess = 1,
ChildProcessSet_FailIfProcessAlreadyAttachedToABuffer = 2,
@ -469,143 +479,56 @@ STRUCT Buffer_Identifier{
Buffer_ID id;
};
/* DOC(Describes the various coordinate locations associated with the view's scroll position within it's buffer.) */
STRUCT GUI_Scroll_Vars{
UNION{
STRUCT{
/* DOC(The current actual x position of the view scroll.) */
f32 scroll_x;
/* DOC(The current actual y position of the view scroll.) */
f32 scroll_y;
};
/* DOC(TODO) */
Vec2 scroll_p;
};
UNION{
STRUCT{
/* DOC(The target x position to which the view is moving. If scroll_x is not the same value, then it is still sliding to the target by the smooth scroll rule.) */
i32 target_x;
/* DOC(The target y position to which the view is moving. If scroll_y is not the same value, then it is still sliding to the target by the smooth scroll rule.) */
i32 target_y;
};
/* DOC(TODO) */
Vec2_i32 target_p;
};
STRUCT Buffer_Scroll{
Buffer_Point position;
Buffer_Point target;
};
STRUCT Basic_Scroll{
Vec2_f32 position;
Vec2_f32 target;
};
/* DOC(The Buffer_Seek_Type is is used in a Buffer_Seek to identify which coordinates are suppose to be used for the seek.)
DOC_SEE(Buffer_Seek)
DOC_SEE(4coder_Buffer_Positioning_System)
*/
ENUM(i32, Buffer_Seek_Type){
/* DOC(This value indicates absolute byte index positioning
where positions are measured as the number of bytes from the start of the file.) */
buffer_seek_pos,
/* DOC(This value indicates apparent character index positioning
where positions are measured as the number of apparent characters from the starts of the file.) */
buffer_seek_character_pos,
/* DOC(This value indicates xy positioning with wrapped lines where the x and y values are in pixels.) */
buffer_seek_wrapped_xy,
/* DOC(This value indicates xy positioning with unwrapped lines where the x and y values are in pixels.) */
buffer_seek_unwrapped_xy,
/* DOC(This value indicates line-character positioning.
These coordinates are 1 based to match standard line numbering.) */
buffer_seek_line_char
buffer_seek_line_col,
};
/* DOC(Buffer_Seek describes the destination of a seek operation. There are helpers for concisely creating Buffer_Seek structs. They can be found in 4coder_buffer_types.h.)
DOC_SEE(Buffer_Seek_Type)
DOC_SEE(4coder_Buffer_Positioning_System) */
STRUCT Buffer_Seek{
/* DOC(The type field determines the coordinate system of the seek operation.) */
Buffer_Seek_Type type;
UNION{
STRUCT {
/* DOC(The pos field specified the pos when the seek is in absolute position.) */
STRUCT{
i64 pos;
};
STRUCT {
/* DOC(For xy coordinate seeks, rounding down means that any x in the box of the character lands on that character. For instance when clicking rounding down is the user's expected behavior. Not rounding down means that the right hand portion of the character's box, which is closer to the next character, will land on that next character. The unrounded behavior is the expected behavior when moving vertically and keeping the preferred x.) */
b32 round_down;
/* DOC(The x coordinate for xy type seeks.) */
f32 x;
/* DOC(The y coordinate for xy type seeks.) */
f32 y;
};
STRUCT {
/* DOC(The line number of a line-character type seek.) */
STRUCT{
i64 line;
/* DOC(The character number of a line-character type seek.) */
i64 character;
i64 col;
};
};
};
/* DOC(Full_Cursor describes the position of a cursor in every buffer coordinate system supported by 4coder. This cursor type requires that the buffer is associated with a view to give the x/y values meaning.)
DOC_SEE(4coder_Buffer_Positioning_System) */
STRUCT Full_Cursor{
/* DOC(This field contains the cursor's position in absolute byte index positioning.) */
STRUCT Buffer_Cursor{
i64 pos;
/* DOC(This field contains the cursor's position in apparent character index positioning.) */
i64 character_pos;
/* DOC(This field contains the number of the line where the cursor is located. This field is one based.) */
i64 line;
/* DOC(This field contains the number of the character from the beginninf of the line where the cursor is located. This field is one based.) */
i64 character;
/* DOC(This field contains the number of the line where the cursor is located, taking the line wrapping into account. This field is one based.) */
i64 wrap_line;
union{
struct{
/* DOC(This field contains the x position measured with unwrapped lines.) */
f32 unwrapped_x;
/* DOC(This field contains the y position measured with unwrapped lines.) */
f32 unwrapped_y;
};
/* DOC(TODO) */
Vec2 unwrapped_p;
};
union{
struct{
/* DOC(This field contains the x position measured with wrapped lines.) */
f32 wrapped_x;
/* DOC(This field contains the y position measured with wrapped lines.) */
f32 wrapped_y;
};
/* DOC(TODO) */
Vec2 wrapped_p;
};
i64 col;
};
/* DOC(Partial_Cursor describes the position of a cursor in all of the coordinate systems that a invariant to the View. In other words the coordinate systems available here can be used on a buffer that is not currently associated with a View.)
DOC_SEE(4coder_Buffer_Positioning_System) */
STRUCT Partial_Cursor{
/* DOC(This field contains the cursor's position in absolute byte index positioning.) */
i32 pos;
/* DOC(This field contains the cursor's position in apparent character index positioning.) */
i32 character_pos;
/* DOC(This field contains the number of the character from the beginninf of the line
where the cursor is located. This field is one based.) */
i32 line;
/* DOC(This field contains the number of the column where the cursor is located. This field is one based.) */
i32 character;
};
STRUCT Range_Partial_Cursor{
STRUCT Range_Cursor{
struct{
Partial_Cursor min;
Partial_Cursor max;
Buffer_Cursor min;
Buffer_Cursor max;
};
struct{
Partial_Cursor begin;
Partial_Cursor end;
Buffer_Cursor begin;
Buffer_Cursor end;
};
struct{
Partial_Cursor start;
Partial_Cursor end;
Buffer_Cursor start;
Buffer_Cursor end;
};
struct{
Partial_Cursor first;
Partial_Cursor one_past_last;
Buffer_Cursor first;
Buffer_Cursor one_past_last;
};
};
@ -651,12 +574,6 @@ static Managed_Scope ManagedScope_NULL = 0;
static Managed_Variable_ID ManagedVariableIndex_ERROR = -1;
static Managed_Object ManagedObject_NULL = 0;
STRUCT Text_Layout_Coordinates{
Vec2_f32 on_screen_p0;
Vec2_f32 in_buffer_p0;
Vec2_f32 dim;
};
/* DOC(A multi-member identifier for a marker visual. A marker visual is attached to a marker object (Marker_Object), it is freed when the marker object is freed or when it is specifically destroyed. Multiple marker visuals can be placed on a single marker object.)
DOC_SEE(Marker_Visual_Type)
DOC_SEE(Marker_Visual_Symbolic_Color)
@ -843,34 +760,14 @@ STRUCT Face_Metrics{
f32 typical_character_width;
};
/* DOC(Buffer_Edit describes a range of a buffer and string to replace that range. A Buffer_Edit has to be paired with a string that contains the actual
text that will be replaced into the buffer.) */
STRUCT Buffer_Edit{
/* DOC(The str_start field specifies the first character in the accompanying string that corresponds with this edit.) */
i32 str_start;
/* DOC(The len field specifies the length of the string being written into the buffer.) */
i32 len;
/* DOC(The start field specifies the start of the range in the buffer to replace in absolute position.) */
i32 start;
/* DOC(The end field specifies one past the end of the range in the buffer to replace in absolute position.) */
i32 end;
STRUCT Edit{
String_Const_u8 text;
Interval_i64 range;
};
/*
DOC(This struct is used to bundle the parameters of the buffer_batch_edit function. It is convenient for a few functions that return a batch edit to the user.)
DOC_SEE(Buffer_Edit)
DOC_SEE(buffer_batch_edit)
*/
STRUCT Buffer_Batch_Edit{
/* DOC(The pointer to the edit string buffer.) */
char *str;
/* DOC(The length of the edit string buffer.) */
i32 str_len;
/* DOC(The array of edits to be applied.) */
Buffer_Edit *edits;
/* DOC(The number of edits in the array.) */
i32 edit_count;
STRUCT Batch_Edit{
Batch_Edit *next;
Edit edit;
};
ENUM(i32, Record_Kind){
@ -1022,8 +919,9 @@ TYPEDEF_FUNC i32 Hook_Function(struct Application_Links *app);
TYPEDEF_FUNC i32 Open_File_Hook_Function(struct Application_Links *app, Buffer_ID buffer_id);
#define OPEN_FILE_HOOK_SIG(name) i32 name(struct Application_Links *app, Buffer_ID buffer_id)
TYPEDEF_FUNC i32 File_Edit_Range_Function(struct Application_Links *app, Buffer_ID buffer_id, Range range, String_Const_u8 text);
#define FILE_EDIT_RANGE_SIG(name) i32 name(struct Application_Links *app, Buffer_ID buffer_id, Range range, String_Const_u8 text)
TYPEDEF_FUNC i32 File_Edit_Range_Function(struct Application_Links *app, Buffer_ID buffer_id,
Interval_i64 range, String_Const_u8 text);
#define FILE_EDIT_RANGE_SIG(name) i32 name(struct Application_Links *app, Buffer_ID buffer_id, Interval_i64 range, String_Const_u8 text)
TYPEDEF_FUNC i32 File_Edit_Finished_Function(struct Application_Links *app, Buffer_ID *buffer_ids, i32 buffer_id_count);
#define FILE_EDIT_FINISHED_SIG(name) i32 name(struct Application_Links *app, Buffer_ID *buffer_ids, i32 buffer_id_count)
@ -1034,9 +932,8 @@ TYPEDEF_FUNC i32 File_Externally_Modified_Function(struct Application_Links *app
TYPEDEF_FUNC void Input_Filter_Function(Mouse_State *mouse);
#define INPUT_FILTER_SIG(name) void name(Mouse_State *mouse)
TYPEDEF_FUNC i32 Scroll_Rule_Function(float target_x, float target_y, float *scroll_x, float *scroll_y, i32 view_id, i32 is_new_target, float dt);
#define SCROLL_RULE_SIG(name) \
i32 name(float target_x, float target_y, float *scroll_x, float *scroll_y, i32 view_id, i32 is_new_target, float dt)
TYPEDEF_FUNC Vec2_f32 Delta_Rule_Function(Vec2_f32 pending_delta, View_ID view_id, b32 is_new_target, f32 dt);
#define DELTA_RULE_SIG(name) Vec2_f32 name(Vec2_f32 pending_delta, View_ID view_id, b32 is_new_target, f32 dt)
STRUCT Color_Table{
argb_color *vals;

View File

@ -1,644 +0,0 @@
/*
* Helpers for the API transition from 4.0.30 to 4.0.31
*
* In order to keep your layer on the old API you don't have to do anything, this provides wrappers
* idential to the 4.0.30 API.
* In order to transition your entire layer over to the 4.0.31 API define 'REMOVE_TRANSITION_HELPER_31' and fix errors.
* Or you can do it step by step by removing a few wrappers at a time.
* This transition helper will be removed in a future version so it is recommended to get off sooner or laster.
*
* Tips on transitioning:
*
* Wrather than just try to inline this code everywhere, you can simplify things quite a lot by storing references
* to buffers and views and Buffer_ID and View_ID instead of Buffer_Summary and View_Summary.
* Just get the summaries when you need information in those structures.
*
* You will make your code simpler if you stick to String as much as possible, but whenever you want to you can switch
* to any string type you have to String by calling make_string(char_ptr, length) or make_string_slowly(null_terminated_c_str).
* To pull the char ptr and length out of a String named "string": string.str and str.size.
* If you need a null terminated string from a String use get_null_terminated in 4coder_helper.cpp
*
*/
// TOP
#if !defined(REMOVE_TRANSITION_HELPER_31)
typedef b32 bool32;
static b32
get_buffer_summary(Application_Links *app, Buffer_ID buffer, Access_Flag access, Buffer_Summary *summary){
b32 result = false;
if (buffer_exists(app, buffer)){
Scratch_Block scratch(app);
Access_Flag buffer_access_flags = buffer_get_access_flags(app, buffer);
if ((buffer_access_flags & ~access) == 0){
result = true;
summary->exists = true;
summary->ready = buffer_ready(app, buffer);
summary->buffer_id = buffer;
summary->size = (i32)buffer_get_size(app, buffer);
summary->line_count = (i32)buffer_get_line_count(app, buffer);
String_Const_u8 file_name_get = push_buffer_file_name(app, scratch, buffer);
block_copy(summary->file_name, file_name_get.str, file_name_get.size);
summary->file_name_len = (i32)file_name_get.size;
String_Const_u8 buffer_name_get = push_buffer_unique_name(app, scratch, buffer);
block_copy(summary->buffer_name, buffer_name_get.str, buffer_name_get.size);
summary->buffer_name_len = (i32)buffer_name_get.size;
summary->dirty = buffer_get_dirty_state(app, buffer);
buffer_get_setting(app, buffer, BufferSetting_Lex, &summary->is_lexed);
summary->tokens_are_ready = buffer_tokens_are_ready(app, buffer);
buffer_get_setting(app, buffer, BufferSetting_MapID, &summary->map_id);
buffer_get_setting(app, buffer, BufferSetting_WrapLine, &summary->unwrapped_lines);
summary->unwrapped_lines = !summary->unwrapped_lines;
summary->lock_flags = buffer_access_flags;
}
}
return(result);
}
static b32
get_view_summary(Application_Links *app, View_ID view_id, Access_Flag access, View_Summary *view){
b32 result = false;
if (view_exists(app, view_id)){
Buffer_ID buffer = view_get_buffer(app, view_id, access);
if (buffer != 0){
result = true;
Face_ID face_id = get_face_id(app, buffer);
Face_Metrics metrics = get_face_metrics(app, face_id);
view->exists = true;
view->view_id = view_id;
view->line_height = metrics.line_height;
buffer_get_setting(app, buffer, BufferSetting_WrapLine, &view->unwrapped_lines);
view->unwrapped_lines = !view->unwrapped_lines;
view_get_setting(app, view_id, ViewSetting_ShowWhitespace, &view->show_whitespace);
view->buffer_id = buffer;
i64 pos = view_get_mark_pos(app, view_id);
view->mark = view_compute_cursor(app, view_id, seek_pos(pos));
pos = view_get_cursor_pos(app, view_id);
view->cursor = view_compute_cursor(app, view_id, seek_pos(pos));
view->preferred_x = view_get_preferred_x(app, view_id);
Rect_f32 screen_rect = view_get_screen_rect(app, view_id);
view->view_region = screen_rect;
view->render_region = Rf32(0.f, 0.f, rect_width(screen_rect), rect_height(screen_rect));
view->scroll_vars = view_get_scroll_vars(app, view_id);
}
}
return(result);
}
static b32
clipboard_post(Application_Links *app, i32 clipboard_id, char *str, i32 len){
return(clipboard_post(app, clipboard_id, SCu8(str, len)));
}
static i32
clipboard_index(Application_Links *app, i32 clipboard_id, i32 item_index, char *out, i32 len){
Scratch_Block scratch(app);
String_Const_u8 string = push_clipboard_index(app, scratch, clipboard_id, item_index);
block_copy(out, string.str, clamp_top((i32)string.size, len));
return((i32)string.size);
}
static Buffer_Summary
get_buffer_first(Application_Links *app, Access_Flag access){
Buffer_Summary buffer = {};
Buffer_ID buffer_id = get_buffer_next(app, 0, access);
if (buffer_id != 0){
get_buffer_summary(app, buffer_id, access, &buffer);
}
return(buffer);
}
static void
get_buffer_next(Application_Links *app, Buffer_Summary *buffer, Access_Flag access){
if (buffer != 0 && buffer->exists){
Buffer_ID buffer_id = get_buffer_next(app, buffer->buffer_id, access);
if (buffer_id != 0){
get_buffer_summary(app, buffer_id, access, buffer);
}
else{
block_zero_struct(buffer);
}
}
}
static Buffer_Summary
get_buffer(Application_Links *app, Buffer_ID buffer_id, Access_Flag access){
Buffer_Summary buffer = {};
get_buffer_summary(app, buffer_id, access, &buffer);
return(buffer);
}
static Buffer_Summary
get_buffer_by_name(Application_Links *app, char *name, i32 len, Access_Flag access){
Buffer_Summary buffer = {};
Buffer_ID id = get_buffer_by_name(app, SCu8(name, len), access);
if (id != 0){
get_buffer_summary(app, id, access, &buffer);
}
return(buffer);
}
static Buffer_Summary
get_buffer_by_file_name(Application_Links *app, char *name, i32 len, Access_Flag access){
Buffer_Summary buffer = {};
Buffer_ID id = get_buffer_by_file_name(app, SCu8(name, len), access);
if (id != 0){
get_buffer_summary(app, id, access, &buffer);
}
return(buffer);
}
static b32
buffer_read_range(Application_Links *app, Buffer_Summary *buffer, i32 start, i32 one_past_last, char *out){
b32 result = false;
if (buffer != 0 && buffer->exists){
result = buffer_read_range(app, buffer->buffer_id, Ii64(start, one_past_last), out);
get_buffer_summary(app, buffer->buffer_id, AccessAll, buffer);
}
return(result);
}
static b32
buffer_replace_range(Application_Links *app, Buffer_Summary *buffer, i32 start, i32 one_past_last, char *str, i32 len){
b32 result = false;
if (buffer != 0 && buffer->exists){
result = buffer_replace_range(app, buffer->buffer_id, Ii64(start, one_past_last), SCu8(str, len));
get_buffer_summary(app, buffer->buffer_id, AccessAll, buffer);
}
return(result);
}
static b32
buffer_compute_cursor(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out){
b32 result = false;
if (buffer != 0 && buffer->exists){
*cursor_out = buffer_compute_cursor(app, buffer->buffer_id, seek);
result = (cursor_out->line > 0);
get_buffer_summary(app, buffer->buffer_id, AccessAll, buffer);
}
return(result);
}
static b32
buffer_batch_edit(Application_Links *app, Buffer_Summary *buffer, char *str, i32 str_len, Buffer_Edit *edits, i32 edit_count, i32 type){
b32 result = false;
if (buffer != 0 && buffer->exists){
result = buffer_batch_edit(app, buffer->buffer_id, str, edits, edit_count);
get_buffer_summary(app, buffer->buffer_id, AccessAll, buffer);
}
return(result);
}
static b32
buffer_get_setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, i32 *value_out){
b32 result = false;
if (buffer != 0 && buffer->exists){
result = buffer_get_setting(app, buffer->buffer_id, setting, value_out);
get_buffer_summary(app, buffer->buffer_id, AccessAll, buffer);
}
return(result);
}
static b32
buffer_set_setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, i32 value){
b32 result = false;
if (buffer != 0 && buffer->exists){
result = buffer_set_setting(app, buffer->buffer_id, setting, value);
get_buffer_summary(app, buffer->buffer_id, AccessAll, buffer);
}
return(result);
}
static i32
buffer_token_count(Application_Links *app, Buffer_Summary *buffer){
i32 count = 0;
if (buffer != 0 && buffer->exists){
count = buffer_get_token_array(app, buffer->buffer_id).count;
}
return(count);
}
static b32
buffer_read_tokens(Application_Links *app, Buffer_ID buffer, i32 start_token, i32 end_token, Cpp_Token *tokens_out){
b32 result = false;
if (buffer != 0){
Cpp_Token_Array array = buffer_get_token_array(app, buffer);
if (0 <= start_token && start_token <= end_token && end_token < array.count){
result = true;
block_copy_dynamic_array(tokens_out, array.tokens + start_token, end_token - start_token);
}
}
return(result);
}
static b32
buffer_read_tokens(Application_Links *app, Buffer_Summary *buffer, i32 start_token, i32 end_token, Cpp_Token *tokens_out){
Buffer_ID buffer_id = (buffer==0?0:buffer->buffer_id);
b32 result = buffer_read_tokens(app, buffer_id, start_token, end_token, tokens_out);
get_buffer_summary(app, buffer_id, AccessAll, buffer);
return(result);
}
static b32
buffer_get_token_range(Application_Links *app, Buffer_Summary *buffer, Cpp_Token **first_token_out, Cpp_Token **one_past_last_token_out){
b32 result = false;
if (buffer != 0 && buffer->exists){
Cpp_Token_Array array = buffer_get_token_array(app, buffer->buffer_id);
result = true;
if (first_token_out != 0){
*first_token_out = array.tokens;
}
if (one_past_last_token_out != 0){
*one_past_last_token_out = array.tokens + array.count;
}
get_buffer_summary(app, buffer->buffer_id, AccessAll, buffer);
}
return(result);
}
static b32
buffer_get_token_index(Application_Links *app, Buffer_Summary *buffer, i32 pos, Cpp_Get_Token_Result *get_result){
b32 result = false;
if (buffer != 0 && buffer->exists){
Cpp_Token_Array array = buffer_get_token_array(app, buffer->buffer_id);
result = true;
*get_result = cpp_get_token(array, pos);
get_buffer_summary(app, buffer->buffer_id, AccessAll, buffer);
}
return(result);
}
static b32
buffer_send_end_signal(Application_Links *app, Buffer_Summary *buffer){
b32 result = false;
if (buffer != 0 && buffer->exists){
result = buffer_send_end_signal(app, buffer->buffer_id);
get_buffer_summary(app, buffer->buffer_id, AccessAll, buffer);
}
return(result);
}
static Buffer_Summary
create_buffer(Application_Links *app, char *filename, i32 filename_len, Buffer_Create_Flag flags){
Buffer_Summary buffer = {};
Buffer_ID buffer_id = create_buffer(app, SCu8(filename, filename_len), flags);
if (buffer_id != 0){
get_buffer_summary(app, buffer_id, AccessAll, &buffer);
}
return(buffer);
}
static b32
save_buffer(Application_Links *app, Buffer_Summary *buffer, char *file_name, i32 file_name_len, u32 flags){
b32 result = false;
if (buffer != 0 && buffer->exists){
result = buffer_save(app, buffer->buffer_id, SCu8(file_name, file_name_len), flags);
get_buffer_summary(app, buffer->buffer_id, AccessAll, buffer);
}
return(result);
}
static Buffer_Kill_Result
kill_buffer(Application_Links *app, Buffer_Identifier buffer, Buffer_Kill_Flag flags){
Buffer_Kill_Result result = 0;
if (buffer.id != 0){
result = buffer_kill(app, buffer.id, flags);
}
else if (buffer.name != 0){
Buffer_ID id = get_buffer_by_name(app, SCu8(buffer.name, buffer.name_len), AccessAll);
if (id != 0){
result = buffer_kill(app, id, flags);
}
}
return(result);
}
static Buffer_Reopen_Result
reopen_buffer(Application_Links *app, Buffer_Summary *buffer, Buffer_Reopen_Flag flags){
Buffer_Reopen_Result result = 0;
if (buffer != 0 && buffer->exists){
result = buffer_reopen(app, buffer->buffer_id, flags);
}
return(result);
}
static View_Summary
get_view_first(Application_Links *app, Access_Flag access){
View_Summary view = {};
View_ID view_id = get_view_next(app, 0, access);
if (view_id != 0){
get_view_summary(app, view_id, access, &view);
}
return(view);
}
static void
get_view_next(Application_Links *app, View_Summary *view, Access_Flag access){
if (view != 0 && view->exists){
View_ID view_id = get_view_next(app, view->view_id, access);
if (view_id != 0){
get_view_summary(app, view_id, access, view);
}
else{
block_zero_struct(view);
}
}
}
static View_Summary
get_view(Application_Links *app, View_ID view_id, Access_Flag access){
View_Summary view = {};
get_view_summary(app, view_id, access, &view);
return(view);
}
static View_Summary
get_active_view_DEP(Application_Links *app, Access_Flag access){
View_Summary view = {};
View_ID id = get_active_view(app, access);
if (id != 0){
get_view_summary(app, id, access, &view);
}
return(view);
}
static View_Summary
open_view(Application_Links *app, View_Summary *view_location, View_Split_Position position){
View_Summary view = {};
if (view_location != 0 && view_location->exists){
Panel_ID panel_id = view_get_panel(app, view_location->view_id);
if (panel_id != 0){
b32 vertical = (position == ViewSplit_Left || position == ViewSplit_Right);
if (panel_split(app, panel_id, vertical?PanelSplit_LeftAndRight:PanelSplit_TopAndBottom)){
Panel_Child child = (position == ViewSplit_Left || position == ViewSplit_Top)?PanelChild_Min:PanelChild_Max;
Panel_ID new_panel_id = panel_get_child(app, panel_id, child);
if (new_panel_id != 0){
View_ID new_view_id = panel_get_view(app, new_panel_id);
if (new_view_id != 0){
get_view_summary(app, new_view_id, AccessAll, &view);
get_view_summary(app, view_location->view_id, AccessAll, view_location);
}
}
}
}
}
return(view);
}
static b32
close_view(Application_Links *app, View_Summary *view){
b32 result = false;
if (view != 0 && view->exists){
result = view_close(app, view->view_id);
}
return(result);
}
static b32
set_active_view(Application_Links *app, View_Summary *view){
b32 result = false;
if (view != 0 && view->exists){
result = view_set_active(app, view->view_id);
}
return(result);
}
static b32
view_get_setting(Application_Links *app, View_Summary *view, View_Setting_ID setting, i32 *value_out){
b32 result = false;
if (view != 0 && view->exists){
result = view_get_setting(app, view->view_id, setting, value_out);
get_view_summary(app, view->view_id, AccessAll, view);
}
return(result);
}
static b32
view_set_setting(Application_Links *app, View_Summary *view, View_Setting_ID setting, i32 value){
b32 result = false;
if (view != 0 && view->exists){
result = view_set_setting(app, view->view_id, setting, value);
get_view_summary(app, view->view_id, AccessAll, view);
}
return(result);
}
static b32
view_compute_cursor_DEP(Application_Links *app, View_Summary *view, Buffer_Seek seek, Full_Cursor *cursor_out){
b32 result = false;
if (view != 0 && view->exists){
*cursor_out = view_compute_cursor(app, view->view_id, seek);
result = (cursor_out->line > 0);
get_view_summary(app, view->view_id, AccessAll, view);
}
return(result);
}
static b32
view_set_cursor(Application_Links *app, View_Summary *view, Buffer_Seek seek, b32 set_preferred_x){
b32 result = false;
if (view != 0 && view->exists){
result = view_set_cursor(app, view->view_id, seek, set_preferred_x);
get_view_summary(app, view->view_id, AccessAll, view);
}
return(result);
}
static b32
view_set_scroll(Application_Links *app, View_Summary *view, GUI_Scroll_Vars scroll){
b32 result = false;
if (view != 0 && view->exists){
result = view_set_scroll(app, view->view_id, scroll);
get_view_summary(app, view->view_id, AccessAll, view);
}
return(result);
}
static b32
view_set_mark(Application_Links *app, View_Summary *view, Buffer_Seek seek){
b32 result = false;
if (view != 0 && view->exists){
result = view_set_mark(app, view->view_id, seek);
get_view_summary(app, view->view_id, AccessAll, view);
}
return(result);
}
static b32
view_set_buffer(Application_Links *app, View_Summary *view, Buffer_ID buffer_id, Set_Buffer_Flag flags){
b32 result = false;
if (view != 0 && view->exists){
result = view_set_buffer(app, view->view_id, buffer_id, flags);
get_view_summary(app, view->view_id, AccessAll, view);
}
return(result);
}
static b32
view_post_fade(Application_Links *app, View_Summary *view, float seconds, i32 start, i32 end, int_color color){
b32 result = false;
if (view != 0 && view->exists){
result = view_post_fade(app, view->view_id, seconds, Ii64(start, end), color);
get_view_summary(app, view->view_id, AccessAll, view);
}
return(result);
}
static b32
view_begin_ui_mode(Application_Links *app, View_Summary *view){
b32 result = false;
if (view != 0 && view->exists){
result = view_begin_ui_mode(app, view->view_id);
get_view_summary(app, view->view_id, AccessAll, view);
}
return(result);
}
static b32
view_end_ui_mode(Application_Links *app, View_Summary *view){
b32 result = false;
if (view != 0 && view->exists){
result = view_end_ui_mode(app, view->view_id);
get_view_summary(app, view->view_id, AccessAll, view);
}
return(result);
}
static b32
view_set_highlight(Application_Links *app, View_ID view_id, i32 start, i32 end, b32 turn_on){
// NOTE(allen): this feature is completely removed, transition to using highlighted markers instead
return(false);
}
static b32
buffer_set_face(Application_Links *app, Buffer_Summary *buffer, Face_ID id){
b32 result = false;
if (buffer != 0 && buffer->exists){
result = buffer_set_face(app, buffer->buffer_id, id);
get_buffer_summary(app, buffer->buffer_id, AccessAll, buffer);
}
return(result);
}
static Face_ID
get_face_id(Application_Links *app, Buffer_Summary *buffer){
Face_ID result = 0;
if (buffer != 0 && buffer->exists){
result = get_face_id(app, buffer->buffer_id);
}
else{
result = get_face_id(app, 0);
}
return(result);
}
static void
print_message(Application_Links *app, char *str, i32 len){
print_message(app, SCu8(str, len));
}
#if 0
static void
create_theme(Application_Links *app, Theme *theme, char *name, i32 len){
create_theme(app, theme, make_string(name, len));
}
static void
change_theme(Application_Links *app, char *name, i32 len){
change_theme(app, make_string(name, len));
}
#endif
static i32
directory_get_hot(Application_Links *app, char *out, i32 capacity){
Scratch_Block scratch(app);
String_Const_u8 string = push_hot_directory(app, scratch);
block_copy(out, string.str, clamp_top((i32)string.size, capacity));
return((i32)string.size);
}
static b32
directory_set_hot(Application_Links *app, char *str, i32 len){
return(set_hot_directory(app, SCu8(str, len)));
}
static b32
file_exists(Application_Links *app, char *file_name, i32 len){
File_Attributes attributes = get_file_attributes(app, SCu8(file_name, len));
return(attributes.last_write_time > 0);
}
static b32
directory_cd(Application_Links *app, char *dir, i32 *len, i32 capacity, char *rel_path, i32 rel_len){
String_Const_u8 directory = SCu8(dir, *len);
String_Const_u8 relative_path = SCu8(rel_path, rel_len);
Scratch_Block scratch(app);
String_Const_u8 new_directory = {};
b32 result = false;
if (relative_path.size > 0){
if (string_match(relative_path, string_u8_litexpr("."))){
new_directory = directory;
result = true;
}
else if (string_match(relative_path, string_u8_litexpr(".."))){
directory = string_remove_last_folder(directory);
if (file_exists(app, (char*)directory.str, (i32)directory.size)){
new_directory = directory;
result = true;
}
}
else{
new_directory = push_u8_stringf(scratch, "%.*s/%.*s",
string_expand(directory),
string_expand(relative_path));
if (file_exists(app, (char*)new_directory.str, (i32)new_directory.size)){
result = true;
}
}
}
if (result){
i32 new_len = clamp_top((i32)new_directory.size, capacity);
block_copy(dir, new_directory.str, new_len);
*len = new_len;
}
return(result);
}
static i32
get_4ed_path(Application_Links *app, char *out, i32 capacity){
Scratch_Block scratch(app);
String_Const_u8 string = push_4ed_path(app, scratch);
block_copy(out, string.str, clamp_top((i32)string.size, capacity));
return((i32)string.size);
}
static void
set_window_title(Application_Links *app, char *title){
String_Const_u8 title_string = SCu8(title);
set_window_title(app, title_string);
}
static Process_State
get_process_state(Application_Links *app, Buffer_ID buffer){
Process_State state = {};
Child_Process_ID child_process = buffer_get_attached_child_process(app, buffer);
if (child_process != 0){
state = child_process_get_state(app, child_process);
}
return(state);
}
#endif
// BOTTOM

View File

@ -1,134 +0,0 @@
/*
* Helpers for the API transition from 4.0.30 to 4.0.31
*
* In order to keep your layer on the old API you don't have to do anything, this provides wrappers
* idential to the 4.0.30 API.
* In order to transition your entire layer over to the 4.0.31 API define 'REMOVE_TRANSITION_HELPER_31' and fix errors.
* Or you can do it step by step by removing a few wrappers at a time.
* This transition helper will be removed in a future version so it is recommended to get off sooner or laster.
*
* Tips on transitioning:
*
* Wrather than just try to inline this code everywhere, you can simplify things quite a lot by storing references
* to buffers and views and Buffer_ID and View_ID instead of Buffer_Summary and View_Summary.
* Just get the summaries when you need information in those structures.
*
* You will make your code simpler if you stick to String as much as possible, but whenever you want to you can switch
* to any string type you have to String by calling make_string(char_ptr, length) or make_string_slowly(null_terminated_c_str).
* To pull the char ptr and length out of a String named "string": string.str and str.size.
* If you need a null terminated string from a String use get_null_terminated in 4coder_helper.cpp
*
*/
// TOP
#if !defined(REMOVE_TRANSITION_HELPER_31)
#define BatchEdit_PreserveTokens 0
#define BatchEdit_Normal 0
/* DOC(Buffer_Summary acts as a handle to a buffer and describes the state of the buffer.)
DOC_SEE(Access_Flag)
DOC_SEE(Dirty_State) */
STRUCT Buffer_Summary{
/* DOC(This field indicates whether the Buffer_Summary describes a buffer that is open in 4coder. When this field is false the summary is referred to as a "null summary".) */
b32 exists;
/* DOC(If this is not a null summary, this field indicates whether the buffer has finished loading.) */
b32 ready;
/* DOC(If this is not a null summary this field is the id of the associated buffer. If this is a null summary then buffer_id is 0.) */
Buffer_ID buffer_id;
/* DOC(If this is not a null summary, this field contains flags describing the protection status of the buffer.) */
Access_Flag lock_flags;
/* DOC(If this is not a null summary, this field specifies the number of bytes in the buffer.) */
i32 size;
/* DOC(If this is not a null summary, this field specifies the number of lines in the buffer.) */
i32 line_count;
/* DOC(If this is not a null summary, this field specifies the file name associated to this buffer.) */
char file_name[256];
/* DOC(This field specifies the length of the file_name string.) */
i32 file_name_len;
/* DOC(If this is not a null summary, this field specifies the name of the buffer.) */
char buffer_name[256];
/* DOC(This field specifies the length of the buffer_name string.) */
i32 buffer_name_len;
/* DOC(This field indicates the dirty state of the buffer.) */
Dirty_State dirty;
/* DOC(If this is not a null summary, this field indicates whether the buffer is set to lex tokens.) */
b32 is_lexed;
/* DOC(If this is not a null summary, this field indicates whether the buffer has up to date tokens available. If this field is false, it may simply mean the tokens are still being generated in a background task and will be available later. If that is the case, is_lexed will be true to indicate that the buffer is trying to get it's tokens up to date.) */
b32 tokens_are_ready;
/* DOC(If this is not a null summary, this field specifies the id of the command map for this buffer.) */
i32 map_id;
/* DOC(If this is not a null summary, this field indicates whether the buffer 'prefers' wrapped lines.) */
b32 unwrapped_lines;
};
/* DOC(View_Summary acts as a handle to a view and describes the state of the view.)
DOC_SEE(Access_Flag)
DOC_SEE(Full_Cursor)
DOC_SEE(GUI_Scroll_Vars) */
STRUCT View_Summary{
/* DOC(This field indicates whether the View_Summary describes a view that is open in 4coder. When this field is false the summary is referred to as a "null summary". ) */
b32 exists;
/* DOC(This field is the id of the associated view. If this is a null summary then view_id is 0. ) */
i32 view_id;
/* DOC(Then this is the id of the buffer this view currently sees.) */
i32 buffer_id;
/* DOC(This field contains flags describing the protection status of the view.) */
Access_Flag lock_flags;
/* DOC(This describes the position of the cursor.) */
Full_Cursor cursor;
/* DOC(This describes the position of the mark.) */
Full_Cursor mark;
/* DOC(This is the x position that is maintained in vertical navigation.) */
f32 preferred_x;
/* DOC(This specifies the height of a line rendered in the view.) */
f32 line_height;
/* DOC(This indicates that the view is set to render with unwrapped lines.) */
b32 unwrapped_lines;
/* DOC(This indicates that the view is set to highlight white space.) */
b32 show_whitespace;
/* DOC(This describes the screen position in which this view is displayed.) */
Rect_f32 view_region;
/* DOC(TODO) */
Rect_f32 render_region;
/* DOC(This describes the scrolling position inside the view.) */
GUI_Scroll_Vars scroll_vars;
};
/* DOC(A Seek_Boundary_Flag field specifies a set of "boundary" types used in seeks for the beginning or end of different types of words.) */
typedef u32 Seek_Boundary_Flag;
enum{
BoundaryWhitespace = 0x1,
BoundaryToken = 0x2,
BoundaryAlphanumeric = 0x4,
BoundaryCamelCase = 0x8
};
// NOTE(allen|4.0.31): Stream_Tokens has been deprecated in favor of the Token_Iterator.
// For examples of usage: 4coder_function_list.cpp 4coder_scope_commands.cpp
// If you want to keep your code working easily uncomment the typedef for Stream_Tokens.
struct Stream_Tokens_DEP{
Application_Links *app;
Buffer_ID buffer_id;
Cpp_Token *base_tokens;
Cpp_Token *tokens;
i32 start;
i32 end;
i32 count;
i32 token_count;
};
//typedef Stream_Tokens_DEP Stream_Tokens;
#endif
// BOTTOM

File diff suppressed because it is too large Load Diff

View File

@ -4,17 +4,14 @@
// TOP
internal Buffer_Batch_Edit
internal Batch_Edit*
make_batch_from_indent_marks(Application_Links *app, Arena *arena, Buffer_ID buffer,
i64 first_line, i64 one_past_last_line, i64 *indent_marks,
Indent_Options opts){
i64 *shifted_indent_marks = indent_marks - first_line;
i64 edit_count = 0;
i64 edit_max = one_past_last_line - first_line;
Buffer_Edit *edits = push_array(arena, Buffer_Edit, edit_max);
List_String_Const_u8 list = {};
Batch_Edit *batch_first = 0;
Batch_Edit *batch_last = 0;
for (i64 line_number = first_line;
line_number < one_past_last_line;
@ -32,50 +29,37 @@ make_batch_from_indent_marks(Application_Links *app, Arena *arena, Buffer_ID buf
if (correct_indentation != hard_start.indent_pos){
umem str_size = 0;
char *str = 0;
u8 *str = 0;
if (opts.use_tabs){
i64 tab_count = correct_indentation/opts.tab_width;
i64 indent = tab_count*opts.tab_width;
i64 space_count = correct_indentation - indent;
str_size = tab_count + space_count;
str = push_array(arena, char, str_size);
str = push_array(arena, u8, str_size);
block_fill_u8(str, tab_count, '\t');
block_fill_u8(str + tab_count, space_count, ' ');
}
else{
str_size = correct_indentation;
str = push_array(arena, char, str_size);
str = push_array(arena, u8, str_size);
block_fill_u8(str, str_size, ' ');
}
i64 str_position = list.total_size;
string_list_push(arena, &list, SCu8(str, str_size));
edits[edit_count].str_start = (i32)str_position;
edits[edit_count].len = (i32)str_size;
edits[edit_count].start = (i32)line_start_pos;
edits[edit_count].end = (i32)hard_start.first_char_pos;
edit_count += 1;
Batch_Edit *batch = push_array(arena, Batch_Edit, 1);
sll_queue_push(batch_first, batch_last, batch);
batch->edit.text = SCu8(str, str_size);
batch->edit.range = Ii64(line_start_pos, hard_start.first_char_pos);
}
}
Assert(edit_count <= edit_max);
}
String_Const_u8 contiguous_text = string_list_flatten(arena, list);
Buffer_Batch_Edit result = {};
result.str = (char*)contiguous_text.str;
result.str_len = (i32)contiguous_text.size;
result.edits = edits;
result.edit_count = (i32)edit_count;
return(result);
return(batch_first);
}
internal void
set_line_indents(Application_Links *app, Arena *arena, Buffer_ID buffer, i64 first_line, i64 one_past_last_line, i64 *indent_marks, Indent_Options opts){
Buffer_Batch_Edit batch = make_batch_from_indent_marks(app, arena, buffer, first_line, one_past_last_line, indent_marks, opts);
if (batch.edit_count > 0){
buffer_batch_edit(app, buffer, batch.str, batch.edits, batch.edit_count);
Batch_Edit *batch = make_batch_from_indent_marks(app, arena, buffer, first_line, one_past_last_line, indent_marks, opts);
if (batch != 0){
buffer_batch_edit(app, buffer, batch);
}
}

View File

@ -11,17 +11,10 @@ write_character_parameter(Application_Links *app, u8 *character, u32 length){
View_ID view = get_active_view(app, AccessOpen);
if_view_has_highlighted_range_delete_range(app, view);
Buffer_ID buffer = view_get_buffer(app, view, AccessOpen);
i64 pos = view_get_cursor_pos(app, view);
Full_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos));
pos = view_get_character_legal_pos_from_pos(app, view, pos);
// NOTE(allen): setup markers to figure out the new position of cursor after the insert
Marker next_cursor_marker = {};
// TODO(allen): should be using character_pos_to_pos_buffer here!
next_cursor_marker.pos = (i32)character_pos_to_pos_view(app, view, cursor.character_pos);
next_cursor_marker.lean_right = true;
Managed_Object handle = alloc_buffer_markers_on_buffer(app, buffer, 1, 0);
managed_object_store_data(app, handle, 0, 1, &next_cursor_marker);
Buffer_ID buffer = view_get_buffer(app, view, AccessOpen);
// NOTE(allen): consecutive inserts merge logic
History_Record_Index first_index = buffer_history_get_current_state_index(app, buffer);
@ -55,10 +48,8 @@ write_character_parameter(Application_Links *app, u8 *character, u32 length){
}
// NOTE(allen): finish updating the cursor
managed_object_load_data(app, handle, 0, 1, &next_cursor_marker);
managed_object_free(app, handle);
if (edit_success){
view_set_cursor(app, view, seek_pos(next_cursor_marker.pos), true);
view_set_cursor(app, view, seek_pos(pos + length), true);
}
}
}
@ -88,9 +79,9 @@ CUSTOM_DOC("Deletes the character to the right of the cursor.")
i64 start = view_get_cursor_pos(app, view);
i64 buffer_size = buffer_get_size(app, buffer);
if (0 <= start && start < buffer_size){
Full_Cursor cursor = view_compute_cursor(app, view, seek_pos(start));
cursor = view_compute_cursor(app, view, seek_character_pos(cursor.character_pos + 1));
i64 end = cursor.pos;
Buffer_Cursor cursor = view_compute_cursor(app, view, seek_pos(start));
i64 character = view_relative_character_from_pos(app, view, cursor.line, cursor.pos);
i64 end = view_pos_from_relative_character(app, view, cursor.line, character + 1);
buffer_replace_range(app, buffer, Ii64(start, end), string_u8_empty);
}
}
@ -105,9 +96,9 @@ CUSTOM_DOC("Deletes the character to the left of the cursor.")
i64 end = view_get_cursor_pos(app, view);
i64 buffer_size = buffer_get_size(app, buffer);
if (0 < end && end <= buffer_size){
Full_Cursor cursor = view_compute_cursor(app, view, seek_pos(end));
cursor = view_compute_cursor(app, view, seek_character_pos(cursor.character_pos - 1));
i64 start = cursor.pos;
Buffer_Cursor cursor = view_compute_cursor(app, view, seek_pos(end));
i64 character = view_relative_character_from_pos(app, view, cursor.line, cursor.pos);
i64 start = view_pos_from_relative_character(app, view, cursor.line, character - 1);
if (buffer_replace_range(app, buffer, Ii64(start, end), string_u8_empty)){
view_set_cursor(app, view, seek_pos(start), true);
}
@ -207,52 +198,37 @@ CUSTOM_COMMAND_SIG(center_view)
CUSTOM_DOC("Centers the view vertically on the line on which the cursor sits.")
{
View_ID view = get_active_view(app, AccessProtected);
Rect_f32 region = view_get_buffer_region(app, view);
GUI_Scroll_Vars scroll = view_get_scroll_vars(app, view);
f32 h = (f32)(rect_height(region));
f32 y = get_view_y(app, view);
y = y - h*.5f;
scroll.target_y = (i32)(y + .5f);
view_set_scroll(app, view, scroll);
i64 pos = view_get_cursor_pos(app, view);
Buffer_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos));
f32 view_height = rect_height(region);
Buffer_Scroll scroll = view_get_buffer_scroll(app, view);
scroll.target.line_number = cursor.line;
scroll.target.pixel_shift.y = -view_height*0.5f;
view_set_buffer_scroll(app, view, scroll);
}
CUSTOM_COMMAND_SIG(left_adjust_view)
CUSTOM_DOC("Sets the left size of the view near the x position of the cursor.")
{
View_ID view = get_active_view(app, AccessProtected);
GUI_Scroll_Vars scroll = view_get_scroll_vars(app, view);
f32 x = clamp_bot(0.f, get_view_x(app, view) - 30.f);
scroll.target_x = (i32)(x + .5f);
view_set_scroll(app, view, scroll);
}
static b32
view_space_from_screen_space_checked(Vec2_f32 p, Rect_f32 file_region, Vec2 scroll_p, Vec2 *p_out){
b32 result = false;
if (rect_contains_point(file_region, p)){
*p_out = view_space_from_screen_space(p, file_region.p0, scroll_p);
result = true;
}
else{
*p_out = V2(0.f, 0.f);
}
return(result);
i64 pos = view_get_cursor_pos(app, view);
Buffer_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos));
Vec2_f32 p = view_relative_xy_of_pos(app, view, cursor.line, pos);
Buffer_Scroll scroll = view_get_buffer_scroll(app, view);
scroll.target.pixel_shift.x = clamp_bot(0.f, p.x - 30.f);
view_set_buffer_scroll(app, view, scroll);
}
CUSTOM_COMMAND_SIG(click_set_cursor_and_mark)
CUSTOM_DOC("Sets the cursor position and mark to the mouse position.")
{
View_ID view = get_active_view(app, AccessProtected);
Rect_f32 region = view_get_buffer_region(app, view);
GUI_Scroll_Vars scroll_vars = view_get_scroll_vars(app, view);
if (!view_is_in_ui_mode(app, view)){
Mouse_State mouse = get_mouse_state(app);
Vec2 p = {};
if (view_space_from_screen_space_checked(V2(mouse.p), region, scroll_vars.scroll_p, &p)){
Full_Cursor cursor = view_compute_cursor(app, view, seek_wrapped_xy(p.x, p.y, true));
view_set_cursor(app, view, seek_pos(cursor.pos), true);
view_set_mark(app, view, seek_pos(cursor.pos));
i64 pos = view_pos_from_xy(app, view, V2(mouse.p));
view_set_cursor(app, view, seek_pos(pos), true);
view_set_mark(app, view, seek_pos(pos));
}
}
@ -260,44 +236,38 @@ CUSTOM_COMMAND_SIG(click_set_cursor)
CUSTOM_DOC("Sets the cursor position to the mouse position.")
{
View_ID view = get_active_view(app, AccessProtected);
Rect_f32 region = view_get_buffer_region(app, view);
GUI_Scroll_Vars scroll_vars = view_get_scroll_vars(app, view);
if (!view_is_in_ui_mode(app, view)){
Mouse_State mouse = get_mouse_state(app);
Vec2 p = {};
if (view_space_from_screen_space_checked(V2(mouse.p), region, scroll_vars.scroll_p, &p)){
view_set_cursor(app, view, seek_wrapped_xy(p.x, p.y, true), true);
}
i64 pos = view_pos_from_xy(app, view, V2(mouse.p));
view_set_cursor(app, view, seek_pos(pos), true);
no_mark_snap_to_cursor(app, view);
}
}
CUSTOM_COMMAND_SIG(click_set_cursor_if_lbutton)
CUSTOM_DOC("If the mouse left button is pressed, sets the cursor position to the mouse position.")
{
View_ID view = get_active_view(app, AccessProtected);
if (!view_is_in_ui_mode(app, view)){
Mouse_State mouse = get_mouse_state(app);
if (mouse.l){
Rect_f32 region = view_get_buffer_region(app, view);
GUI_Scroll_Vars scroll_vars = view_get_scroll_vars(app, view);
Vec2 p = {};
if (view_space_from_screen_space_checked(V2(mouse.p), region, scroll_vars.scroll_p, &p)){
view_set_cursor(app, view, seek_wrapped_xy(p.x, p.y, true), true);
}
i64 pos = view_pos_from_xy(app, view, V2(mouse.p));
view_set_cursor(app, view, seek_pos(pos), true);
}
no_mark_snap_to_cursor(app, view);
}
}
CUSTOM_COMMAND_SIG(click_set_mark)
CUSTOM_DOC("Sets the mark position to the mouse position.")
{
View_ID view = get_active_view(app, AccessProtected);
Rect_f32 region = view_get_buffer_region(app, view);
GUI_Scroll_Vars scroll_vars = view_get_scroll_vars(app, view);
if (!view_is_in_ui_mode(app, view)){
Mouse_State mouse = get_mouse_state(app);
Vec2 p = {};
if (view_space_from_screen_space_checked(V2(mouse.p), region, scroll_vars.scroll_p, &p)){
view_set_mark(app, view, seek_wrapped_xy(p.x, p.y, true));
}
i64 pos = view_pos_from_xy(app, view, V2(mouse.p));
view_set_mark(app, view, seek_pos(pos));
no_mark_snap_to_cursor(app, view);
}
}
CUSTOM_COMMAND_SIG(mouse_wheel_scroll)
@ -306,9 +276,16 @@ CUSTOM_DOC("Reads the scroll wheel value from the mouse state and scrolls accord
View_ID view = get_active_view(app, AccessProtected);
Mouse_State mouse = get_mouse_state(app);
if (mouse.wheel != 0){
GUI_Scroll_Vars scroll = view_get_scroll_vars(app, view);
scroll.target_y += mouse.wheel;
view_set_scroll(app, view, scroll);
if (view_is_in_ui_mode(app, view)){
Basic_Scroll scroll = view_get_basic_scroll(app, view);
scroll.target.y += mouse.wheel;
view_set_basic_scroll(app, view, scroll);
}
else{
Buffer_Scroll scroll = view_get_buffer_scroll(app, view);
scroll.target = view_move_buffer_point(app, view, scroll.target, V2f32(0.f, (f32)mouse.wheel));
view_set_buffer_scroll(app, view, scroll);
}
}
}
@ -316,24 +293,12 @@ CUSTOM_DOC("Reads the scroll wheel value from the mouse state and scrolls accord
internal void
move_vertical_pixels(Application_Links *app, View_ID view, f32 pixels){
f32 new_y = get_view_y(app, view) + pixels;
f32 x = view_get_preferred_x(app, view);
view_set_cursor(app, view, seek_wrapped_xy(x, new_y, false), false);
f32 actual_new_y = get_view_y(app, view);
if (actual_new_y < new_y){
Rect_f32 file_region = view_get_buffer_region(app, view);
f32 height = rect_height(file_region);
f32 full_scroll_y = actual_new_y - height*0.5f;
GUI_Scroll_Vars scroll_vars = view_get_scroll_vars(app, view);
if (scroll_vars.target_y < full_scroll_y){
GUI_Scroll_Vars new_scroll_vars = scroll_vars;
new_scroll_vars.target_y += (i32)pixels;
new_scroll_vars.target_y = clamp_top(new_scroll_vars.target_y, (i32)full_scroll_y);
view_set_scroll(app, view, new_scroll_vars);
}
}
i64 pos = view_get_cursor_pos(app, view);
Buffer_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos));
Vec2_f32 p = view_relative_xy_of_pos(app, view, cursor.line, pos);
p.y += pixels;
i64 new_pos = view_pos_at_relative_xy(app, view, cursor.line, p);
view_set_cursor(app, view, seek_pos(new_pos), false);
no_mark_snap_to_cursor_if_shift(app, view);
}
@ -396,9 +361,9 @@ CUSTOM_DOC("Moves down to the next line of actual text, regardless of line wrapp
{
View_ID view = get_active_view(app, AccessOpen);
i64 pos = view_get_cursor_pos(app, view);
Full_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos));
Buffer_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos));
i64 next_line = cursor.line + 1;
view_set_cursor(app, view, seek_line_char(next_line, 1), true);
view_set_cursor(app, view, seek_line_col(next_line, 1), true);
}
CUSTOM_COMMAND_SIG(page_up)
@ -484,9 +449,10 @@ CUSTOM_DOC("Moves the cursor one character to the left.")
{
View_ID view = get_active_view(app, AccessProtected);
i64 pos = view_get_cursor_pos(app, view);
Full_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos));
i64 new_pos = clamp_bot(0, cursor.character_pos - 1);
view_set_cursor(app, view, seek_character_pos(new_pos), true);
Buffer_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos));
i64 character = view_relative_character_from_pos(app, view, cursor.line, pos);
i64 new_pos = view_pos_from_relative_character(app, view, cursor.line, character - 1);
view_set_cursor(app, view, seek_pos(new_pos), true);
no_mark_snap_to_cursor_if_shift(app, view);
}
@ -495,9 +461,10 @@ CUSTOM_DOC("Moves the cursor one character to the right.")
{
View_ID view = get_active_view(app, AccessProtected);
i64 pos = view_get_cursor_pos(app, view);
Full_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos));
i64 new_pos = cursor.character_pos + 1;
view_set_cursor(app, view, seek_character_pos(new_pos), 1);
Buffer_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos));
i64 character = view_relative_character_from_pos(app, view, cursor.line, pos);
i64 new_pos = view_pos_from_relative_character(app, view, cursor.line, character + 1);
view_set_cursor(app, view, seek_pos(new_pos), true);
no_mark_snap_to_cursor_if_shift(app, view);
}
@ -649,11 +616,9 @@ CUSTOM_DOC("Removes trailing whitespace from all lines in the current buffer.")
View_ID view = get_active_view(app, AccessOpen);
Buffer_ID buffer = view_get_buffer(app, view, AccessOpen);
i32 line_count = (i32)buffer_get_line_count(app, buffer);
Scratch_Block scratch(app);
Buffer_Edit *edits = push_array(scratch, Buffer_Edit, line_count);
Buffer_Edit *edit = edits;
Batch_Edit *batch_first = 0;
Batch_Edit *batch_last = 0;
String_Const_u8 text = push_whole_buffer(app, scratch, buffer);
@ -662,11 +627,10 @@ CUSTOM_DOC("Removes trailing whitespace from all lines in the current buffer.")
u8 v = string_get_character(text, i);
if (v == '\n' || i + 1 == text.size){
if (whitespace_start < i){
edit->str_start = 0;
edit->len = 0;
edit->start = (i32)whitespace_start;
edit->end = (i32)i;
++edit;
Batch_Edit *batch = push_array(scratch, Batch_Edit, 1);
sll_queue_push(batch_first, batch_last, batch);
batch->edit.text = SCu8();
batch->edit.range = Ii64(whitespace_start, i);
}
whitespace_start = i + 1;
}
@ -675,8 +639,7 @@ CUSTOM_DOC("Removes trailing whitespace from all lines in the current buffer.")
}
}
i32 edit_count = (i32)(edit - edits);
buffer_batch_edit(app, buffer, 0, edits, edit_count);
buffer_batch_edit(app, buffer, batch_first);
}
////////////////////////////////
@ -870,7 +833,7 @@ CUSTOM_DOC("Queries the user for a number, and jumps the cursor to the correspon
if (query_user_number(app, &bar)){
i32 line_number = (i32)string_to_integer(bar.string, 10);
View_ID view = get_active_view(app, AccessProtected);
view_set_cursor(app, view, seek_line_char(line_number, 0), true);
view_set_cursor(app, view, seek_line_col(line_number, 0), true);
}
}
@ -1647,7 +1610,9 @@ CUSTOM_DOC("Set the other non-active panel to view the buffer that the active pa
change_active_panel(app);
View_ID view2 = get_active_view(app, AccessAll);
if (view1 != view2){
if (view1 != view2 &&
!view_is_in_ui_mode(app, view1) &&
!view_is_in_ui_mode(app, view2)){
Buffer_ID buffer1 = view_get_buffer(app, view1, AccessAll);
Buffer_ID buffer2 = view_get_buffer(app, view2, AccessAll);
if (buffer1 != buffer2){
@ -1657,17 +1622,17 @@ CUSTOM_DOC("Set the other non-active panel to view the buffer that the active pa
else{
i64 p1 = view_get_cursor_pos(app, view1);
i64 m1 = view_get_mark_pos(app, view1);
GUI_Scroll_Vars sc1 = view_get_scroll_vars(app, view1);
Buffer_Scroll sc1 = view_get_buffer_scroll(app, view1);
i64 p2 = view_get_cursor_pos(app, view2);
i64 m2 = view_get_mark_pos(app, view2);
GUI_Scroll_Vars sc2 = view_get_scroll_vars(app, view2);
Buffer_Scroll sc2 = view_get_buffer_scroll(app, view2);
view_set_cursor(app, view1, seek_pos(p2), true);
view_set_mark (app, view1, seek_pos(m2));
view_set_scroll(app, view1, sc2);
view_set_buffer_scroll(app, view1, sc2);
view_set_cursor(app, view2, seek_pos(p1), true);
view_set_mark (app, view2, seek_pos(m1));
view_set_scroll(app, view2, sc1);
view_set_buffer_scroll(app, view2, sc1);
}
}
}

View File

@ -274,6 +274,7 @@ block_fill_u64(void *a, umem size, u64 val){
#define block_zero_struct(p) block_zero((p), sizeof(*(p)))
#define block_zero_array(a) block_zero((a), sizeof(a))
#define block_zero_dynamic_array(p,c) block_zero((p), sizeof(*(p))*(c))
#define block_copy_struct(d,s) block_copy((d), (s), sizeof(*(d)))
#define block_copy_array(d,s) block_copy((d), (s), sizeof(d))
@ -1428,6 +1429,40 @@ operator!=(Vec4_f32 a, Vec4_f32 b){
////////////////////////////////
static b32
near_zero(f32 p, f32 epsilon){
return(-epsilon <= p && p <= epsilon);
}
static b32
near_zero(Vec2_f32 p, f32 epsilon){
return(-epsilon <= p.x && p.x <= epsilon &&
-epsilon <= p.y && p.y <= epsilon);
}
static b32
near_zero(Vec3_f32 p, f32 epsilon){
return(-epsilon <= p.x && p.x <= epsilon &&
-epsilon <= p.y && p.y <= epsilon &&
-epsilon <= p.z && p.z <= epsilon);
}
static b32
near_zero(Vec4_f32 p, f32 epsilon){
return(-epsilon <= p.x && p.x <= epsilon &&
-epsilon <= p.y && p.y <= epsilon &&
-epsilon <= p.z && p.z <= epsilon &&
-epsilon <= p.w && p.w <= epsilon);
}
static b32
near_zero(f32 p){ return(near_zero(p, epsilon_f32)); }
static b32
near_zero(Vec2_f32 p){ return(near_zero(p, epsilon_f32)); }
static b32
near_zero(Vec3_f32 p){ return(near_zero(p, epsilon_f32)); }
static b32
near_zero(Vec4_f32 p){ return(near_zero(p, epsilon_f32)); }
////////////////////////////////
static b32
operator==(Rect_i32 a, Rect_i32 b){
return(a.p0 == b.p0 && a.p1 == b.p1);
@ -1718,6 +1753,23 @@ range_overlap(Interval_f32 a, Interval_f32 b){
return(a.min < b.max && b.min < a.max);
}
internal b32
range_contains_inclusive(Interval_i32 a, i32 p){
return(a.min <= p && p <= a.max);
}
internal b32
range_contains_inclusive(Interval_i64 a, i64 p){
return(a.min <= p && p <= a.max);
}
internal b32
range_contains_inclusive(Interval_u64 a, u64 p){
return(a.min <= p && p <= a.max);
}
internal b32
range_inclusive_contains(Interval_f32 a, f32 p){
return(a.min <= p && p <= a.max);
}
internal b32
range_contains(Interval_i32 a, i32 p){
return(a.min <= p && p < a.max);
@ -1760,6 +1812,31 @@ range_size(Interval_f32 a){
return(size);
}
internal i32
range_size_inclusive(Interval_i32 a){
i32 size = a.max - a.min + 1;
size = clamp_bot(0, size);
return(size);
}
internal i64
range_size_inclusive(Interval_i64 a){
i64 size = a.max - a.min + 1;
size = clamp_bot(0, size);
return(size);
}
internal u64
range_size_inclusive(Interval_u64 a){
u64 size = a.max - a.min + 1;
size = clamp_bot(0, size);
return(size);
}
internal f32
range_size_inclusive(Interval_f32 a){
f32 size = a.max - a.min + 1;
size = clamp_bot(0, size);
return(size);
}
internal Interval_i32
rectify(Interval_i32 a){
return(Ii32(a.min, a.max));
@ -1892,39 +1969,39 @@ range_distance(Interval_f32 a, Interval_f32 b){
////////////////////////////////
internal i32
replace_range_compute_shift(i32 replace_length, i32 insert_length){
replace_range_shift(i32 replace_length, i32 insert_length){
return(insert_length - replace_length);
}
internal i32
replace_range_compute_shift(i32 start, i32 end, i32 insert_length){
replace_range_shift(i32 start, i32 end, i32 insert_length){
return(insert_length - (end - start));
}
internal i32
replace_range_compute_shift(Interval_i32 range, i32 insert_length){
replace_range_shift(Interval_i32 range, i32 insert_length){
return(insert_length - (range.end - range.start));
}
internal i64
replace_range_compute_shift(i64 replace_length, i64 insert_length){
replace_range_shift(i64 replace_length, i64 insert_length){
return(insert_length - replace_length);
}
internal i64
replace_range_compute_shift(i64 start, i64 end, i64 insert_length){
replace_range_shift(i64 start, i64 end, i64 insert_length){
return(insert_length - (end - start));
}
internal i64
replace_range_compute_shift(Interval_i64 range, i64 insert_length){
replace_range_shift(Interval_i64 range, i64 insert_length){
return(insert_length - (range.end - range.start));
}
internal i64
replace_range_compute_shift(u64 replace_length, u64 insert_length){
replace_range_shift(u64 replace_length, u64 insert_length){
return((i64)insert_length - replace_length);
}
internal i64
replace_range_compute_shift(i64 start, i64 end, u64 insert_length){
replace_range_shift(i64 start, i64 end, u64 insert_length){
return((i64)insert_length - (end - start));
}
internal i64
replace_range_compute_shift(Interval_i64 range, u64 insert_length){
replace_range_shift(Interval_i64 range, u64 insert_length){
return((i64)insert_length - (range.end - range.start));
}
@ -1991,6 +2068,9 @@ Rf32_xy_wh(Vec2_f32 p0, Vec2_f32 d){
#define i32R_xy_wh
#define f32R_xy_wh
global_const Rect_f32 Rf32_infinity = {-max_f32, -max_f32, max_f32, max_f32};
global_const Rect_f32 Rf32_negative_infinity = { max_f32, max_f32, -max_f32, -max_f32};
internal b32
rect_equals(Rect_i32 a, Rect_i32 b){
return(a.x0 == b.x0 && a.y0 == b.y0 && a.x1 == b.x1 && a.y1 == b.y1);
@ -2053,6 +2133,15 @@ rect_height(Rect_f32 r){
return(r.y1 - r.y0);
}
internal Vec2_i32
rect_center(Rect_i32 r){
return((r.p0 + r.p1)/2);
}
internal Vec2_f32
rect_center(Rect_f32 r){
return((r.p0 + r.p1)*0.5f);
}
internal Interval_i32
rect_range_x(Rect_i32 r){
return(Ii32(r.x0, r.x1));
@ -2082,16 +2171,14 @@ rect_overlap(Rect_f32 a, Rect_f32 b){
}
internal Vec2_i32
rect_center(Rect_i32 r){
rect_half_dim(Rect_i32 r){
return(rect_dim(r)/2);
}
internal Vec2_f32
rect_center(Rect_f32 r){
return(rect_dim(r)/2);
rect_half_dim(Rect_f32 r){
return(rect_dim(r)*0.5f);
}
#define center_of rect_center
internal Rect_i32
rect_intersect(Rect_i32 a, Rect_i32 b){
a.x0 = Max(a.x0, b.x0);
@ -2221,7 +2308,9 @@ base_allocate(Base_Allocator *allocator, umem size){
}
static void
base_free(Base_Allocator *allocator, void *ptr){
if (ptr != 0){
allocator->free(allocator->user_data, ptr);
}
}
////////////////////////////////
@ -5355,6 +5444,59 @@ string_wildcard_match_insensitive(List_String_Const_u8 list, String_Const_u8 str
return(string_wildcard_match(list, string, StringMatch_CaseInsensitive));
}
static void
string_list_reverse(List_String_Const_char *list){
Node_String_Const_char *first = 0;
Node_String_Const_char *last = list->first;
for (Node_String_Const_char *node = list->first, *next = 0;
node != 0;
node = next){
next = node->next;
sll_stack_push(first, node);
}
list->first = first;
list->last = last;
}
static void
string_list_reverse(List_String_Const_u8 *list){
Node_String_Const_u8 *first = 0;
Node_String_Const_u8 *last = list->first;
for (Node_String_Const_u8 *node = list->first, *next = 0;
node != 0;
node = next){
next = node->next;
sll_stack_push(first, node);
}
list->first = first;
list->last = last;
}
static void
string_list_reverse(List_String_Const_u16 *list){
Node_String_Const_u16 *first = 0;
Node_String_Const_u16 *last = list->first;
for (Node_String_Const_u16 *node = list->first, *next = 0;
node != 0;
node = next){
next = node->next;
sll_stack_push(first, node);
}
list->first = first;
list->last = last;
}
static void
string_list_reverse(List_String_Const_u32 *list){
Node_String_Const_u32 *first = 0;
Node_String_Const_u32 *last = list->first;
for (Node_String_Const_u32 *node = list->first, *next = 0;
node != 0;
node = next){
next = node->next;
sll_stack_push(first, node);
}
list->first = first;
list->last = last;
}
////////////////////////////////
global_const u8 utf8_class[32] = {

View File

@ -13,49 +13,11 @@ seek_pos(i64 pos){
}
static Buffer_Seek
seek_character_pos(i64 pos){
seek_line_col(i64 line, i64 col){
Buffer_Seek result;
result.type = buffer_seek_character_pos;
result.pos = pos;
return(result);
}
static Buffer_Seek
seek_wrapped_xy(f32 x, f32 y, b32 round_down){
Buffer_Seek result;
result.type = buffer_seek_wrapped_xy;
result.x = x;
result.y = y;
result.round_down = round_down;
return(result);
}
static Buffer_Seek
seek_unwrapped_xy(f32 x, f32 y, b32 round_down){
Buffer_Seek result;
result.type = buffer_seek_unwrapped_xy;
result.x = x;
result.y = y;
result.round_down = round_down;
return(result);
}
static Buffer_Seek
seek_xy(f32 x, f32 y, b32 round_down, b32 unwrapped){
Buffer_Seek result;
result.type = unwrapped?buffer_seek_unwrapped_xy:buffer_seek_wrapped_xy;
result.x = x;
result.y = y;
result.round_down = round_down;
return(result);
}
static Buffer_Seek
seek_line_char(i64 line, i64 character){
Buffer_Seek result;
result.type = buffer_seek_line_char;
result.type = buffer_seek_line_col;
result.line = line;
result.character = character;
result.col = col;
return(result);
}

View File

@ -13,7 +13,7 @@ CUSTOM_COMMAND_SIG(set_bindings_choose);
CUSTOM_COMMAND_SIG(set_bindings_default);
CUSTOM_COMMAND_SIG(set_bindings_mac_default);
static Named_Mapping named_maps_values[] = {
global Named_Mapping named_maps_values[] = {
{string_u8_litexpr("mac-default") , set_bindings_mac_default },
{string_u8_litexpr("choose") , set_bindings_choose },
{string_u8_litexpr("default") , set_bindings_default },
@ -119,7 +119,7 @@ struct Highlight_Record{
int_color color;
};
static void
internal void
sort_highlight_record(Highlight_Record *records, i32 first, i32 one_past_last){
if (first + 1 < one_past_last){
i32 pivot_index = one_past_last - 1;
@ -140,7 +140,7 @@ sort_highlight_record(Highlight_Record *records, i32 first, i32 one_past_last){
}
}
static Range_i64_Array
internal Range_i64_Array
get_enclosure_ranges(Application_Links *app, Arena *arena, Buffer_ID buffer, i64 pos, u32 flags){
Range_i64_Array array = {};
i32 max = 100;
@ -168,7 +168,7 @@ enum{
RangeHighlightKind_CharacterHighlight,
};
static void
internal void
draw_enclosures(Application_Links *app, Text_Layout_ID text_layout_id, Buffer_ID buffer,
i64 pos, u32 flags, Range_Highlight_Kind kind,
int_color *back_colors, int_color *fore_colors, i32 color_count){
@ -327,27 +327,7 @@ GET_VIEW_BUFFER_REGION_SIG(default_view_buffer_region){
return(sub_region);
}
static Buffer_Point
buffer_position_from_scroll_position(Application_Links *app, View_ID view_id, Vec2 scroll){
Full_Cursor cursor = view_compute_cursor(app, view_id, seek_wrapped_xy(0.f, scroll.y, false));
cursor = view_compute_cursor(app, view_id, seek_line_char(cursor.line, 1));
Buffer_Point result = {};
result.line_number = cursor.line;
result.pixel_shift.x = scroll.x;
result.pixel_shift.y = scroll.y - cursor.wrapped_y;
return(result);
}
static i64
abs_position_from_buffer_point(Application_Links *app, View_ID view_id, Buffer_Point buffer_point){
Full_Cursor cursor = view_compute_cursor(app, view_id, seek_line_char(buffer_point.line_number, 0));
Buffer_Seek seek = seek_wrapped_xy(buffer_point.pixel_shift.x,
buffer_point.pixel_shift.y + cursor.wrapped_y, false);
cursor = view_compute_cursor(app, view_id, seek);
return(cursor.pos);
}
static void
internal void
default_buffer_render_caller(Application_Links *app, Frame_Info frame_info, View_ID view_id, Rect_f32 view_inner_rect){
Buffer_ID buffer = view_get_buffer(app, view_id, AccessAll);
@ -362,11 +342,10 @@ default_buffer_render_caller(Application_Links *app, Frame_Info frame_info, View
V2(view_inner_rect.p0 + sub_region.p1));
buffer_rect = rect_intersect(buffer_rect, view_inner_rect);
GUI_Scroll_Vars scroll = view_get_scroll_vars(app, view_id);
Buffer_Point buffer_point = buffer_position_from_scroll_position(app, view_id, scroll.scroll_p);
Text_Layout_ID text_layout_id = compute_render_layout(app, view_id, buffer, buffer_rect.p0, rect_dim(buffer_rect), buffer_point, max_i32);
Range_i64 on_screen_range = text_layout_get_on_screen_range(app, text_layout_id);
Buffer_Scroll scroll = view_get_buffer_scroll(app, view_id);
Buffer_Point buffer_point = scroll.position;
Text_Layout_ID text_layout_id = text_layout_create(app, buffer, buffer_rect, buffer_point);
Interval_i64 visible_range = text_layout_get_visible_range(app, text_layout_id);
View_ID active_view = get_active_view(app, AccessAll);
b32 is_active_view = (active_view == view_id);
@ -376,7 +355,7 @@ default_buffer_render_caller(Application_Links *app, Frame_Info frame_info, View
// NOTE(allen): Scan for TODOs and NOTEs
{
Temp_Memory temp = begin_temp(scratch);
String_Const_u8 tail = push_buffer_range(app, scratch, buffer, on_screen_range);
String_Const_u8 tail = push_buffer_range(app, scratch, buffer, visible_range);
Highlight_Record *record_first = 0;
Highlight_Record *record_last = 0;
@ -388,7 +367,7 @@ default_buffer_render_caller(Application_Links *app, Frame_Info frame_info, View
Highlight_Record *record = push_array(scratch, Highlight_Record, 1);
sll_queue_push(record_first, record_last, record);
record_count += 1;
record->range.first = on_screen_range.first + index;
record->range.first = visible_range.first + index;
record->range.one_past_last = record->range.first + 4;
record->color = Stag_Text_Cycle_2;
tail = string_skip(tail, 3);
@ -398,7 +377,7 @@ default_buffer_render_caller(Application_Links *app, Frame_Info frame_info, View
Highlight_Record *record = push_array(scratch, Highlight_Record, 1);
sll_queue_push(record_first, record_last, record);
record_count += 1;
record->range.first = on_screen_range.first + index;
record->range.first = visible_range.first + index;
record->range.one_past_last = record->range.first + 4;
record->color = Stag_Text_Cycle_1;
tail = string_skip(tail, 3);
@ -537,7 +516,7 @@ default_buffer_render_caller(Application_Links *app, Frame_Info frame_info, View
}
draw_clip_push(app, buffer_rect);
draw_render_layout(app, view_id);
draw_text_layout(app, text_layout_id);
text_layout_free(app, text_layout_id);
draw_clip_pop(app);
@ -622,12 +601,12 @@ default_buffer_render_caller(Application_Links *app, Frame_Info frame_info, View
Temp_Memory temp = begin_temp(scratch);
i64 cursor_position = view_get_cursor_pos(app, view_id);
Full_Cursor cursor = view_compute_cursor(app, view_id, seek_pos(cursor_position));
Buffer_Cursor cursor = view_compute_cursor(app, view_id, seek_pos(cursor_position));
Fancy_String_List list = {};
String_Const_u8 unique_name = push_buffer_unique_name(app, scratch, buffer);
push_fancy_string(scratch, &list, base_color, unique_name);
push_fancy_stringf(scratch, &list, base_color, " - Row: %3.lld Col: %3.lld -", cursor.line, cursor.character);
push_fancy_stringf(scratch, &list, base_color, " - Row: %3.lld Col: %3.lld -", cursor.line, cursor.col);
b32 is_dos_mode = false;
if (buffer_get_setting(app, buffer, BufferSetting_Eol, &is_dos_mode)){
@ -715,18 +694,16 @@ default_buffer_render_caller(Application_Links *app, Frame_Info frame_info, View
Fancy_Color line_color = fancy_id(Stag_Line_Numbers_Text);
Full_Cursor cursor = view_compute_cursor(app, view_id, seek_pos(on_screen_range.first));
GUI_Scroll_Vars scroll_vars = view_get_scroll_vars(app, view_id);
for (;cursor.pos <= on_screen_range.one_past_last;){
Vec2 p = panel_space_from_view_space(cursor.wrapped_p, scroll_vars.scroll_p);
p.y += left_margin.y0;
p.x = left_margin.x0;
Buffer_Cursor cursor = view_compute_cursor(app, view_id, seek_pos(visible_range.first));
for (;cursor.pos <= visible_range.one_past_last;){
Rect_f32 line_rect = text_layout_line_on_screen(app, text_layout_id, cursor.line);
Vec2_f32 p = V2f32(left_margin.x1, line_rect.y0);
Temp_Memory temp = begin_temp(scratch);
Fancy_String *line_string = push_fancy_stringf(scratch, line_color, "%*lld", line_count_digit_count, cursor.line);
draw_fancy_string(app, face_id, line_string, p, Stag_Margin_Active, 0);
end_temp(temp);
i64 next_line = cursor.line + 1;
cursor = view_compute_cursor(app, view_id, seek_line_char(next_line, 1));
cursor = view_compute_cursor(app, view_id, seek_line_col(next_line, 1));
if (cursor.line < next_line){
break;
}
@ -736,12 +713,12 @@ default_buffer_render_caller(Application_Links *app, Frame_Info frame_info, View
}
}
static void
internal void
default_ui_render_caller(Application_Links *app, View_ID view_id, Rect_f32 rect_f32, Face_ID face_id){
UI_Data *ui_data = 0;
Arena *ui_arena = 0;
if (view_get_ui_data(app, view_id, ViewGetUIFlag_KeepDataAsIs, &ui_data, &ui_arena)){
GUI_Scroll_Vars ui_scroll = view_get_scroll_vars(app, view_id);
Basic_Scroll scroll = view_get_basic_scroll(app, view_id);
for (UI_Item *item = ui_data->list.first;
item != 0;
@ -751,8 +728,8 @@ default_ui_render_caller(Application_Links *app, View_ID view_id, Rect_f32 rect_
switch (item->coordinates){
case UICoordinates_ViewSpace:
{
item_rect.p0 -= ui_scroll.scroll_p;
item_rect.p1 -= ui_scroll.scroll_p;
item_rect.p0 -= scroll.position;
item_rect.p1 -= scroll.position;
}break;
case UICoordinates_PanelSpace:
{}break;
@ -778,20 +755,20 @@ default_ui_render_caller(Application_Links *app, View_ID view_id, Rect_f32 rect_
}
}
}
static void
internal void
default_ui_render_caller(Application_Links *app, View_ID view_id, Rect_f32 rect_f32){
Buffer_ID buffer = view_get_buffer(app, view_id, AccessAll);
Face_ID face_id = get_face_id(app, buffer);
default_ui_render_caller(app, view_id, rect_f32, face_id);
}
static void
internal void
default_ui_render_caller(Application_Links *app, View_ID view_id, Face_ID face_id){
Rect_f32 rect = view_get_screen_rect(app, view_id);
rect.p1 -= rect.p0;
rect.p0 = V2(0.f,0.f);
default_ui_render_caller(app, view_id, rect, face_id);
}
static void
internal void
default_ui_render_caller(Application_Links *app, View_ID view){
Rect_f32 rect = view_get_screen_rect(app, view);
rect.p1 -= rect.p0;
@ -801,7 +778,7 @@ default_ui_render_caller(Application_Links *app, View_ID view){
default_ui_render_caller(app, view, rect, face_id);
}
static void
internal void
default_render_view(Application_Links *app, Frame_Info frame_info, View_ID view, b32 is_active){
Rect_f32 view_rect = view_get_screen_rect(app, view);
Rect_f32 inner = rect_inner(view_rect, 3);
@ -1244,57 +1221,54 @@ INPUT_FILTER_SIG(default_suppress_mouse_filter){
// 4coder scrolling behavior.
//
Vec2 scroll_velocity_[16] = {};
Vec2 *scroll_velocity = scroll_velocity_ - 1;
Vec2_f32 scroll_velocity_[16] = {};
Vec2_f32 *scroll_velocity = scroll_velocity_ - 1;
static i32
smooth_camera_step(f32 target, f32 *current, f32 *vel, f32 S, f32 T){
i32 result = 0;
f32 curr = *current;
f32 v = *vel;
if (curr != target){
if (curr > target - .1f && curr < target + .1f){
curr = target;
v = 1.f;
struct Smooth_Step{
f32 p;
f32 v;
};
internal Smooth_Step
smooth_camera_step(f32 target, f32 v, f32 S, f32 T){
Smooth_Step step = {};
step.v = v;
if (step.p != target){
if (step.p > target - .1f && step.p < target + .1f){
step.p = target;
step.v = 1.f;
}
else{
f32 L = curr + T*(target - curr);
i32 sign = (target > curr) - (target < curr);
f32 V = curr + sign*v;
if (sign > 0) curr = (L<V)?(L):(V);
else curr = (L>V)?(L):(V);
if (curr == V){
v *= S;
f32 L = step.p + T*(target - step.p);
i32 sign = (target > step.p) - (target < step.p);
f32 V = step.p + sign*step.v;
if (sign > 0){
step.p = (L<V)?(L):(V);
}
else{
step.p = (L>V)?(L):(V);
}
if (step.p == V){
step.v *= S;
}
}
*current = curr;
*vel = v;
result = 1;
}
return(result);
return(step);
}
SCROLL_RULE_SIG(smooth_scroll_rule){
Vec2 *velocity = scroll_velocity + view_id;
i32 result = 0;
DELTA_RULE_SIG(smooth_scroll_rule){
Vec2_f32 *velocity = scroll_velocity + view_id;
if (velocity->x == 0.f){
velocity->x = 1.f;
velocity->y = 1.f;
}
if (smooth_camera_step(target_y, scroll_y, &velocity->y, 80.f, 1.f/2.f)){
result = 1;
}
if (smooth_camera_step(target_x, scroll_x, &velocity->x, 80.f, 1.f/2.f)){
result = 1;
}
return(result);
Smooth_Step step_x = smooth_camera_step(pending_delta.x, velocity->x, 80.f, 1.f/2.f);
Smooth_Step step_y = smooth_camera_step(pending_delta.y, velocity->y, 80.f, 1.f/2.f);
*velocity = V2f32(step_x.v, step_y.v);
return(V2f32(step_x.p, step_y.p));
}
static void
internal void
set_all_default_hooks(Bind_Helper *context){
set_hook(context, hook_exit, default_exit);
set_hook(context, hook_buffer_viewer_update, default_view_adjust);

View File

@ -7,16 +7,6 @@
#if !defined(FCODER_DEFAULT_INCLUDE_CPP)
#define FCODER_DEFAULT_INCLUDE_CPP
// NOTE(allen): Defines before 4coder_default_include.cpp:
// REMOVE_TRANSITION_HELPER_31 -> does not include the transition helpers for the API changes in 4.0.31
// REMOVE_OLD_STRING -> does not include the old 4coder_string.h library.
// NOTE: You can only remove "old string" if you first remove the transition helper.
#if 0
#define REMOVE_TRANSITION_HELPER_31
#define REMOVE_OLD_STRING
#endif
#include "4coder_API/4coder_custom.h"
#include "4coder_generated/command_metadata.h"
@ -34,8 +24,6 @@
#include "4coder_table.h"
#include "4coder_string_match.h"
#include "4coder_api_transition_30_31.h"
#include "4coder_helper.h"
#include "4coder_insertion.h"
#include "4coder_fancy.h"
@ -61,8 +49,6 @@
#include "4coder_string_match.cpp"
#include "4coder_buffer_seek_constructors.cpp"
#include "4coder_api_transition_30_31.cpp"
#include "4coder_default_framework_variables.cpp"
#include "4coder_helper.cpp"
#include "4coder_seek.cpp"
@ -91,8 +77,6 @@
#include "4coder_default_hooks.cpp"
#include "4coder_remapping_commands.cpp"
#include "4coder_api_transition_30_31_helpers.cpp"
#endif
// BOTTOM

View File

@ -12,205 +12,6 @@
#include <string.h>
static float
get_line_y(Application_Links *app, View_ID view, i32 line){
Full_Cursor cursor = view_compute_cursor(app, view, seek_line_char(line, 1));
return(cursor.wrapped_y);
}
static Rect_i32
get_line_x_rect(Application_Links *app, View_ID view){
i64 cursor_pos = view_get_cursor_pos(app, view);
Full_Cursor cursor = view_compute_cursor(app, view, seek_pos(cursor_pos));
i64 mark_pos = view_get_mark_pos(app, view);
Full_Cursor mark = view_compute_cursor(app, view, seek_pos(mark_pos));
Rect_i32 rect = {};
rect.x0 = (i32)mark.wrapped_x;
rect.x1 = (i32)cursor.wrapped_x;
rect.y0 = (i32)mark.line;
rect.y1 = (i32)cursor.line;
if (rect.y0 > rect.y1){
Swap(i32, rect.y0, rect.y1);
}
if (rect.x0 > rect.x1){
Swap(i32, rect.x0, rect.x1);
}
return(rect);
}
CUSTOM_COMMAND_SIG(kill_rect)
CUSTOM_DOC("Delete characters in a rectangular region. Range testing is done by unwrapped-xy coordinates.")
{
View_ID view = get_active_view(app, AccessOpen);
Buffer_ID buffer = view_get_buffer(app, view, AccessOpen);
i32_Rect rect = get_line_x_rect(app, view);
for (i32 line = rect.y1; line >= rect.y0; --line){
f32 y = get_line_y(app, view, line);
Full_Cursor cursor = view_compute_cursor(app, view, seek_wrapped_xy((f32)rect.x0, y, 0));
if (cursor.line > 0){
i64 start = cursor.pos;
cursor = view_compute_cursor(app, view, seek_wrapped_xy((f32)rect.x1, y, 0));
if (cursor.line > 0){
i64 end = cursor.pos;
buffer_replace_range(app, buffer, Ii64(start, end), string_u8_empty);
}
}
}
}
static void
pad_buffer_line(Application_Links *app, Buffer_ID buffer, i64 line, char padchar, i64 target){
Partial_Cursor start = buffer_compute_cursor(app, buffer, seek_line_char(line, 1));
if (start.line == line){
Partial_Cursor end = buffer_compute_cursor(app, buffer, seek_line_char(line, 65536));
if (end.line == line){
if (end.character - 1 < target){
Scratch_Block scratch(app);
i64 size = target - (end.character - 1);
char *str = push_array(scratch, char, size);
block_fill_u8(str, size, ' ');
buffer_replace_range(app, buffer, Ii64(end.pos), SCu8(str, size));
}
}
}
}
/*
NOTE(allen): Things I learned from this experiment.
First of all the batch edits aren't too bad, but I think
there could be a single system that I run that through that
knows how to build the batch edit from slightly higher level
information. For instance the idea in point 2.
Secondly I definitely believe I need some sort of "mini-buffer"
concept where a view sends commands so that things like
pasting still work. Then the contents of the "mini-buffer"
can be used to complete the edits at all cursor points.
This doesn't answer all questions, because somehow backspace
still wants to work for multi-lines even when the "mini-buffer"
is emtpy. Such a system would also make it possible to send
paste commands and cursor navigation to interactive bars.
Thirdly any system like this will probably not want to
operate through the co-routine system, because that makes
sending these commands to the "mini-buffer" much more
difficult.
Fourthly I desperately need some way to do multi-highlighting
multi-cursor showing but it is unclear to me how to do that
conveniently. Since this won't exist inside a coroutine
what does such an API even look like??? It's clear to me now
that I may need to start pushing for the view routine before
I am even able to support the GUI. Because that will set up the
system to allow me to think about the problem in more ways.
Finally I have decided not to pursue this direction any more,
it just seems like the wrong way to do it, so I'll stop without
doing multi-cursor for now.
*/
struct Buffer_Rect{
i64 char0;
i64 line0;
i64 char1;
i64 line1;
};
CUSTOM_COMMAND_SIG(multi_line_edit)
CUSTOM_DOC("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.")
{
View_ID view = get_active_view(app, AccessOpen);
Buffer_ID buffer = view_get_buffer(app, view, AccessOpen);
i64 cursor_pos = view_get_cursor_pos(app, view);
Full_Cursor cursor = view_compute_cursor(app, view, seek_pos(cursor_pos));
i64 mark_pos = view_get_mark_pos(app, view);
Full_Cursor mark = view_compute_cursor(app, view, seek_pos(mark_pos));
Buffer_Rect rect = {};
rect.char0 = mark.character;
rect.line0 = mark.line;
rect.char1 = cursor.character;
rect.line1 = cursor.line;
if (rect.line0 > rect.line1){
Swap(i64, rect.line0, rect.line1);
}
if (rect.char0 > rect.char1){
Swap(i64, rect.char0, rect.char1);
}
i64 start_line = cursor.line;
i64 pos = cursor.character - 1;
for (i64 i = rect.line0; i <= rect.line1; ++i){
pad_buffer_line(app, buffer, i, ' ', pos);
}
i64 line_count = rect.line1 - rect.line0 + 1;
for (;;){
User_Input in = get_user_input(app, EventOnAnyKey, EventOnEsc|EventOnMouseLeftButton|EventOnMouseRightButton);
if (in.abort) break;
if (in.key.character && key_is_unmodified(&in.key)){
char str = (char)in.key.character;
Scratch_Block scratch(app);
Buffer_Edit *edits = push_array(scratch, Buffer_Edit, line_count);
Buffer_Edit *edit = edits;
for (i64 i = rect.line0; i <= rect.line1; ++i){
Partial_Cursor partial_cursor = buffer_compute_cursor(app, buffer, seek_line_char(i, pos + 1));
if (partial_cursor.line > 0){
edit->str_start = 0;
edit->len = 1;
edit->start = partial_cursor.pos;
edit->end = partial_cursor.pos;
++edit;
}
}
i32 edit_count = (int)(edit - edits);
buffer_batch_edit(app, buffer, &str, edits, edit_count);
++pos;
view_set_cursor(app, view, seek_line_char(start_line, pos + 1), true);
}
else if (in.key.keycode == key_back){
if (pos > 0){
Scratch_Block scratch(app);
Buffer_Edit *edits = push_array(scratch, Buffer_Edit, line_count);
Buffer_Edit *edit = edits;
for (i64 i = rect.line0; i <= rect.line1; ++i){
Partial_Cursor partial_cursor = buffer_compute_cursor(app, buffer, seek_line_char(i, pos + 1));
if (partial_cursor.line > 0){
edit->str_start = 0;
edit->len = 0;
edit->start = partial_cursor.pos - 1;
edit->end = partial_cursor.pos;
++edit;
}
}
i32 edit_count = (int)(edit - edits);
buffer_batch_edit(app, buffer, 0, edits, edit_count);
--pos;
}
}
else{
break;
}
}
}
// NOTE(allen): An experimental mutli-pasting thing
CUSTOM_COMMAND_SIG(multi_paste){
@ -260,9 +61,11 @@ multi_paste_range(Application_Links *app, View_ID view, Range_i64 range, i32 pas
if (paste_count >= 1){
Buffer_ID buffer = view_get_buffer(app, view, AccessOpen);
if (buffer != 0){
i32 total_size = 0;
i64 total_size = 0;
for (i32 paste_index = 0; paste_index < paste_count; ++paste_index){
total_size += 1 + clipboard_index(app, 0, paste_index, 0, 0);
Scratch_Block scratch(app);
String_Const_u8 string = push_clipboard_index(app, scratch, 0, paste_index);
total_size += string.size + 1;
}
total_size -= 1;
@ -386,6 +189,8 @@ CUSTOM_COMMAND_SIG(multi_paste_interactive_quick){
CUSTOM_COMMAND_SIG(rename_parameter)
CUSTOM_DOC("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.")
{
NotImplemented;
#if 0
View_ID view = get_active_view(app, AccessOpen);
Buffer_ID buffer = view_get_buffer(app, view, AccessOpen);
i64 cursor_pos = view_get_cursor_pos(app, view);
@ -396,7 +201,6 @@ CUSTOM_DOC("If the cursor is found to be on the name of a function parameter in
Cpp_Get_Token_Result result = {};
if (get_token_from_pos(app, buffer, cursor_pos, &result)){
if (!result.in_whitespace_after_token){
#if 0
static const i32 stream_space_size = 512;
Cpp_Token stream_space[stream_space_size];
Stream_Tokens_DEP stream = {};
@ -517,11 +321,11 @@ CUSTOM_DOC("If the cursor is found to be on the name of a function parameter in
}
}
}
#endif
}
}
end_temp(temp);
#endif
}
typedef u32 Write_Explicit_Enum_Values_Mode;
@ -532,6 +336,8 @@ enum{
static void
write_explicit_enum_values_parameters(Application_Links *app, Write_Explicit_Enum_Values_Mode mode){
NotImplemented;
#if 0
View_ID view = get_active_view(app, AccessOpen);
Buffer_ID buffer = view_get_buffer(app, view, AccessOpen);
@ -543,7 +349,6 @@ write_explicit_enum_values_parameters(Application_Links *app, Write_Explicit_Enu
Cpp_Get_Token_Result result = {};
if (get_token_from_pos(app, buffer, pos, &result)){
if (!result.in_whitespace_after_token){
#if 0
Cpp_Token stream_space[32];
Stream_Tokens_DEP stream = {};
@ -683,11 +488,11 @@ write_explicit_enum_values_parameters(Application_Links *app, Write_Explicit_Enu
}
}
}
#endif
}
}
end_temp(temp);
#endif
}
CUSTOM_COMMAND_SIG(write_explicit_enum_values)
@ -742,8 +547,8 @@ get_bindings(void *data, i32 size){
// begin_map to clear everything that was in the map and
// bind new things instead.
begin_map(context, mapid_file);
bind(context, key_back, MDFR_ALT|MDFR_CTRL, kill_rect);
bind(context, ' ', MDFR_ALT|MDFR_CTRL, multi_line_edit);
//bind(context, key_back, MDFR_ALT|MDFR_CTRL, kill_rect);
//bind(context, ' ', MDFR_ALT|MDFR_CTRL, multi_line_edit);
bind(context, key_page_up, MDFR_ALT, miblo_increment_time_stamp);
bind(context, key_page_down, MDFR_ALT, miblo_decrement_time_stamp);

View File

@ -19,10 +19,21 @@ struct Application_Links;
#define GET_BUFFER_BY_FILE_NAME_SIG(n) Buffer_ID n(Application_Links *app, String_Const_u8 file_name, Access_Flag access)
#define BUFFER_READ_RANGE_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id, Range_i64 range, char *out)
#define BUFFER_REPLACE_RANGE_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id, Range_i64 range, String_Const_u8 string)
#define BUFFER_BATCH_EDIT_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id, char *str, Buffer_Edit *edits, i32 edit_count)
#define BUFFER_BATCH_EDIT_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id, Batch_Edit *batch)
#define BUFFER_SEEK_STRING_SIG(n) String_Match n(Application_Links *app, Buffer_ID buffer, String_Const_u8 needle, Scan_Direction direction, i64 start_pos)
#define BUFFER_SEEK_CHARACTER_CLASS_SIG(n) String_Match n(Application_Links *app, Buffer_ID buffer, Character_Predicate *predicate, Scan_Direction direction, i64 start_pos)
#define BUFFER_COMPUTE_CURSOR_SIG(n) Partial_Cursor n(Application_Links *app, Buffer_ID buffer_id, Buffer_Seek seek)
#define BUFFER_LINE_Y_DIFFERENCE_SIG(n) f32 n(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 line_a, i64 line_b)
#define BUFFER_LINE_SHIFT_Y_SIG(n) Line_Shift_Vertical n(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 line, f32 y_shift)
#define BUFFER_POS_AT_RELATIVE_XY_SIG(n) i64 n(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, Vec2_f32 relative_xy)
#define BUFFER_RELATIVE_XY_OF_POS_SIG(n) Vec2_f32 n(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos)
#define BUFFER_RELATIVE_CHARACTER_FROM_POS_SIG(n) i64 n(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos)
#define BUFFER_POS_FROM_RELATIVE_CHARACTER_SIG(n) i64 n(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 relative_character)
#define VIEW_LINE_Y_DIFFERENCE_SIG(n) f32 n(Application_Links *app, View_ID view_id, i64 line_a, i64 line_b)
#define VIEW_LINE_SHIFT_Y_SIG(n) Line_Shift_Vertical n(Application_Links *app, View_ID view_id, i64 line, f32 y_shift)
#define VIEW_POS_AT_RELATIVE_XY_SIG(n) i64 n(Application_Links *app, View_ID view_id, i64 base_line, Vec2_f32 relative_xy)
#define VIEW_RELATIVE_XY_OF_POS_SIG(n) Vec2_f32 n(Application_Links *app, View_ID view_id, i64 base_line, i64 pos)
#define VIEW_RELATIVE_CHARACTER_FROM_POS_SIG(n) i64 n(Application_Links *app, View_ID view_id, i64 base_line, i64 pos)
#define VIEW_POS_FROM_RELATIVE_CHARACTER_SIG(n) i64 n(Application_Links *app, View_ID view_id, i64 base_line, i64 character)
#define BUFFER_EXISTS_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id)
#define BUFFER_READY_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id)
#define BUFFER_GET_ACCESS_FLAGS_SIG(n) Access_Flag n(Application_Links *app, Buffer_ID buffer_id)
@ -68,14 +79,16 @@ struct Application_Links;
#define PANEL_GET_MARGIN_SIG(n) Rect_i32 n(Application_Links *app, Panel_ID panel_id)
#define VIEW_CLOSE_SIG(n) b32 n(Application_Links *app, View_ID view_id)
#define VIEW_GET_BUFFER_REGION_SIG(n) Rect_f32 n(Application_Links *app, View_ID view_id)
#define VIEW_GET_SCROLL_VARS_SIG(n) GUI_Scroll_Vars n(Application_Links *app, View_ID view_id)
#define VIEW_GET_BUFFER_SCROLL_SIG(n) Buffer_Scroll n(Application_Links *app, View_ID view_id)
#define VIEW_GET_BASIC_SCROLL_SIG(n) Basic_Scroll n(Application_Links *app, View_ID view_id)
#define VIEW_SET_ACTIVE_SIG(n) b32 n(Application_Links *app, View_ID view_id)
#define VIEW_GET_SETTING_SIG(n) b32 n(Application_Links *app, View_ID view_id, View_Setting_ID setting, i32 *value_out)
#define VIEW_SET_SETTING_SIG(n) b32 n(Application_Links *app, View_ID view_id, View_Setting_ID setting, i32 value)
#define VIEW_GET_MANAGED_SCOPE_SIG(n) Managed_Scope n(Application_Links *app, View_ID view_id)
#define VIEW_COMPUTE_CURSOR_SIG(n) Full_Cursor n(Application_Links *app, View_ID view_id, Buffer_Seek seek)
#define BUFFER_COMPUTE_CURSOR_SIG(n) Buffer_Cursor n(Application_Links *app, Buffer_ID buffer, Buffer_Seek seek)
#define VIEW_SET_CURSOR_SIG(n) b32 n(Application_Links *app, View_ID view_id, Buffer_Seek seek, b32 set_preferred_x)
#define VIEW_SET_SCROLL_SIG(n) b32 n(Application_Links *app, View_ID view_id, GUI_Scroll_Vars scroll)
#define VIEW_SET_BUFFER_SCROLL_SIG(n) b32 n(Application_Links *app, View_ID view_id, Buffer_Scroll scroll)
#define VIEW_SET_BASIC_SCROLL_SIG(n) b32 n(Application_Links *app, View_ID view_id, Basic_Scroll scroll)
#define VIEW_SET_MARK_SIG(n) b32 n(Application_Links *app, View_ID view_id, Buffer_Seek seek)
#define VIEW_SET_BUFFER_SIG(n) b32 n(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Set_Buffer_Flag flags)
#define VIEW_POST_FADE_SIG(n) b32 n(Application_Links *app, View_ID view_id, f32 seconds, Range_i64 range, int_color color)
@ -159,21 +172,17 @@ struct Application_Links;
#define DRAW_CLIP_POP_SIG(n) f32_Rect n(Application_Links *app)
#define DRAW_COORDINATE_CENTER_PUSH_SIG(n) void n(Application_Links *app, Vec2 point)
#define DRAW_COORDINATE_CENTER_POP_SIG(n) Vec2 n(Application_Links *app)
#define TEXT_LAYOUT_CREATE_SIG(n) Text_Layout_ID n(Application_Links *app, Buffer_ID buffer_id, Rect_f32 rect, Buffer_Point buffer_point)
#define TEXT_LAYOUT_GET_BUFFER_SIG(n) b32 n(Application_Links *app, Text_Layout_ID text_layout_id, Buffer_ID *buffer_id_out)
#define TEXT_LAYOUT_BUFFER_POINT_TO_LAYOUT_POINT_SIG(n) b32 n(Application_Links *app, Text_Layout_ID text_layout_id, Vec2 buffer_relative_p, Vec2 *p_out)
#define TEXT_LAYOUT_LAYOUT_POINT_TO_BUFFER_POINT_SIG(n) b32 n(Application_Links *app, Text_Layout_ID text_layout_id, Vec2 layout_relative_p, Vec2 *p_out)
#define TEXT_LAYOUT_GET_ON_SCREEN_RANGE_SIG(n) Range_i64 n(Application_Links *app, Text_Layout_ID text_layout_id)
#define TEXT_LAYOUT_ON_SCREEN_SIG(n) Rect_f32 n(Application_Links *app, Text_Layout_ID text_layout_id)
#define TEXT_LAYOUT_GET_VISIBLE_RANGE_SIG(n) Interval_i64 n(Application_Links *app, Text_Layout_ID text_layout_id)
#define TEXT_LAYOUT_LINE_ON_SCREEN_SIG(n) Rect_f32 n(Application_Links *app, Text_Layout_ID layout_id, i64 line_number)
#define TEXT_LAYOUT_CHARACTER_ON_SCREEN_SIG(n) Rect_f32 n(Application_Links *app, Text_Layout_ID layout_id, i64 pos)
#define PAINT_TEXT_COLOR_SIG(n) void n(Application_Links *app, Text_Layout_ID layout_id, Range_i64 range, int_color color)
#define PAINT_TEXT_COLOR_SIG(n) void n(Application_Links *app, Text_Layout_ID layout_id, Interval_i64 range, int_color color)
#define TEXT_LAYOUT_FREE_SIG(n) b32 n(Application_Links *app, Text_Layout_ID text_layout_id)
#define COMPUTE_RENDER_LAYOUT_SIG(n) Text_Layout_ID n(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Vec2 screen_p, Vec2 layout_dim, Buffer_Point buffer_point, i32 one_past_last)
#define DRAW_RENDER_LAYOUT_SIG(n) void n(Application_Links *app, View_ID view_id)
#define DRAW_TEXT_LAYOUT_SIG(n) void n(Application_Links *app, Text_Layout_ID layout_id)
#define OPEN_COLOR_PICKER_SIG(n) void n(Application_Links *app, Color_Picker *picker)
#define ANIMATE_IN_N_MILLISECONDS_SIG(n) void n(Application_Links *app, u32 n)
#define BUFFER_FIND_ALL_MATCHES_SIG(n) String_Match_List n(Application_Links *app, Arena *arena, Buffer_ID buffer, i32 string_id, Range_i64 range, String_Const_u8 needle, Character_Predicate *predicate, Scan_Direction direction)
#define GET_VIEW_VISIBLE_RANGE_SIG(n) Range n(Application_Links *app, View_ID view_id)
typedef GLOBAL_SET_SETTING_SIG(Global_Set_Setting_Function);
typedef GLOBAL_SET_MAPPING_SIG(Global_Set_Mapping_Function);
typedef GLOBAL_GET_SCREEN_RECTANGLE_SIG(Global_Get_Screen_Rectangle_Function);
@ -197,7 +206,18 @@ typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function);
typedef BUFFER_BATCH_EDIT_SIG(Buffer_Batch_Edit_Function);
typedef BUFFER_SEEK_STRING_SIG(Buffer_Seek_String_Function);
typedef BUFFER_SEEK_CHARACTER_CLASS_SIG(Buffer_Seek_Character_Class_Function);
typedef BUFFER_COMPUTE_CURSOR_SIG(Buffer_Compute_Cursor_Function);
typedef BUFFER_LINE_Y_DIFFERENCE_SIG(Buffer_Line_Y_Difference_Function);
typedef BUFFER_LINE_SHIFT_Y_SIG(Buffer_Line_Shift_Y_Function);
typedef BUFFER_POS_AT_RELATIVE_XY_SIG(Buffer_Pos_At_Relative_XY_Function);
typedef BUFFER_RELATIVE_XY_OF_POS_SIG(Buffer_Relative_XY_Of_Pos_Function);
typedef BUFFER_RELATIVE_CHARACTER_FROM_POS_SIG(Buffer_Relative_Character_From_Pos_Function);
typedef BUFFER_POS_FROM_RELATIVE_CHARACTER_SIG(Buffer_Pos_From_Relative_Character_Function);
typedef VIEW_LINE_Y_DIFFERENCE_SIG(View_Line_Y_Difference_Function);
typedef VIEW_LINE_SHIFT_Y_SIG(View_Line_Shift_Y_Function);
typedef VIEW_POS_AT_RELATIVE_XY_SIG(View_Pos_At_Relative_XY_Function);
typedef VIEW_RELATIVE_XY_OF_POS_SIG(View_Relative_XY_Of_Pos_Function);
typedef VIEW_RELATIVE_CHARACTER_FROM_POS_SIG(View_Relative_Character_From_Pos_Function);
typedef VIEW_POS_FROM_RELATIVE_CHARACTER_SIG(View_Pos_From_Relative_Character_Function);
typedef BUFFER_EXISTS_SIG(Buffer_Exists_Function);
typedef BUFFER_READY_SIG(Buffer_Ready_Function);
typedef BUFFER_GET_ACCESS_FLAGS_SIG(Buffer_Get_Access_Flags_Function);
@ -243,14 +263,16 @@ typedef PANEL_GET_MAX_SIG(Panel_Get_Max_Function);
typedef PANEL_GET_MARGIN_SIG(Panel_Get_Margin_Function);
typedef VIEW_CLOSE_SIG(View_Close_Function);
typedef VIEW_GET_BUFFER_REGION_SIG(View_Get_Buffer_Region_Function);
typedef VIEW_GET_SCROLL_VARS_SIG(View_Get_Scroll_Vars_Function);
typedef VIEW_GET_BUFFER_SCROLL_SIG(View_Get_Buffer_Scroll_Function);
typedef VIEW_GET_BASIC_SCROLL_SIG(View_Get_Basic_Scroll_Function);
typedef VIEW_SET_ACTIVE_SIG(View_Set_Active_Function);
typedef VIEW_GET_SETTING_SIG(View_Get_Setting_Function);
typedef VIEW_SET_SETTING_SIG(View_Set_Setting_Function);
typedef VIEW_GET_MANAGED_SCOPE_SIG(View_Get_Managed_Scope_Function);
typedef VIEW_COMPUTE_CURSOR_SIG(View_Compute_Cursor_Function);
typedef BUFFER_COMPUTE_CURSOR_SIG(Buffer_Compute_Cursor_Function);
typedef VIEW_SET_CURSOR_SIG(View_Set_Cursor_Function);
typedef VIEW_SET_SCROLL_SIG(View_Set_Scroll_Function);
typedef VIEW_SET_BUFFER_SCROLL_SIG(View_Set_Buffer_Scroll_Function);
typedef VIEW_SET_BASIC_SCROLL_SIG(View_Set_Basic_Scroll_Function);
typedef VIEW_SET_MARK_SIG(View_Set_Mark_Function);
typedef VIEW_SET_BUFFER_SIG(View_Set_Buffer_Function);
typedef VIEW_POST_FADE_SIG(View_Post_Fade_Function);
@ -334,21 +356,17 @@ typedef DRAW_CLIP_PUSH_SIG(Draw_Clip_Push_Function);
typedef DRAW_CLIP_POP_SIG(Draw_Clip_Pop_Function);
typedef DRAW_COORDINATE_CENTER_PUSH_SIG(Draw_Coordinate_Center_Push_Function);
typedef DRAW_COORDINATE_CENTER_POP_SIG(Draw_Coordinate_Center_Pop_Function);
typedef TEXT_LAYOUT_CREATE_SIG(Text_Layout_Create_Function);
typedef TEXT_LAYOUT_GET_BUFFER_SIG(Text_Layout_Get_Buffer_Function);
typedef TEXT_LAYOUT_BUFFER_POINT_TO_LAYOUT_POINT_SIG(Text_Layout_Buffer_Point_To_Layout_Point_Function);
typedef TEXT_LAYOUT_LAYOUT_POINT_TO_BUFFER_POINT_SIG(Text_Layout_Layout_Point_To_Buffer_Point_Function);
typedef TEXT_LAYOUT_GET_ON_SCREEN_RANGE_SIG(Text_Layout_Get_On_Screen_Range_Function);
typedef TEXT_LAYOUT_ON_SCREEN_SIG(Text_Layout_On_Screen_Function);
typedef TEXT_LAYOUT_GET_VISIBLE_RANGE_SIG(Text_Layout_Get_Visible_Range_Function);
typedef TEXT_LAYOUT_LINE_ON_SCREEN_SIG(Text_Layout_Line_On_Screen_Function);
typedef TEXT_LAYOUT_CHARACTER_ON_SCREEN_SIG(Text_Layout_Character_On_Screen_Function);
typedef PAINT_TEXT_COLOR_SIG(Paint_Text_Color_Function);
typedef TEXT_LAYOUT_FREE_SIG(Text_Layout_Free_Function);
typedef COMPUTE_RENDER_LAYOUT_SIG(Compute_Render_Layout_Function);
typedef DRAW_RENDER_LAYOUT_SIG(Draw_Render_Layout_Function);
typedef DRAW_TEXT_LAYOUT_SIG(Draw_Text_Layout_Function);
typedef OPEN_COLOR_PICKER_SIG(Open_Color_Picker_Function);
typedef ANIMATE_IN_N_MILLISECONDS_SIG(Animate_In_N_Milliseconds_Function);
typedef BUFFER_FIND_ALL_MATCHES_SIG(Buffer_Find_All_Matches_Function);
typedef GET_VIEW_VISIBLE_RANGE_SIG(Get_View_Visible_Range_Function);
struct Application_Links{
#if defined(ALLOW_DEP_4CODER)
Global_Set_Setting_Function *global_set_setting;
@ -374,7 +392,18 @@ Buffer_Replace_Range_Function *buffer_replace_range;
Buffer_Batch_Edit_Function *buffer_batch_edit;
Buffer_Seek_String_Function *buffer_seek_string;
Buffer_Seek_Character_Class_Function *buffer_seek_character_class;
Buffer_Compute_Cursor_Function *buffer_compute_cursor;
Buffer_Line_Y_Difference_Function *buffer_line_y_difference;
Buffer_Line_Shift_Y_Function *buffer_line_shift_y;
Buffer_Pos_At_Relative_XY_Function *buffer_pos_at_relative_xy;
Buffer_Relative_XY_Of_Pos_Function *buffer_relative_xy_of_pos;
Buffer_Relative_Character_From_Pos_Function *buffer_relative_character_from_pos;
Buffer_Pos_From_Relative_Character_Function *buffer_pos_from_relative_character;
View_Line_Y_Difference_Function *view_line_y_difference;
View_Line_Shift_Y_Function *view_line_shift_y;
View_Pos_At_Relative_XY_Function *view_pos_at_relative_xy;
View_Relative_XY_Of_Pos_Function *view_relative_xy_of_pos;
View_Relative_Character_From_Pos_Function *view_relative_character_from_pos;
View_Pos_From_Relative_Character_Function *view_pos_from_relative_character;
Buffer_Exists_Function *buffer_exists;
Buffer_Ready_Function *buffer_ready;
Buffer_Get_Access_Flags_Function *buffer_get_access_flags;
@ -420,14 +449,16 @@ Panel_Get_Max_Function *panel_get_max;
Panel_Get_Margin_Function *panel_get_margin;
View_Close_Function *view_close;
View_Get_Buffer_Region_Function *view_get_buffer_region;
View_Get_Scroll_Vars_Function *view_get_scroll_vars;
View_Get_Buffer_Scroll_Function *view_get_buffer_scroll;
View_Get_Basic_Scroll_Function *view_get_basic_scroll;
View_Set_Active_Function *view_set_active;
View_Get_Setting_Function *view_get_setting;
View_Set_Setting_Function *view_set_setting;
View_Get_Managed_Scope_Function *view_get_managed_scope;
View_Compute_Cursor_Function *view_compute_cursor;
Buffer_Compute_Cursor_Function *buffer_compute_cursor;
View_Set_Cursor_Function *view_set_cursor;
View_Set_Scroll_Function *view_set_scroll;
View_Set_Buffer_Scroll_Function *view_set_buffer_scroll;
View_Set_Basic_Scroll_Function *view_set_basic_scroll;
View_Set_Mark_Function *view_set_mark;
View_Set_Buffer_Function *view_set_buffer;
View_Post_Fade_Function *view_post_fade;
@ -511,21 +542,17 @@ Draw_Clip_Push_Function *draw_clip_push;
Draw_Clip_Pop_Function *draw_clip_pop;
Draw_Coordinate_Center_Push_Function *draw_coordinate_center_push;
Draw_Coordinate_Center_Pop_Function *draw_coordinate_center_pop;
Text_Layout_Create_Function *text_layout_create;
Text_Layout_Get_Buffer_Function *text_layout_get_buffer;
Text_Layout_Buffer_Point_To_Layout_Point_Function *text_layout_buffer_point_to_layout_point;
Text_Layout_Layout_Point_To_Buffer_Point_Function *text_layout_layout_point_to_buffer_point;
Text_Layout_Get_On_Screen_Range_Function *text_layout_get_on_screen_range;
Text_Layout_On_Screen_Function *text_layout_on_screen;
Text_Layout_Get_Visible_Range_Function *text_layout_get_visible_range;
Text_Layout_Line_On_Screen_Function *text_layout_line_on_screen;
Text_Layout_Character_On_Screen_Function *text_layout_character_on_screen;
Paint_Text_Color_Function *paint_text_color;
Text_Layout_Free_Function *text_layout_free;
Compute_Render_Layout_Function *compute_render_layout;
Draw_Render_Layout_Function *draw_render_layout;
Draw_Text_Layout_Function *draw_text_layout;
Open_Color_Picker_Function *open_color_picker;
Animate_In_N_Milliseconds_Function *animate_in_n_milliseconds;
Buffer_Find_All_Matches_Function *buffer_find_all_matches;
Get_View_Visible_Range_Function *get_view_visible_range;
#else
Global_Set_Setting_Function *global_set_setting_;
Global_Set_Mapping_Function *global_set_mapping_;
@ -550,7 +577,18 @@ Buffer_Replace_Range_Function *buffer_replace_range_;
Buffer_Batch_Edit_Function *buffer_batch_edit_;
Buffer_Seek_String_Function *buffer_seek_string_;
Buffer_Seek_Character_Class_Function *buffer_seek_character_class_;
Buffer_Compute_Cursor_Function *buffer_compute_cursor_;
Buffer_Line_Y_Difference_Function *buffer_line_y_difference_;
Buffer_Line_Shift_Y_Function *buffer_line_shift_y_;
Buffer_Pos_At_Relative_XY_Function *buffer_pos_at_relative_xy_;
Buffer_Relative_XY_Of_Pos_Function *buffer_relative_xy_of_pos_;
Buffer_Relative_Character_From_Pos_Function *buffer_relative_character_from_pos_;
Buffer_Pos_From_Relative_Character_Function *buffer_pos_from_relative_character_;
View_Line_Y_Difference_Function *view_line_y_difference_;
View_Line_Shift_Y_Function *view_line_shift_y_;
View_Pos_At_Relative_XY_Function *view_pos_at_relative_xy_;
View_Relative_XY_Of_Pos_Function *view_relative_xy_of_pos_;
View_Relative_Character_From_Pos_Function *view_relative_character_from_pos_;
View_Pos_From_Relative_Character_Function *view_pos_from_relative_character_;
Buffer_Exists_Function *buffer_exists_;
Buffer_Ready_Function *buffer_ready_;
Buffer_Get_Access_Flags_Function *buffer_get_access_flags_;
@ -596,14 +634,16 @@ Panel_Get_Max_Function *panel_get_max_;
Panel_Get_Margin_Function *panel_get_margin_;
View_Close_Function *view_close_;
View_Get_Buffer_Region_Function *view_get_buffer_region_;
View_Get_Scroll_Vars_Function *view_get_scroll_vars_;
View_Get_Buffer_Scroll_Function *view_get_buffer_scroll_;
View_Get_Basic_Scroll_Function *view_get_basic_scroll_;
View_Set_Active_Function *view_set_active_;
View_Get_Setting_Function *view_get_setting_;
View_Set_Setting_Function *view_set_setting_;
View_Get_Managed_Scope_Function *view_get_managed_scope_;
View_Compute_Cursor_Function *view_compute_cursor_;
Buffer_Compute_Cursor_Function *buffer_compute_cursor_;
View_Set_Cursor_Function *view_set_cursor_;
View_Set_Scroll_Function *view_set_scroll_;
View_Set_Buffer_Scroll_Function *view_set_buffer_scroll_;
View_Set_Basic_Scroll_Function *view_set_basic_scroll_;
View_Set_Mark_Function *view_set_mark_;
View_Set_Buffer_Function *view_set_buffer_;
View_Post_Fade_Function *view_post_fade_;
@ -687,21 +727,17 @@ Draw_Clip_Push_Function *draw_clip_push_;
Draw_Clip_Pop_Function *draw_clip_pop_;
Draw_Coordinate_Center_Push_Function *draw_coordinate_center_push_;
Draw_Coordinate_Center_Pop_Function *draw_coordinate_center_pop_;
Text_Layout_Create_Function *text_layout_create_;
Text_Layout_Get_Buffer_Function *text_layout_get_buffer_;
Text_Layout_Buffer_Point_To_Layout_Point_Function *text_layout_buffer_point_to_layout_point_;
Text_Layout_Layout_Point_To_Buffer_Point_Function *text_layout_layout_point_to_buffer_point_;
Text_Layout_Get_On_Screen_Range_Function *text_layout_get_on_screen_range_;
Text_Layout_On_Screen_Function *text_layout_on_screen_;
Text_Layout_Get_Visible_Range_Function *text_layout_get_visible_range_;
Text_Layout_Line_On_Screen_Function *text_layout_line_on_screen_;
Text_Layout_Character_On_Screen_Function *text_layout_character_on_screen_;
Paint_Text_Color_Function *paint_text_color_;
Text_Layout_Free_Function *text_layout_free_;
Compute_Render_Layout_Function *compute_render_layout_;
Draw_Render_Layout_Function *draw_render_layout_;
Draw_Text_Layout_Function *draw_text_layout_;
Open_Color_Picker_Function *open_color_picker_;
Animate_In_N_Milliseconds_Function *animate_in_n_milliseconds_;
Buffer_Find_All_Matches_Function *buffer_find_all_matches_;
Get_View_Visible_Range_Function *get_view_visible_range_;
#endif
void *memory;
int32_t memory_size;
@ -734,7 +770,18 @@ app_links->buffer_replace_range_ = Buffer_Replace_Range;\
app_links->buffer_batch_edit_ = Buffer_Batch_Edit;\
app_links->buffer_seek_string_ = Buffer_Seek_String;\
app_links->buffer_seek_character_class_ = Buffer_Seek_Character_Class;\
app_links->buffer_compute_cursor_ = Buffer_Compute_Cursor;\
app_links->buffer_line_y_difference_ = Buffer_Line_Y_Difference;\
app_links->buffer_line_shift_y_ = Buffer_Line_Shift_Y;\
app_links->buffer_pos_at_relative_xy_ = Buffer_Pos_At_Relative_XY;\
app_links->buffer_relative_xy_of_pos_ = Buffer_Relative_XY_Of_Pos;\
app_links->buffer_relative_character_from_pos_ = Buffer_Relative_Character_From_Pos;\
app_links->buffer_pos_from_relative_character_ = Buffer_Pos_From_Relative_Character;\
app_links->view_line_y_difference_ = View_Line_Y_Difference;\
app_links->view_line_shift_y_ = View_Line_Shift_Y;\
app_links->view_pos_at_relative_xy_ = View_Pos_At_Relative_XY;\
app_links->view_relative_xy_of_pos_ = View_Relative_XY_Of_Pos;\
app_links->view_relative_character_from_pos_ = View_Relative_Character_From_Pos;\
app_links->view_pos_from_relative_character_ = View_Pos_From_Relative_Character;\
app_links->buffer_exists_ = Buffer_Exists;\
app_links->buffer_ready_ = Buffer_Ready;\
app_links->buffer_get_access_flags_ = Buffer_Get_Access_Flags;\
@ -780,14 +827,16 @@ app_links->panel_get_max_ = Panel_Get_Max;\
app_links->panel_get_margin_ = Panel_Get_Margin;\
app_links->view_close_ = View_Close;\
app_links->view_get_buffer_region_ = View_Get_Buffer_Region;\
app_links->view_get_scroll_vars_ = View_Get_Scroll_Vars;\
app_links->view_get_buffer_scroll_ = View_Get_Buffer_Scroll;\
app_links->view_get_basic_scroll_ = View_Get_Basic_Scroll;\
app_links->view_set_active_ = View_Set_Active;\
app_links->view_get_setting_ = View_Get_Setting;\
app_links->view_set_setting_ = View_Set_Setting;\
app_links->view_get_managed_scope_ = View_Get_Managed_Scope;\
app_links->view_compute_cursor_ = View_Compute_Cursor;\
app_links->buffer_compute_cursor_ = Buffer_Compute_Cursor;\
app_links->view_set_cursor_ = View_Set_Cursor;\
app_links->view_set_scroll_ = View_Set_Scroll;\
app_links->view_set_buffer_scroll_ = View_Set_Buffer_Scroll;\
app_links->view_set_basic_scroll_ = View_Set_Basic_Scroll;\
app_links->view_set_mark_ = View_Set_Mark;\
app_links->view_set_buffer_ = View_Set_Buffer;\
app_links->view_post_fade_ = View_Post_Fade;\
@ -871,21 +920,17 @@ app_links->draw_clip_push_ = Draw_Clip_Push;\
app_links->draw_clip_pop_ = Draw_Clip_Pop;\
app_links->draw_coordinate_center_push_ = Draw_Coordinate_Center_Push;\
app_links->draw_coordinate_center_pop_ = Draw_Coordinate_Center_Pop;\
app_links->text_layout_create_ = Text_Layout_Create;\
app_links->text_layout_get_buffer_ = Text_Layout_Get_Buffer;\
app_links->text_layout_buffer_point_to_layout_point_ = Text_Layout_Buffer_Point_To_Layout_Point;\
app_links->text_layout_layout_point_to_buffer_point_ = Text_Layout_Layout_Point_To_Buffer_Point;\
app_links->text_layout_get_on_screen_range_ = Text_Layout_Get_On_Screen_Range;\
app_links->text_layout_on_screen_ = Text_Layout_On_Screen;\
app_links->text_layout_get_visible_range_ = Text_Layout_Get_Visible_Range;\
app_links->text_layout_line_on_screen_ = Text_Layout_Line_On_Screen;\
app_links->text_layout_character_on_screen_ = Text_Layout_Character_On_Screen;\
app_links->paint_text_color_ = Paint_Text_Color;\
app_links->text_layout_free_ = Text_Layout_Free;\
app_links->compute_render_layout_ = Compute_Render_Layout;\
app_links->draw_render_layout_ = Draw_Render_Layout;\
app_links->draw_text_layout_ = Draw_Text_Layout;\
app_links->open_color_picker_ = Open_Color_Picker;\
app_links->animate_in_n_milliseconds_ = Animate_In_N_Milliseconds;\
app_links->buffer_find_all_matches_ = Buffer_Find_All_Matches;\
app_links->get_view_visible_range_ = Get_View_Visible_Range;} while(false)
app_links->buffer_find_all_matches_ = Buffer_Find_All_Matches;} while(false)
#if defined(ALLOW_DEP_4CODER)
static b32 global_set_setting(Application_Links *app, Global_Setting_ID setting, i32 value){return(app->global_set_setting(app, setting, value));}
static b32 global_set_mapping(Application_Links *app, void *data, i32 size){return(app->global_set_mapping(app, data, size));}
@ -907,10 +952,21 @@ static Buffer_ID get_buffer_by_name(Application_Links *app, String_Const_u8 name
static Buffer_ID get_buffer_by_file_name(Application_Links *app, String_Const_u8 file_name, Access_Flag access){return(app->get_buffer_by_file_name(app, file_name, access));}
static b32 buffer_read_range(Application_Links *app, Buffer_ID buffer_id, Range_i64 range, char *out){return(app->buffer_read_range(app, buffer_id, range, out));}
static b32 buffer_replace_range(Application_Links *app, Buffer_ID buffer_id, Range_i64 range, String_Const_u8 string){return(app->buffer_replace_range(app, buffer_id, range, string));}
static b32 buffer_batch_edit(Application_Links *app, Buffer_ID buffer_id, char *str, Buffer_Edit *edits, i32 edit_count){return(app->buffer_batch_edit(app, buffer_id, str, edits, edit_count));}
static b32 buffer_batch_edit(Application_Links *app, Buffer_ID buffer_id, Batch_Edit *batch){return(app->buffer_batch_edit(app, buffer_id, batch));}
static String_Match buffer_seek_string(Application_Links *app, Buffer_ID buffer, String_Const_u8 needle, Scan_Direction direction, i64 start_pos){return(app->buffer_seek_string(app, buffer, needle, direction, start_pos));}
static String_Match buffer_seek_character_class(Application_Links *app, Buffer_ID buffer, Character_Predicate *predicate, Scan_Direction direction, i64 start_pos){return(app->buffer_seek_character_class(app, buffer, predicate, direction, start_pos));}
static Partial_Cursor buffer_compute_cursor(Application_Links *app, Buffer_ID buffer_id, Buffer_Seek seek){return(app->buffer_compute_cursor(app, buffer_id, seek));}
static f32 buffer_line_y_difference(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 line_a, i64 line_b){return(app->buffer_line_y_difference(app, buffer_id, width, face_id, line_a, line_b));}
static Line_Shift_Vertical buffer_line_shift_y(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 line, f32 y_shift){return(app->buffer_line_shift_y(app, buffer_id, width, face_id, line, y_shift));}
static i64 buffer_pos_at_relative_xy(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, Vec2_f32 relative_xy){return(app->buffer_pos_at_relative_xy(app, buffer_id, width, face_id, base_line, relative_xy));}
static Vec2_f32 buffer_relative_xy_of_pos(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos){return(app->buffer_relative_xy_of_pos(app, buffer_id, width, face_id, base_line, pos));}
static i64 buffer_relative_character_from_pos(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos){return(app->buffer_relative_character_from_pos(app, buffer_id, width, face_id, base_line, pos));}
static i64 buffer_pos_from_relative_character(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 relative_character){return(app->buffer_pos_from_relative_character(app, buffer_id, width, face_id, base_line, relative_character));}
static f32 view_line_y_difference(Application_Links *app, View_ID view_id, i64 line_a, i64 line_b){return(app->view_line_y_difference(app, view_id, line_a, line_b));}
static Line_Shift_Vertical view_line_shift_y(Application_Links *app, View_ID view_id, i64 line, f32 y_shift){return(app->view_line_shift_y(app, view_id, line, y_shift));}
static i64 view_pos_at_relative_xy(Application_Links *app, View_ID view_id, i64 base_line, Vec2_f32 relative_xy){return(app->view_pos_at_relative_xy(app, view_id, base_line, relative_xy));}
static Vec2_f32 view_relative_xy_of_pos(Application_Links *app, View_ID view_id, i64 base_line, i64 pos){return(app->view_relative_xy_of_pos(app, view_id, base_line, pos));}
static i64 view_relative_character_from_pos(Application_Links *app, View_ID view_id, i64 base_line, i64 pos){return(app->view_relative_character_from_pos(app, view_id, base_line, pos));}
static i64 view_pos_from_relative_character(Application_Links *app, View_ID view_id, i64 base_line, i64 character){return(app->view_pos_from_relative_character(app, view_id, base_line, character));}
static b32 buffer_exists(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_exists(app, buffer_id));}
static b32 buffer_ready(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_ready(app, buffer_id));}
static Access_Flag buffer_get_access_flags(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_get_access_flags(app, buffer_id));}
@ -956,14 +1012,16 @@ static Panel_ID panel_get_max(Application_Links *app, Panel_ID panel_id){return(
static Rect_i32 panel_get_margin(Application_Links *app, Panel_ID panel_id){return(app->panel_get_margin(app, panel_id));}
static b32 view_close(Application_Links *app, View_ID view_id){return(app->view_close(app, view_id));}
static Rect_f32 view_get_buffer_region(Application_Links *app, View_ID view_id){return(app->view_get_buffer_region(app, view_id));}
static GUI_Scroll_Vars view_get_scroll_vars(Application_Links *app, View_ID view_id){return(app->view_get_scroll_vars(app, view_id));}
static Buffer_Scroll view_get_buffer_scroll(Application_Links *app, View_ID view_id){return(app->view_get_buffer_scroll(app, view_id));}
static Basic_Scroll view_get_basic_scroll(Application_Links *app, View_ID view_id){return(app->view_get_basic_scroll(app, view_id));}
static b32 view_set_active(Application_Links *app, View_ID view_id){return(app->view_set_active(app, view_id));}
static b32 view_get_setting(Application_Links *app, View_ID view_id, View_Setting_ID setting, i32 *value_out){return(app->view_get_setting(app, view_id, setting, value_out));}
static b32 view_set_setting(Application_Links *app, View_ID view_id, View_Setting_ID setting, i32 value){return(app->view_set_setting(app, view_id, setting, value));}
static Managed_Scope view_get_managed_scope(Application_Links *app, View_ID view_id){return(app->view_get_managed_scope(app, view_id));}
static Full_Cursor view_compute_cursor(Application_Links *app, View_ID view_id, Buffer_Seek seek){return(app->view_compute_cursor(app, view_id, seek));}
static Buffer_Cursor buffer_compute_cursor(Application_Links *app, Buffer_ID buffer, Buffer_Seek seek){return(app->buffer_compute_cursor(app, buffer, seek));}
static b32 view_set_cursor(Application_Links *app, View_ID view_id, Buffer_Seek seek, b32 set_preferred_x){return(app->view_set_cursor(app, view_id, seek, set_preferred_x));}
static b32 view_set_scroll(Application_Links *app, View_ID view_id, GUI_Scroll_Vars scroll){return(app->view_set_scroll(app, view_id, scroll));}
static b32 view_set_buffer_scroll(Application_Links *app, View_ID view_id, Buffer_Scroll scroll){return(app->view_set_buffer_scroll(app, view_id, scroll));}
static b32 view_set_basic_scroll(Application_Links *app, View_ID view_id, Basic_Scroll scroll){return(app->view_set_basic_scroll(app, view_id, scroll));}
static b32 view_set_mark(Application_Links *app, View_ID view_id, Buffer_Seek seek){return(app->view_set_mark(app, view_id, seek));}
static b32 view_set_buffer(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Set_Buffer_Flag flags){return(app->view_set_buffer(app, view_id, buffer_id, flags));}
static b32 view_post_fade(Application_Links *app, View_ID view_id, f32 seconds, Range_i64 range, int_color color){return(app->view_post_fade(app, view_id, seconds, range, color));}
@ -1047,21 +1105,17 @@ static void draw_clip_push(Application_Links *app, Rect_f32 clip_box){(app->draw
static f32_Rect draw_clip_pop(Application_Links *app){return(app->draw_clip_pop(app));}
static void draw_coordinate_center_push(Application_Links *app, Vec2 point){(app->draw_coordinate_center_push(app, point));}
static Vec2 draw_coordinate_center_pop(Application_Links *app){return(app->draw_coordinate_center_pop(app));}
static Text_Layout_ID text_layout_create(Application_Links *app, Buffer_ID buffer_id, Rect_f32 rect, Buffer_Point buffer_point){return(app->text_layout_create(app, buffer_id, rect, buffer_point));}
static b32 text_layout_get_buffer(Application_Links *app, Text_Layout_ID text_layout_id, Buffer_ID *buffer_id_out){return(app->text_layout_get_buffer(app, text_layout_id, buffer_id_out));}
static b32 text_layout_buffer_point_to_layout_point(Application_Links *app, Text_Layout_ID text_layout_id, Vec2 buffer_relative_p, Vec2 *p_out){return(app->text_layout_buffer_point_to_layout_point(app, text_layout_id, buffer_relative_p, p_out));}
static b32 text_layout_layout_point_to_buffer_point(Application_Links *app, Text_Layout_ID text_layout_id, Vec2 layout_relative_p, Vec2 *p_out){return(app->text_layout_layout_point_to_buffer_point(app, text_layout_id, layout_relative_p, p_out));}
static Range_i64 text_layout_get_on_screen_range(Application_Links *app, Text_Layout_ID text_layout_id){return(app->text_layout_get_on_screen_range(app, text_layout_id));}
static Rect_f32 text_layout_on_screen(Application_Links *app, Text_Layout_ID text_layout_id){return(app->text_layout_on_screen(app, text_layout_id));}
static Interval_i64 text_layout_get_visible_range(Application_Links *app, Text_Layout_ID text_layout_id){return(app->text_layout_get_visible_range(app, text_layout_id));}
static Rect_f32 text_layout_line_on_screen(Application_Links *app, Text_Layout_ID layout_id, i64 line_number){return(app->text_layout_line_on_screen(app, layout_id, line_number));}
static Rect_f32 text_layout_character_on_screen(Application_Links *app, Text_Layout_ID layout_id, i64 pos){return(app->text_layout_character_on_screen(app, layout_id, pos));}
static void paint_text_color(Application_Links *app, Text_Layout_ID layout_id, Range_i64 range, int_color color){(app->paint_text_color(app, layout_id, range, color));}
static void paint_text_color(Application_Links *app, Text_Layout_ID layout_id, Interval_i64 range, int_color color){(app->paint_text_color(app, layout_id, range, color));}
static b32 text_layout_free(Application_Links *app, Text_Layout_ID text_layout_id){return(app->text_layout_free(app, text_layout_id));}
static Text_Layout_ID compute_render_layout(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Vec2 screen_p, Vec2 layout_dim, Buffer_Point buffer_point, i32 one_past_last){return(app->compute_render_layout(app, view_id, buffer_id, screen_p, layout_dim, buffer_point, one_past_last));}
static void draw_render_layout(Application_Links *app, View_ID view_id){(app->draw_render_layout(app, view_id));}
static void draw_text_layout(Application_Links *app, Text_Layout_ID layout_id){(app->draw_text_layout(app, layout_id));}
static void open_color_picker(Application_Links *app, Color_Picker *picker){(app->open_color_picker(app, picker));}
static void animate_in_n_milliseconds(Application_Links *app, u32 n){(app->animate_in_n_milliseconds(app, n));}
static String_Match_List buffer_find_all_matches(Application_Links *app, Arena *arena, Buffer_ID buffer, i32 string_id, Range_i64 range, String_Const_u8 needle, Character_Predicate *predicate, Scan_Direction direction){return(app->buffer_find_all_matches(app, arena, buffer, string_id, range, needle, predicate, direction));}
static Range get_view_visible_range(Application_Links *app, View_ID view_id){return(app->get_view_visible_range(app, view_id));}
#else
static b32 global_set_setting(Application_Links *app, Global_Setting_ID setting, i32 value){return(app->global_set_setting_(app, setting, value));}
static b32 global_set_mapping(Application_Links *app, void *data, i32 size){return(app->global_set_mapping_(app, data, size));}
@ -1083,10 +1137,21 @@ static Buffer_ID get_buffer_by_name(Application_Links *app, String_Const_u8 name
static Buffer_ID get_buffer_by_file_name(Application_Links *app, String_Const_u8 file_name, Access_Flag access){return(app->get_buffer_by_file_name_(app, file_name, access));}
static b32 buffer_read_range(Application_Links *app, Buffer_ID buffer_id, Range_i64 range, char *out){return(app->buffer_read_range_(app, buffer_id, range, out));}
static b32 buffer_replace_range(Application_Links *app, Buffer_ID buffer_id, Range_i64 range, String_Const_u8 string){return(app->buffer_replace_range_(app, buffer_id, range, string));}
static b32 buffer_batch_edit(Application_Links *app, Buffer_ID buffer_id, char *str, Buffer_Edit *edits, i32 edit_count){return(app->buffer_batch_edit_(app, buffer_id, str, edits, edit_count));}
static b32 buffer_batch_edit(Application_Links *app, Buffer_ID buffer_id, Batch_Edit *batch){return(app->buffer_batch_edit_(app, buffer_id, batch));}
static String_Match buffer_seek_string(Application_Links *app, Buffer_ID buffer, String_Const_u8 needle, Scan_Direction direction, i64 start_pos){return(app->buffer_seek_string_(app, buffer, needle, direction, start_pos));}
static String_Match buffer_seek_character_class(Application_Links *app, Buffer_ID buffer, Character_Predicate *predicate, Scan_Direction direction, i64 start_pos){return(app->buffer_seek_character_class_(app, buffer, predicate, direction, start_pos));}
static Partial_Cursor buffer_compute_cursor(Application_Links *app, Buffer_ID buffer_id, Buffer_Seek seek){return(app->buffer_compute_cursor_(app, buffer_id, seek));}
static f32 buffer_line_y_difference(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 line_a, i64 line_b){return(app->buffer_line_y_difference_(app, buffer_id, width, face_id, line_a, line_b));}
static Line_Shift_Vertical buffer_line_shift_y(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 line, f32 y_shift){return(app->buffer_line_shift_y_(app, buffer_id, width, face_id, line, y_shift));}
static i64 buffer_pos_at_relative_xy(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, Vec2_f32 relative_xy){return(app->buffer_pos_at_relative_xy_(app, buffer_id, width, face_id, base_line, relative_xy));}
static Vec2_f32 buffer_relative_xy_of_pos(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos){return(app->buffer_relative_xy_of_pos_(app, buffer_id, width, face_id, base_line, pos));}
static i64 buffer_relative_character_from_pos(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos){return(app->buffer_relative_character_from_pos_(app, buffer_id, width, face_id, base_line, pos));}
static i64 buffer_pos_from_relative_character(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 relative_character){return(app->buffer_pos_from_relative_character_(app, buffer_id, width, face_id, base_line, relative_character));}
static f32 view_line_y_difference(Application_Links *app, View_ID view_id, i64 line_a, i64 line_b){return(app->view_line_y_difference_(app, view_id, line_a, line_b));}
static Line_Shift_Vertical view_line_shift_y(Application_Links *app, View_ID view_id, i64 line, f32 y_shift){return(app->view_line_shift_y_(app, view_id, line, y_shift));}
static i64 view_pos_at_relative_xy(Application_Links *app, View_ID view_id, i64 base_line, Vec2_f32 relative_xy){return(app->view_pos_at_relative_xy_(app, view_id, base_line, relative_xy));}
static Vec2_f32 view_relative_xy_of_pos(Application_Links *app, View_ID view_id, i64 base_line, i64 pos){return(app->view_relative_xy_of_pos_(app, view_id, base_line, pos));}
static i64 view_relative_character_from_pos(Application_Links *app, View_ID view_id, i64 base_line, i64 pos){return(app->view_relative_character_from_pos_(app, view_id, base_line, pos));}
static i64 view_pos_from_relative_character(Application_Links *app, View_ID view_id, i64 base_line, i64 character){return(app->view_pos_from_relative_character_(app, view_id, base_line, character));}
static b32 buffer_exists(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_exists_(app, buffer_id));}
static b32 buffer_ready(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_ready_(app, buffer_id));}
static Access_Flag buffer_get_access_flags(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_get_access_flags_(app, buffer_id));}
@ -1132,14 +1197,16 @@ static Panel_ID panel_get_max(Application_Links *app, Panel_ID panel_id){return(
static Rect_i32 panel_get_margin(Application_Links *app, Panel_ID panel_id){return(app->panel_get_margin_(app, panel_id));}
static b32 view_close(Application_Links *app, View_ID view_id){return(app->view_close_(app, view_id));}
static Rect_f32 view_get_buffer_region(Application_Links *app, View_ID view_id){return(app->view_get_buffer_region_(app, view_id));}
static GUI_Scroll_Vars view_get_scroll_vars(Application_Links *app, View_ID view_id){return(app->view_get_scroll_vars_(app, view_id));}
static Buffer_Scroll view_get_buffer_scroll(Application_Links *app, View_ID view_id){return(app->view_get_buffer_scroll_(app, view_id));}
static Basic_Scroll view_get_basic_scroll(Application_Links *app, View_ID view_id){return(app->view_get_basic_scroll_(app, view_id));}
static b32 view_set_active(Application_Links *app, View_ID view_id){return(app->view_set_active_(app, view_id));}
static b32 view_get_setting(Application_Links *app, View_ID view_id, View_Setting_ID setting, i32 *value_out){return(app->view_get_setting_(app, view_id, setting, value_out));}
static b32 view_set_setting(Application_Links *app, View_ID view_id, View_Setting_ID setting, i32 value){return(app->view_set_setting_(app, view_id, setting, value));}
static Managed_Scope view_get_managed_scope(Application_Links *app, View_ID view_id){return(app->view_get_managed_scope_(app, view_id));}
static Full_Cursor view_compute_cursor(Application_Links *app, View_ID view_id, Buffer_Seek seek){return(app->view_compute_cursor_(app, view_id, seek));}
static Buffer_Cursor buffer_compute_cursor(Application_Links *app, Buffer_ID buffer, Buffer_Seek seek){return(app->buffer_compute_cursor_(app, buffer, seek));}
static b32 view_set_cursor(Application_Links *app, View_ID view_id, Buffer_Seek seek, b32 set_preferred_x){return(app->view_set_cursor_(app, view_id, seek, set_preferred_x));}
static b32 view_set_scroll(Application_Links *app, View_ID view_id, GUI_Scroll_Vars scroll){return(app->view_set_scroll_(app, view_id, scroll));}
static b32 view_set_buffer_scroll(Application_Links *app, View_ID view_id, Buffer_Scroll scroll){return(app->view_set_buffer_scroll_(app, view_id, scroll));}
static b32 view_set_basic_scroll(Application_Links *app, View_ID view_id, Basic_Scroll scroll){return(app->view_set_basic_scroll_(app, view_id, scroll));}
static b32 view_set_mark(Application_Links *app, View_ID view_id, Buffer_Seek seek){return(app->view_set_mark_(app, view_id, seek));}
static b32 view_set_buffer(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Set_Buffer_Flag flags){return(app->view_set_buffer_(app, view_id, buffer_id, flags));}
static b32 view_post_fade(Application_Links *app, View_ID view_id, f32 seconds, Range_i64 range, int_color color){return(app->view_post_fade_(app, view_id, seconds, range, color));}
@ -1223,19 +1290,15 @@ static void draw_clip_push(Application_Links *app, Rect_f32 clip_box){(app->draw
static f32_Rect draw_clip_pop(Application_Links *app){return(app->draw_clip_pop_(app));}
static void draw_coordinate_center_push(Application_Links *app, Vec2 point){(app->draw_coordinate_center_push_(app, point));}
static Vec2 draw_coordinate_center_pop(Application_Links *app){return(app->draw_coordinate_center_pop_(app));}
static Text_Layout_ID text_layout_create(Application_Links *app, Buffer_ID buffer_id, Rect_f32 rect, Buffer_Point buffer_point){return(app->text_layout_create_(app, buffer_id, rect, buffer_point));}
static b32 text_layout_get_buffer(Application_Links *app, Text_Layout_ID text_layout_id, Buffer_ID *buffer_id_out){return(app->text_layout_get_buffer_(app, text_layout_id, buffer_id_out));}
static b32 text_layout_buffer_point_to_layout_point(Application_Links *app, Text_Layout_ID text_layout_id, Vec2 buffer_relative_p, Vec2 *p_out){return(app->text_layout_buffer_point_to_layout_point_(app, text_layout_id, buffer_relative_p, p_out));}
static b32 text_layout_layout_point_to_buffer_point(Application_Links *app, Text_Layout_ID text_layout_id, Vec2 layout_relative_p, Vec2 *p_out){return(app->text_layout_layout_point_to_buffer_point_(app, text_layout_id, layout_relative_p, p_out));}
static Range_i64 text_layout_get_on_screen_range(Application_Links *app, Text_Layout_ID text_layout_id){return(app->text_layout_get_on_screen_range_(app, text_layout_id));}
static Rect_f32 text_layout_on_screen(Application_Links *app, Text_Layout_ID text_layout_id){return(app->text_layout_on_screen_(app, text_layout_id));}
static Interval_i64 text_layout_get_visible_range(Application_Links *app, Text_Layout_ID text_layout_id){return(app->text_layout_get_visible_range_(app, text_layout_id));}
static Rect_f32 text_layout_line_on_screen(Application_Links *app, Text_Layout_ID layout_id, i64 line_number){return(app->text_layout_line_on_screen_(app, layout_id, line_number));}
static Rect_f32 text_layout_character_on_screen(Application_Links *app, Text_Layout_ID layout_id, i64 pos){return(app->text_layout_character_on_screen_(app, layout_id, pos));}
static void paint_text_color(Application_Links *app, Text_Layout_ID layout_id, Range_i64 range, int_color color){(app->paint_text_color_(app, layout_id, range, color));}
static void paint_text_color(Application_Links *app, Text_Layout_ID layout_id, Interval_i64 range, int_color color){(app->paint_text_color_(app, layout_id, range, color));}
static b32 text_layout_free(Application_Links *app, Text_Layout_ID text_layout_id){return(app->text_layout_free_(app, text_layout_id));}
static Text_Layout_ID compute_render_layout(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Vec2 screen_p, Vec2 layout_dim, Buffer_Point buffer_point, i32 one_past_last){return(app->compute_render_layout_(app, view_id, buffer_id, screen_p, layout_dim, buffer_point, one_past_last));}
static void draw_render_layout(Application_Links *app, View_ID view_id){(app->draw_render_layout_(app, view_id));}
static void draw_text_layout(Application_Links *app, Text_Layout_ID layout_id){(app->draw_text_layout_(app, layout_id));}
static void open_color_picker(Application_Links *app, Color_Picker *picker){(app->open_color_picker_(app, picker));}
static void animate_in_n_milliseconds(Application_Links *app, u32 n){(app->animate_in_n_milliseconds_(app, n));}
static String_Match_List buffer_find_all_matches(Application_Links *app, Arena *arena, Buffer_ID buffer, i32 string_id, Range_i64 range, String_Const_u8 needle, Character_Predicate *predicate, Scan_Direction direction){return(app->buffer_find_all_matches_(app, arena, buffer, string_id, range, needle, predicate, direction));}
static Range get_view_visible_range(Application_Links *app, View_ID view_id){return(app->get_view_visible_range_(app, view_id));}
#endif

View File

@ -2,7 +2,7 @@
#define command_id(c) (fcoder_metacmd_ID_##c)
#define command_metadata(c) (&fcoder_metacmd_table[command_id(c)])
#define command_metadata_by_id(id) (&fcoder_metacmd_table[id])
#define command_one_past_last_id 235
#define command_one_past_last_id 233
#if defined(CUSTOM_COMMAND_SIG)
#define PROC_LINKS(x,y) x
#else
@ -240,8 +240,6 @@ CUSTOM_COMMAND_SIG(miblo_increment_time_stamp);
CUSTOM_COMMAND_SIG(miblo_decrement_time_stamp);
CUSTOM_COMMAND_SIG(miblo_increment_time_stamp_minute);
CUSTOM_COMMAND_SIG(miblo_decrement_time_stamp_minute);
CUSTOM_COMMAND_SIG(kill_rect);
CUSTOM_COMMAND_SIG(multi_line_edit);
CUSTOM_COMMAND_SIG(rename_parameter);
CUSTOM_COMMAND_SIG(write_explicit_enum_values);
#endif
@ -255,14 +253,14 @@ char *source_name;
int32_t source_name_len;
int32_t line_number;
};
static Command_Metadata fcoder_metacmd_table[235] = {
{ 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, "w:\\4ed\\code\\4coder_experiments.cpp", 34, 699 },
{ PROC_LINKS(seek_beginning_of_textual_line, 0), "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "w:\\4ed\\code\\4coder_seek.cpp", 27, 28 },
{ PROC_LINKS(seek_end_of_textual_line, 0), "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "w:\\4ed\\code\\4coder_seek.cpp", 27, 34 },
{ PROC_LINKS(seek_beginning_of_line, 0), "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "w:\\4ed\\code\\4coder_seek.cpp", 27, 40 },
{ PROC_LINKS(seek_end_of_line, 0), "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "w:\\4ed\\code\\4coder_seek.cpp", 27, 46 },
{ PROC_LINKS(goto_beginning_of_file, 0), "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "w:\\4ed\\code\\4coder_seek.cpp", 27, 52 },
{ PROC_LINKS(goto_end_of_file, 0), "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "w:\\4ed\\code\\4coder_seek.cpp", 27, 60 },
static Command_Metadata fcoder_metacmd_table[233] = {
{ 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, "w:\\4ed\\code\\4coder_experiments.cpp", 34, 504 },
{ PROC_LINKS(seek_beginning_of_textual_line, 0), "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "w:\\4ed\\code\\4coder_seek.cpp", 27, 29 },
{ PROC_LINKS(seek_end_of_textual_line, 0), "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "w:\\4ed\\code\\4coder_seek.cpp", 27, 35 },
{ PROC_LINKS(seek_beginning_of_line, 0), "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "w:\\4ed\\code\\4coder_seek.cpp", 27, 41 },
{ PROC_LINKS(seek_end_of_line, 0), "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "w:\\4ed\\code\\4coder_seek.cpp", 27, 47 },
{ PROC_LINKS(goto_beginning_of_file, 0), "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "w:\\4ed\\code\\4coder_seek.cpp", 27, 53 },
{ PROC_LINKS(goto_end_of_file, 0), "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "w:\\4ed\\code\\4coder_seek.cpp", 27, 61 },
{ PROC_LINKS(change_active_panel, 0), "change_active_panel", 19, "Change the currently active panel, moving to the panel with the next highest view_id.", 85, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 201 },
{ PROC_LINKS(change_active_panel_backwards, 0), "change_active_panel_backwards", 29, "Change the currently active panel, moving to the panel with the next lowest view_id.", 84, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 211 },
{ PROC_LINKS(open_panel_vsplit, 0), "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 221 },
@ -277,105 +275,105 @@ static Command_Metadata fcoder_metacmd_table[235] = {
{ PROC_LINKS(toggle_paren_matching_helper, 0), "toggle_paren_matching_helper", 28, "In code files matching parentheses pairs are colored with distinguishing colors.", 80, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 334 },
{ PROC_LINKS(toggle_fullscreen, 0), "toggle_fullscreen", 17, "Toggle fullscreen mode on or off. The change(s) do not take effect until the next frame.", 89, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 340 },
{ PROC_LINKS(remap_interactive, 0), "remap_interactive", 17, "Switch to a named key binding map.", 34, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 348 },
{ PROC_LINKS(write_character, 0), "write_character", 15, "Inserts whatever character was used to trigger this command.", 60, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 66 },
{ PROC_LINKS(write_underscore, 0), "write_underscore", 16, "Inserts an underscore.", 22, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 75 },
{ PROC_LINKS(delete_char, 0), "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 82 },
{ PROC_LINKS(backspace_char, 0), "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 99 },
{ PROC_LINKS(set_mark, 0), "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 118 },
{ PROC_LINKS(cursor_mark_swap, 0), "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 127 },
{ PROC_LINKS(delete_range, 0), "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 137 },
{ PROC_LINKS(backspace_alpha_numeric_boundary, 0), "backspace_alpha_numeric_boundary", 32, "Delete characters between the cursor position and the first alphanumeric boundary to the left.", 94, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 157 },
{ PROC_LINKS(delete_alpha_numeric_boundary, 0), "delete_alpha_numeric_boundary", 29, "Delete characters between the cursor position and the first alphanumeric boundary to the right.", 95, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 165 },
{ PROC_LINKS(snipe_backward_whitespace_or_token_boundary, 0), "snipe_backward_whitespace_or_token_boundary", 43, "Delete a single, whole token on or to the left of the cursor and post it to the clipboard.", 90, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 185 },
{ PROC_LINKS(snipe_forward_whitespace_or_token_boundary, 0), "snipe_forward_whitespace_or_token_boundary", 42, "Delete a single, whole token on or to the right of the cursor and post it to the clipboard.", 91, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 193 },
{ PROC_LINKS(center_view, 0), "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 206 },
{ PROC_LINKS(left_adjust_view, 0), "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 221 },
{ PROC_LINKS(click_set_cursor_and_mark, 0), "click_set_cursor_and_mark", 25, "Sets the cursor position and mark to the mouse position.", 56, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 244 },
{ PROC_LINKS(click_set_cursor, 0), "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 259 },
{ PROC_LINKS(click_set_cursor_if_lbutton, 0), "click_set_cursor_if_lbutton", 27, "If the mouse left button is pressed, sets the cursor position to the mouse position.", 84, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 273 },
{ PROC_LINKS(click_set_mark, 0), "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 289 },
{ PROC_LINKS(mouse_wheel_scroll, 0), "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 303 },
{ PROC_LINKS(move_up, 0), "move_up", 7, "Moves the cursor up one line.", 29, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 370 },
{ PROC_LINKS(move_down, 0), "move_down", 9, "Moves the cursor down one line.", 31, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 376 },
{ PROC_LINKS(move_up_10, 0), "move_up_10", 10, "Moves the cursor up ten lines.", 30, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 382 },
{ PROC_LINKS(move_down_10, 0), "move_down_10", 12, "Moves the cursor down ten lines.", 32, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 388 },
{ PROC_LINKS(move_down_textual, 0), "move_down_textual", 17, "Moves down to the next line of actual text, regardless of line wrapping.", 72, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 394 },
{ PROC_LINKS(page_up, 0), "page_up", 7, "Scrolls the view up one view height and moves the cursor up one view height.", 76, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 404 },
{ PROC_LINKS(page_down, 0), "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 412 },
{ PROC_LINKS(move_up_to_blank_line, 0), "move_up_to_blank_line", 21, "Seeks the cursor up to the next blank line.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 441 },
{ PROC_LINKS(move_down_to_blank_line, 0), "move_down_to_blank_line", 23, "Seeks the cursor down to the next blank line.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 447 },
{ PROC_LINKS(move_up_to_blank_line_skip_whitespace, 0), "move_up_to_blank_line_skip_whitespace", 37, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 453 },
{ PROC_LINKS(move_down_to_blank_line_skip_whitespace, 0), "move_down_to_blank_line_skip_whitespace", 39, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 459 },
{ PROC_LINKS(move_up_to_blank_line_end, 0), "move_up_to_blank_line_end", 25, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 465 },
{ PROC_LINKS(move_down_to_blank_line_end, 0), "move_down_to_blank_line_end", 27, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 471 },
{ PROC_LINKS(move_left, 0), "move_left", 9, "Moves the cursor one character to the left.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 482 },
{ PROC_LINKS(move_right, 0), "move_right", 10, "Moves the cursor one character to the right.", 44, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 493 },
{ PROC_LINKS(move_right_whitespace_boundary, 0), "move_right_whitespace_boundary", 30, "Seek right for the next boundary between whitespace and non-whitespace.", 71, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 514 },
{ PROC_LINKS(move_left_whitespace_boundary, 0), "move_left_whitespace_boundary", 29, "Seek left for the next boundary between whitespace and non-whitespace.", 70, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 522 },
{ PROC_LINKS(move_right_token_boundary, 0), "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 530 },
{ PROC_LINKS(move_left_token_boundary, 0), "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 538 },
{ PROC_LINKS(move_right_whitespace_or_token_boundary, 0), "move_right_whitespace_or_token_boundary", 39, "Seek right for the next end of a token or boundary between whitespace and non-whitespace.", 89, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 546 },
{ PROC_LINKS(move_left_whitespace_or_token_boundary, 0), "move_left_whitespace_or_token_boundary", 38, "Seek left for the next end of a token or boundary between whitespace and non-whitespace.", 88, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 554 },
{ PROC_LINKS(move_right_alpha_numeric_boundary, 0), "move_right_alpha_numeric_boundary", 33, "Seek right for boundary between alphanumeric characters and non-alphanumeric characters.", 88, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 562 },
{ PROC_LINKS(move_left_alpha_numeric_boundary, 0), "move_left_alpha_numeric_boundary", 32, "Seek left for boundary between alphanumeric characters and non-alphanumeric characters.", 87, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 570 },
{ PROC_LINKS(move_right_alpha_numeric_or_camel_boundary, 0), "move_right_alpha_numeric_or_camel_boundary", 42, "Seek right for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 107, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 578 },
{ PROC_LINKS(move_left_alpha_numeric_or_camel_boundary, 0), "move_left_alpha_numeric_or_camel_boundary", 41, "Seek left for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 106, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 586 },
{ PROC_LINKS(select_all, 0), "select_all", 10, "Puts the cursor at the top of the file, and the mark at the bottom of the file.", 79, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 607 },
{ PROC_LINKS(to_uppercase, 0), "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 620 },
{ PROC_LINKS(to_lowercase, 0), "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 633 },
{ PROC_LINKS(clean_all_lines, 0), "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 646 },
{ PROC_LINKS(basic_change_active_panel, 0), "basic_change_active_panel", 25, "Change the currently active panel, moving to the panel with the next highest view_id. Will not skipe the build panel if it is open.", 132, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 684 },
{ PROC_LINKS(close_panel, 0), "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 692 },
{ PROC_LINKS(show_scrollbar, 0), "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 701 },
{ PROC_LINKS(hide_scrollbar, 0), "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 708 },
{ PROC_LINKS(show_filebar, 0), "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 715 },
{ PROC_LINKS(hide_filebar, 0), "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 722 },
{ PROC_LINKS(toggle_filebar, 0), "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 729 },
{ PROC_LINKS(toggle_line_wrap, 0), "toggle_line_wrap", 16, "Toggles the current buffer's line wrapping status.", 50, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 738 },
{ PROC_LINKS(toggle_fps_meter, 0), "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 748 },
{ PROC_LINKS(increase_line_wrap, 0), "increase_line_wrap", 18, "Increases the current buffer's width for line wrapping.", 55, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 754 },
{ PROC_LINKS(decrease_line_wrap, 0), "decrease_line_wrap", 18, "Decrases the current buffer's width for line wrapping.", 54, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 764 },
{ PROC_LINKS(increase_face_size, 0), "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 774 },
{ PROC_LINKS(decrease_face_size, 0), "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 785 },
{ PROC_LINKS(mouse_wheel_change_face_size, 0), "mouse_wheel_change_face_size", 28, "Reads the state of the mouse wheel and uses it to either increase or decrease the face size.", 92, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 796 },
{ PROC_LINKS(toggle_virtual_whitespace, 0), "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 813 },
{ PROC_LINKS(toggle_show_whitespace, 0), "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 823 },
{ PROC_LINKS(toggle_line_numbers, 0), "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 832 },
{ PROC_LINKS(eol_dosify, 0), "eol_dosify", 10, "Puts the buffer in DOS line ending mode.", 40, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 838 },
{ PROC_LINKS(eol_nixify, 0), "eol_nixify", 10, "Puts the buffer in NIX line ending mode.", 40, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 846 },
{ PROC_LINKS(exit_4coder, 0), "exit_4coder", 11, "Attempts to close 4coder.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 854 },
{ PROC_LINKS(goto_line, 0), "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 862 },
{ PROC_LINKS(search, 0), "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1073 },
{ PROC_LINKS(reverse_search, 0), "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1079 },
{ PROC_LINKS(search_identifier, 0), "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1085 },
{ PROC_LINKS(reverse_search_identifier, 0), "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1096 },
{ PROC_LINKS(replace_in_range, 0), "replace_in_range", 16, "Queries the user for a needle and string. Replaces all occurences of needle with string in the range between cursor and the mark in the active buffer.", 150, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1147 },
{ PROC_LINKS(replace_in_buffer, 0), "replace_in_buffer", 17, "Queries the user for a needle and string. Replaces all occurences of needle with string in the active buffer.", 109, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1156 },
{ PROC_LINKS(replace_in_all_buffers, 0), "replace_in_all_buffers", 22, "Queries the user for a needle and string. Replaces all occurences of needle with string in all editable buffers.", 112, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1165 },
{ PROC_LINKS(query_replace, 0), "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1253 },
{ PROC_LINKS(query_replace_identifier, 0), "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1273 },
{ PROC_LINKS(query_replace_selection, 0), "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1289 },
{ PROC_LINKS(save_all_dirty_buffers, 0), "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1324 },
{ PROC_LINKS(delete_file_query, 0), "delete_file_query", 17, "Deletes the file of the current buffer if 4coder has the appropriate access rights. Will ask the user for confirmation first.", 125, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1349 },
{ PROC_LINKS(save_to_query, 0), "save_to_query", 13, "Queries the user for a file name and saves the contents of the current buffer, altering the buffer's name too.", 110, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1387 },
{ PROC_LINKS(rename_file_query, 0), "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1422 },
{ PROC_LINKS(make_directory_query, 0), "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1462 },
{ PROC_LINKS(move_line_up, 0), "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1495 },
{ PROC_LINKS(move_line_down, 0), "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1501 },
{ PROC_LINKS(duplicate_line, 0), "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1507 },
{ PROC_LINKS(delete_line, 0), "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1521 },
{ PROC_LINKS(open_file_in_quotes, 0), "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1586 },
{ PROC_LINKS(open_matching_file_cpp, 0), "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1618 },
{ PROC_LINKS(view_buffer_other_panel, 0), "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1631 },
{ PROC_LINKS(swap_buffers_between_panels, 0), "swap_buffers_between_panels", 27, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1643 },
{ PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1677 },
{ PROC_LINKS(save, 0), "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1685 },
{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1697 },
{ PROC_LINKS(undo, 0), "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1755 },
{ PROC_LINKS(redo, 0), "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1768 },
{ PROC_LINKS(undo_all_buffers, 0), "undo_all_buffers", 16, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1782 },
{ PROC_LINKS(redo_all_buffers, 0), "redo_all_buffers", 16, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1856 },
{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1959 },
{ PROC_LINKS(write_character, 0), "write_character", 15, "Inserts whatever character was used to trigger this command.", 60, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 57 },
{ PROC_LINKS(write_underscore, 0), "write_underscore", 16, "Inserts an underscore.", 22, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 66 },
{ PROC_LINKS(delete_char, 0), "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 73 },
{ PROC_LINKS(backspace_char, 0), "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 90 },
{ PROC_LINKS(set_mark, 0), "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 109 },
{ PROC_LINKS(cursor_mark_swap, 0), "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 118 },
{ PROC_LINKS(delete_range, 0), "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 128 },
{ PROC_LINKS(backspace_alpha_numeric_boundary, 0), "backspace_alpha_numeric_boundary", 32, "Delete characters between the cursor position and the first alphanumeric boundary to the left.", 94, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 148 },
{ PROC_LINKS(delete_alpha_numeric_boundary, 0), "delete_alpha_numeric_boundary", 29, "Delete characters between the cursor position and the first alphanumeric boundary to the right.", 95, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 156 },
{ PROC_LINKS(snipe_backward_whitespace_or_token_boundary, 0), "snipe_backward_whitespace_or_token_boundary", 43, "Delete a single, whole token on or to the left of the cursor and post it to the clipboard.", 90, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 176 },
{ PROC_LINKS(snipe_forward_whitespace_or_token_boundary, 0), "snipe_forward_whitespace_or_token_boundary", 42, "Delete a single, whole token on or to the right of the cursor and post it to the clipboard.", 91, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 184 },
{ PROC_LINKS(center_view, 0), "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 197 },
{ PROC_LINKS(left_adjust_view, 0), "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 211 },
{ PROC_LINKS(click_set_cursor_and_mark, 0), "click_set_cursor_and_mark", 25, "Sets the cursor position and mark to the mouse position.", 56, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 223 },
{ PROC_LINKS(click_set_cursor, 0), "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 235 },
{ PROC_LINKS(click_set_cursor_if_lbutton, 0), "click_set_cursor_if_lbutton", 27, "If the mouse left button is pressed, sets the cursor position to the mouse position.", 84, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 247 },
{ PROC_LINKS(click_set_mark, 0), "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 261 },
{ PROC_LINKS(mouse_wheel_scroll, 0), "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 273 },
{ PROC_LINKS(move_up, 0), "move_up", 7, "Moves the cursor up one line.", 29, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 335 },
{ PROC_LINKS(move_down, 0), "move_down", 9, "Moves the cursor down one line.", 31, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 341 },
{ PROC_LINKS(move_up_10, 0), "move_up_10", 10, "Moves the cursor up ten lines.", 30, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 347 },
{ PROC_LINKS(move_down_10, 0), "move_down_10", 12, "Moves the cursor down ten lines.", 32, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 353 },
{ PROC_LINKS(move_down_textual, 0), "move_down_textual", 17, "Moves down to the next line of actual text, regardless of line wrapping.", 72, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 359 },
{ PROC_LINKS(page_up, 0), "page_up", 7, "Scrolls the view up one view height and moves the cursor up one view height.", 76, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 369 },
{ PROC_LINKS(page_down, 0), "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 377 },
{ PROC_LINKS(move_up_to_blank_line, 0), "move_up_to_blank_line", 21, "Seeks the cursor up to the next blank line.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 406 },
{ PROC_LINKS(move_down_to_blank_line, 0), "move_down_to_blank_line", 23, "Seeks the cursor down to the next blank line.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 412 },
{ PROC_LINKS(move_up_to_blank_line_skip_whitespace, 0), "move_up_to_blank_line_skip_whitespace", 37, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 418 },
{ PROC_LINKS(move_down_to_blank_line_skip_whitespace, 0), "move_down_to_blank_line_skip_whitespace", 39, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 424 },
{ PROC_LINKS(move_up_to_blank_line_end, 0), "move_up_to_blank_line_end", 25, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 430 },
{ PROC_LINKS(move_down_to_blank_line_end, 0), "move_down_to_blank_line_end", 27, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 436 },
{ PROC_LINKS(move_left, 0), "move_left", 9, "Moves the cursor one character to the left.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 447 },
{ PROC_LINKS(move_right, 0), "move_right", 10, "Moves the cursor one character to the right.", 44, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 459 },
{ PROC_LINKS(move_right_whitespace_boundary, 0), "move_right_whitespace_boundary", 30, "Seek right for the next boundary between whitespace and non-whitespace.", 71, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 481 },
{ PROC_LINKS(move_left_whitespace_boundary, 0), "move_left_whitespace_boundary", 29, "Seek left for the next boundary between whitespace and non-whitespace.", 70, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 489 },
{ PROC_LINKS(move_right_token_boundary, 0), "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 497 },
{ PROC_LINKS(move_left_token_boundary, 0), "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 505 },
{ PROC_LINKS(move_right_whitespace_or_token_boundary, 0), "move_right_whitespace_or_token_boundary", 39, "Seek right for the next end of a token or boundary between whitespace and non-whitespace.", 89, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 513 },
{ PROC_LINKS(move_left_whitespace_or_token_boundary, 0), "move_left_whitespace_or_token_boundary", 38, "Seek left for the next end of a token or boundary between whitespace and non-whitespace.", 88, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 521 },
{ PROC_LINKS(move_right_alpha_numeric_boundary, 0), "move_right_alpha_numeric_boundary", 33, "Seek right for boundary between alphanumeric characters and non-alphanumeric characters.", 88, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 529 },
{ PROC_LINKS(move_left_alpha_numeric_boundary, 0), "move_left_alpha_numeric_boundary", 32, "Seek left for boundary between alphanumeric characters and non-alphanumeric characters.", 87, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 537 },
{ PROC_LINKS(move_right_alpha_numeric_or_camel_boundary, 0), "move_right_alpha_numeric_or_camel_boundary", 42, "Seek right for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 107, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 545 },
{ PROC_LINKS(move_left_alpha_numeric_or_camel_boundary, 0), "move_left_alpha_numeric_or_camel_boundary", 41, "Seek left for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 106, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 553 },
{ PROC_LINKS(select_all, 0), "select_all", 10, "Puts the cursor at the top of the file, and the mark at the bottom of the file.", 79, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 574 },
{ PROC_LINKS(to_uppercase, 0), "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 587 },
{ PROC_LINKS(to_lowercase, 0), "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 600 },
{ PROC_LINKS(clean_all_lines, 0), "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 613 },
{ PROC_LINKS(basic_change_active_panel, 0), "basic_change_active_panel", 25, "Change the currently active panel, moving to the panel with the next highest view_id. Will not skipe the build panel if it is open.", 132, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 647 },
{ PROC_LINKS(close_panel, 0), "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 655 },
{ PROC_LINKS(show_scrollbar, 0), "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 664 },
{ PROC_LINKS(hide_scrollbar, 0), "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 671 },
{ PROC_LINKS(show_filebar, 0), "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 678 },
{ PROC_LINKS(hide_filebar, 0), "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 685 },
{ PROC_LINKS(toggle_filebar, 0), "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 692 },
{ PROC_LINKS(toggle_line_wrap, 0), "toggle_line_wrap", 16, "Toggles the current buffer's line wrapping status.", 50, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 701 },
{ PROC_LINKS(toggle_fps_meter, 0), "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 711 },
{ PROC_LINKS(increase_line_wrap, 0), "increase_line_wrap", 18, "Increases the current buffer's width for line wrapping.", 55, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 717 },
{ PROC_LINKS(decrease_line_wrap, 0), "decrease_line_wrap", 18, "Decrases the current buffer's width for line wrapping.", 54, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 727 },
{ PROC_LINKS(increase_face_size, 0), "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 737 },
{ PROC_LINKS(decrease_face_size, 0), "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 748 },
{ PROC_LINKS(mouse_wheel_change_face_size, 0), "mouse_wheel_change_face_size", 28, "Reads the state of the mouse wheel and uses it to either increase or decrease the face size.", 92, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 759 },
{ PROC_LINKS(toggle_virtual_whitespace, 0), "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 776 },
{ PROC_LINKS(toggle_show_whitespace, 0), "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 786 },
{ PROC_LINKS(toggle_line_numbers, 0), "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 795 },
{ PROC_LINKS(eol_dosify, 0), "eol_dosify", 10, "Puts the buffer in DOS line ending mode.", 40, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 801 },
{ PROC_LINKS(eol_nixify, 0), "eol_nixify", 10, "Puts the buffer in NIX line ending mode.", 40, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 809 },
{ PROC_LINKS(exit_4coder, 0), "exit_4coder", 11, "Attempts to close 4coder.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 817 },
{ PROC_LINKS(goto_line, 0), "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 825 },
{ PROC_LINKS(search, 0), "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1036 },
{ PROC_LINKS(reverse_search, 0), "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1042 },
{ PROC_LINKS(search_identifier, 0), "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1048 },
{ PROC_LINKS(reverse_search_identifier, 0), "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1059 },
{ PROC_LINKS(replace_in_range, 0), "replace_in_range", 16, "Queries the user for a needle and string. Replaces all occurences of needle with string in the range between cursor and the mark in the active buffer.", 150, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1110 },
{ PROC_LINKS(replace_in_buffer, 0), "replace_in_buffer", 17, "Queries the user for a needle and string. Replaces all occurences of needle with string in the active buffer.", 109, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1119 },
{ PROC_LINKS(replace_in_all_buffers, 0), "replace_in_all_buffers", 22, "Queries the user for a needle and string. Replaces all occurences of needle with string in all editable buffers.", 112, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1128 },
{ PROC_LINKS(query_replace, 0), "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1216 },
{ PROC_LINKS(query_replace_identifier, 0), "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1236 },
{ PROC_LINKS(query_replace_selection, 0), "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1252 },
{ PROC_LINKS(save_all_dirty_buffers, 0), "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1287 },
{ PROC_LINKS(delete_file_query, 0), "delete_file_query", 17, "Deletes the file of the current buffer if 4coder has the appropriate access rights. Will ask the user for confirmation first.", 125, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1312 },
{ PROC_LINKS(save_to_query, 0), "save_to_query", 13, "Queries the user for a file name and saves the contents of the current buffer, altering the buffer's name too.", 110, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1350 },
{ PROC_LINKS(rename_file_query, 0), "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1385 },
{ PROC_LINKS(make_directory_query, 0), "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1425 },
{ PROC_LINKS(move_line_up, 0), "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1458 },
{ PROC_LINKS(move_line_down, 0), "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1464 },
{ PROC_LINKS(duplicate_line, 0), "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1470 },
{ PROC_LINKS(delete_line, 0), "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1484 },
{ PROC_LINKS(open_file_in_quotes, 0), "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1549 },
{ PROC_LINKS(open_matching_file_cpp, 0), "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1581 },
{ PROC_LINKS(view_buffer_other_panel, 0), "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1594 },
{ PROC_LINKS(swap_buffers_between_panels, 0), "swap_buffers_between_panels", 27, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1606 },
{ PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1642 },
{ PROC_LINKS(save, 0), "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1650 },
{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1662 },
{ PROC_LINKS(undo, 0), "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1720 },
{ PROC_LINKS(redo, 0), "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1733 },
{ PROC_LINKS(undo_all_buffers, 0), "undo_all_buffers", 16, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1747 },
{ PROC_LINKS(redo_all_buffers, 0), "redo_all_buffers", 16, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1821 },
{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\4coder_base_commands.cpp", 36, 1924 },
{ PROC_LINKS(lister__quit, 0), "lister__quit", 12, "A lister mode command that quits the list without executing any actions.", 72, "w:\\4ed\\code\\4coder_lists.cpp", 28, 8 },
{ PROC_LINKS(lister__activate, 0), "lister__activate", 16, "A lister mode command that activates the list's action on the highlighted item.", 79, "w:\\4ed\\code\\4coder_lists.cpp", 28, 15 },
{ PROC_LINKS(lister__write_character, 0), "lister__write_character", 23, "A lister mode command that dispatches to the lister's write character handler.", 78, "w:\\4ed\\code\\4coder_lists.cpp", 28, 30 },
@ -399,21 +397,21 @@ static Command_Metadata fcoder_metacmd_table[235] = {
{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\4coder_lists.cpp", 28, 854 },
{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\4coder_lists.cpp", 28, 887 },
{ PROC_LINKS(command_lister, 0), "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\4coder_lists.cpp", 28, 969 },
{ PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 546 },
{ PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 555 },
{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 565 },
{ PROC_LINKS(write_and_auto_tab, 0), "write_and_auto_tab", 18, "Inserts a character and auto-indents the line on which the cursor sits.", 71, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 575 },
{ PROC_LINKS(list_all_locations, 0), "list_all_locations", 18, "Queries the user for a string and lists all exact case-sensitive matches found in all open buffers.", 99, "w:\\4ed\\code\\4coder_search.cpp", 29, 164 },
{ PROC_LINKS(list_all_substring_locations, 0), "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "w:\\4ed\\code\\4coder_search.cpp", 29, 170 },
{ PROC_LINKS(list_all_locations_case_insensitive, 0), "list_all_locations_case_insensitive", 35, "Queries the user for a string and lists all exact case-insensitive matches found in all open buffers.", 101, "w:\\4ed\\code\\4coder_search.cpp", 29, 176 },
{ PROC_LINKS(list_all_substring_locations_case_insensitive, 0), "list_all_substring_locations_case_insensitive", 45, "Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.", 105, "w:\\4ed\\code\\4coder_search.cpp", 29, 182 },
{ PROC_LINKS(list_all_locations_of_identifier, 0), "list_all_locations_of_identifier", 32, "Reads a token or word under the cursor and lists all exact case-sensitive mathces in all open buffers.", 102, "w:\\4ed\\code\\4coder_search.cpp", 29, 188 },
{ PROC_LINKS(list_all_locations_of_identifier_case_insensitive, 0), "list_all_locations_of_identifier_case_insensitive", 49, "Reads a token or word under the cursor and lists all exact case-insensitive mathces in all open buffers.", 104, "w:\\4ed\\code\\4coder_search.cpp", 29, 194 },
{ PROC_LINKS(list_all_locations_of_selection, 0), "list_all_locations_of_selection", 31, "Reads the string in the selected range and lists all exact case-sensitive mathces in all open buffers.", 102, "w:\\4ed\\code\\4coder_search.cpp", 29, 200 },
{ PROC_LINKS(list_all_locations_of_selection_case_insensitive, 0), "list_all_locations_of_selection_case_insensitive", 48, "Reads the string in the selected range and lists all exact case-insensitive mathces in all open buffers.", 104, "w:\\4ed\\code\\4coder_search.cpp", 29, 206 },
{ PROC_LINKS(list_all_locations_of_type_definition, 0), "list_all_locations_of_type_definition", 37, "Queries user for string, lists all locations of strings that appear to define a type whose name matches the input string.", 121, "w:\\4ed\\code\\4coder_search.cpp", 29, 212 },
{ PROC_LINKS(list_all_locations_of_type_definition_of_identifier, 0), "list_all_locations_of_type_definition_of_identifier", 51, "Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it.", 125, "w:\\4ed\\code\\4coder_search.cpp", 29, 220 },
{ PROC_LINKS(word_complete, 0), "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "w:\\4ed\\code\\4coder_search.cpp", 29, 374 },
{ PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 530 },
{ PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 539 },
{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 549 },
{ PROC_LINKS(write_and_auto_tab, 0), "write_and_auto_tab", 18, "Inserts a character and auto-indents the line on which the cursor sits.", 71, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 559 },
{ PROC_LINKS(list_all_locations, 0), "list_all_locations", 18, "Queries the user for a string and lists all exact case-sensitive matches found in all open buffers.", 99, "w:\\4ed\\code\\4coder_search.cpp", 29, 166 },
{ PROC_LINKS(list_all_substring_locations, 0), "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "w:\\4ed\\code\\4coder_search.cpp", 29, 172 },
{ PROC_LINKS(list_all_locations_case_insensitive, 0), "list_all_locations_case_insensitive", 35, "Queries the user for a string and lists all exact case-insensitive matches found in all open buffers.", 101, "w:\\4ed\\code\\4coder_search.cpp", 29, 178 },
{ PROC_LINKS(list_all_substring_locations_case_insensitive, 0), "list_all_substring_locations_case_insensitive", 45, "Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.", 105, "w:\\4ed\\code\\4coder_search.cpp", 29, 184 },
{ PROC_LINKS(list_all_locations_of_identifier, 0), "list_all_locations_of_identifier", 32, "Reads a token or word under the cursor and lists all exact case-sensitive mathces in all open buffers.", 102, "w:\\4ed\\code\\4coder_search.cpp", 29, 190 },
{ PROC_LINKS(list_all_locations_of_identifier_case_insensitive, 0), "list_all_locations_of_identifier_case_insensitive", 49, "Reads a token or word under the cursor and lists all exact case-insensitive mathces in all open buffers.", 104, "w:\\4ed\\code\\4coder_search.cpp", 29, 196 },
{ PROC_LINKS(list_all_locations_of_selection, 0), "list_all_locations_of_selection", 31, "Reads the string in the selected range and lists all exact case-sensitive mathces in all open buffers.", 102, "w:\\4ed\\code\\4coder_search.cpp", 29, 202 },
{ PROC_LINKS(list_all_locations_of_selection_case_insensitive, 0), "list_all_locations_of_selection_case_insensitive", 48, "Reads the string in the selected range and lists all exact case-insensitive mathces in all open buffers.", 104, "w:\\4ed\\code\\4coder_search.cpp", 29, 208 },
{ PROC_LINKS(list_all_locations_of_type_definition, 0), "list_all_locations_of_type_definition", 37, "Queries user for string, lists all locations of strings that appear to define a type whose name matches the input string.", 121, "w:\\4ed\\code\\4coder_search.cpp", 29, 214 },
{ PROC_LINKS(list_all_locations_of_type_definition_of_identifier, 0), "list_all_locations_of_type_definition_of_identifier", 51, "Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it.", 125, "w:\\4ed\\code\\4coder_search.cpp", 29, 222 },
{ PROC_LINKS(word_complete, 0), "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "w:\\4ed\\code\\4coder_search.cpp", 29, 376 },
{ PROC_LINKS(goto_jump_at_cursor, 0), "goto_jump_at_cursor", 19, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 352 },
{ PROC_LINKS(goto_jump_at_cursor_same_panel, 0), "goto_jump_at_cursor_same_panel", 30, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.", 167, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 379 },
{ PROC_LINKS(goto_next_jump, 0), "goto_next_jump", 14, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 468 },
@ -459,12 +457,12 @@ static Command_Metadata fcoder_metacmd_table[235] = {
{ PROC_LINKS(list_all_functions_current_buffer_lister, 0), "list_all_functions_current_buffer_lister", 40, "Creates a lister of locations that look like function definitions and declarations in the buffer.", 97, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 276 },
{ PROC_LINKS(list_all_functions_all_buffers, 0), "list_all_functions_all_buffers", 30, "Creates a jump list of lines from all buffers that appear to define or declare functions.", 89, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 288 },
{ PROC_LINKS(list_all_functions_all_buffers_lister, 0), "list_all_functions_all_buffers_lister", 37, "Creates a lister of locations that look like function definitions and declarations all buffers.", 95, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 294 },
{ PROC_LINKS(select_surrounding_scope, 0), "select_surrounding_scope", 24, "Finds the scope enclosed by '{' '}' surrounding the cursor and puts the cursor and mark on the '{' and '}'.", 107, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 337 },
{ PROC_LINKS(select_next_scope_absolute, 0), "select_next_scope_absolute", 26, "Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.", 102, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 352 },
{ PROC_LINKS(select_prev_scope_absolute, 0), "select_prev_scope_absolute", 26, "Finds the first scope started by '{' before the cursor and puts the cursor and mark on the '{' and '}'.", 103, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 371 },
{ PROC_LINKS(place_in_scope, 0), "place_in_scope", 14, "Wraps the code contained in the range between cursor and mark with a new curly brace scope.", 91, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 445 },
{ PROC_LINKS(delete_current_scope, 0), "delete_current_scope", 20, "Deletes the braces surrounding the currently selected scope. Leaves the contents within the scope.", 99, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 451 },
{ PROC_LINKS(scope_absorb_down, 0), "scope_absorb_down", 17, "If a scope is currently selected, and a statement or block statement is present below the current scope, the statement is moved into the scope.", 143, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 670 },
{ PROC_LINKS(select_surrounding_scope, 0), "select_surrounding_scope", 24, "Finds the scope enclosed by '{' '}' surrounding the cursor and puts the cursor and mark on the '{' and '}'.", 107, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 341 },
{ PROC_LINKS(select_next_scope_absolute, 0), "select_next_scope_absolute", 26, "Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.", 102, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 356 },
{ PROC_LINKS(select_prev_scope_absolute, 0), "select_prev_scope_absolute", 26, "Finds the first scope started by '{' before the cursor and puts the cursor and mark on the '{' and '}'.", 103, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 375 },
{ PROC_LINKS(place_in_scope, 0), "place_in_scope", 14, "Wraps the code contained in the range between cursor and mark with a new curly brace scope.", 91, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 449 },
{ PROC_LINKS(delete_current_scope, 0), "delete_current_scope", 20, "Deletes the braces surrounding the currently selected scope. Leaves the contents within the scope.", 99, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 455 },
{ PROC_LINKS(scope_absorb_down, 0), "scope_absorb_down", 17, "If a scope is currently selected, and a statement or block statement is present below the current scope, the statement is moved into the scope.", 143, "w:\\4ed\\code\\4coder_scope_commands.cpp", 37, 672 },
{ PROC_LINKS(open_long_braces, 0), "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 46 },
{ PROC_LINKS(open_long_braces_semicolon, 0), "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 54 },
{ PROC_LINKS(open_long_braces_break, 0), "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "w:\\4ed\\code\\4coder_combined_write_commands.cpp", 46, 62 },
@ -487,10 +485,8 @@ static Command_Metadata fcoder_metacmd_table[235] = {
{ 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, "w:\\4ed\\code\\4coder_miblo_numbers.cpp", 36, 237 },
{ 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, "w:\\4ed\\code\\4coder_miblo_numbers.cpp", 36, 243 },
{ 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, "w:\\4ed\\code\\4coder_miblo_numbers.cpp", 36, 249 },
{ PROC_LINKS(kill_rect, 0), "kill_rect", 9, "Delete characters in a rectangular region. Range testing is done by unwrapped-xy coordinates.", 93, "w:\\4ed\\code\\4coder_experiments.cpp", 34, 44 },
{ 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, "w:\\4ed\\code\\4coder_experiments.cpp", 34, 125 },
{ PROC_LINKS(rename_parameter, 0), "rename_parameter", 16, "If the cursor is found to be on the name of a function parameter in the signature of a function definition, all occurences within the scope of the function will be replaced with a new provided string.", 200, "w:\\4ed\\code\\4coder_experiments.cpp", 34, 386 },
{ 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, "w:\\4ed\\code\\4coder_experiments.cpp", 34, 693 },
{ PROC_LINKS(rename_parameter, 0), "rename_parameter", 16, "If the cursor is found to be on the name of a function parameter in the signature of a function definition, all occurences within the scope of the function will be replaced with a new provided string.", 200, "w:\\4ed\\code\\4coder_experiments.cpp", 34, 189 },
{ 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, "w:\\4ed\\code\\4coder_experiments.cpp", 34, 498 },
};
static int32_t fcoder_metacmd_ID_write_explicit_enum_flags = 0;
static int32_t fcoder_metacmd_ID_seek_beginning_of_textual_line = 1;
@ -723,8 +719,6 @@ static int32_t fcoder_metacmd_ID_miblo_increment_time_stamp = 227;
static int32_t fcoder_metacmd_ID_miblo_decrement_time_stamp = 228;
static int32_t fcoder_metacmd_ID_miblo_increment_time_stamp_minute = 229;
static int32_t fcoder_metacmd_ID_miblo_decrement_time_stamp_minute = 230;
static int32_t fcoder_metacmd_ID_kill_rect = 231;
static int32_t fcoder_metacmd_ID_multi_line_edit = 232;
static int32_t fcoder_metacmd_ID_rename_parameter = 233;
static int32_t fcoder_metacmd_ID_write_explicit_enum_values = 234;
static int32_t fcoder_metacmd_ID_rename_parameter = 231;
static int32_t fcoder_metacmd_ID_write_explicit_enum_values = 232;
#endif

View File

@ -117,7 +117,7 @@ set_hook(Bind_Helper *helper, i32 hook_id, Hook_Function *func){
}
internal void
set_scroll_rule(Bind_Helper *helper, Scroll_Rule_Function *func){
set_scroll_rule(Bind_Helper *helper, Delta_Rule_Function *func){
Binding_Unit unit = {};
unit.type = unit_hook;
unit.hook.hook_id = special_hook_scroll_rule;
@ -290,7 +290,7 @@ get_key_code(char *buffer){
internal Buffer_Seek
seek_location(ID_Line_Column_Jump_Location location){
return(seek_line_char(location.line, location.column));
return(seek_line_col(location.line, location.column));
}
internal Buffer_Seek
@ -300,7 +300,7 @@ seek_location(ID_Pos_Jump_Location location){
internal Buffer_Seek
seek_location(Name_Line_Column_Location location){
return(seek_line_char(location.line, location.column));
return(seek_line_col(location.line, location.column));
}
internal Buffer_Seek
@ -408,6 +408,46 @@ buffer_seek_character_class_change_0_1(Application_Links *app, Buffer_ID buffer,
////////////////////////////////
internal Buffer_Cursor
view_compute_cursor(Application_Links *app, View_ID view, Buffer_Seek seek){
return(buffer_compute_cursor(app, view_get_buffer(app, view, AccessAll), seek));
}
internal i64
view_pos_from_xy(Application_Links *app, View_ID view, Vec2_f32 p){
Buffer_ID buffer = view_get_buffer(app, view, AccessProtected);
Rect_f32 region = view_get_buffer_region(app, view);
f32 width = rect_width(region);
Face_ID face_id = get_face_id(app, buffer);
Buffer_Scroll scroll_vars = view_get_buffer_scroll(app, view);
i64 line = scroll_vars.position.line_number;
p = (p - region.p0) + scroll_vars.position.pixel_shift;
return(buffer_pos_at_relative_xy(app, buffer, width, face_id, line, p));
}
internal Buffer_Point
view_move_buffer_point(Application_Links *app, View_ID view, Buffer_Point buffer_point, Vec2_f32 delta){
delta += buffer_point.pixel_shift;
Line_Shift_Vertical shift = view_line_shift_y(app, view, buffer_point.line_number, delta.y);
buffer_point.line_number = shift.line;
buffer_point.pixel_shift = V2f32(delta.x, delta.y - shift.y_delta);
return(buffer_point);
}
internal void
view_zero_scroll(Application_Links *app, View_ID view){
if (view_is_in_ui_mode(app, view)){
Basic_Scroll scroll = {};
view_set_basic_scroll(app, view, scroll);
}
else{
Buffer_Scroll scroll = {};
view_set_buffer_scroll(app, view, scroll);
}
}
////////////////////////////////
internal Range_i64
buffer_range(Application_Links *app, Buffer_ID buffer){
Range_i64 range = {};
@ -439,20 +479,6 @@ set_view_range(Application_Links *app, View_ID view, Range_i64 range){
}
}
internal f32
get_view_y(Application_Links *app, View_ID view){
i64 pos = view_get_cursor_pos(app, view);
Full_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos));
return(cursor.wrapped_y);
}
internal f32
get_view_x(Application_Links *app, View_ID view){
i64 pos = view_get_cursor_pos(app, view);
Full_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos));
return(cursor.wrapped_x);
}
internal b32
is_valid_line(Application_Links *app, Buffer_ID buffer_id, i64 line){
i64 max_line = buffer_get_line_count(app, buffer_id);
@ -467,42 +493,40 @@ is_valid_line_range(Application_Links *app, Buffer_ID buffer_id, Range_i64 range
internal i64
get_line_number_from_pos(Application_Links *app, Buffer_ID buffer, i64 pos){
Partial_Cursor partial_cursor = buffer_compute_cursor(app, buffer, seek_pos(pos));
return(partial_cursor.line);
Buffer_Cursor cursor = buffer_compute_cursor(app, buffer, seek_pos(pos));
return(cursor.line);
}
internal i64
character_pos_to_pos_view(Application_Links *app, View_ID view, i64 character_pos){
i64 result = 0;
Full_Cursor cursor = view_compute_cursor(app, view, seek_character_pos(character_pos));
if (cursor.line > 0){
result = cursor.pos;
}
return(result);
buffer_get_character_legal_pos_from_pos(Application_Links *app, Buffer_ID buffer, f32 width, Face_ID face, i64 pos){
Buffer_Cursor cursor = buffer_compute_cursor(app, buffer, seek_pos(pos));
i64 character = buffer_relative_character_from_pos(app, buffer, width, face, cursor.line, pos);
return(buffer_pos_from_relative_character(app, buffer, width, face, cursor.line, character));
}
internal i64
character_pos_to_pos_buffer(Application_Links *app, Buffer_ID buffer, i64 character_pos){
Partial_Cursor cursor = buffer_compute_cursor(app, buffer, seek_character_pos(character_pos));
return(cursor.pos);
view_get_character_legal_pos_from_pos(Application_Links *app, Buffer_ID buffer, i64 pos){
Buffer_Cursor cursor = buffer_compute_cursor(app, buffer, seek_pos(pos));
i64 character = view_relative_character_from_pos(app, buffer, cursor.line, pos);
return(view_pos_from_relative_character(app, buffer, cursor.line, character));
}
internal Partial_Cursor
internal Buffer_Cursor
get_line_side(Application_Links *app, Buffer_ID buffer, i64 line_number, Side side){
i64 character_index = (side == Side_Min)?(1):(-1);
return(buffer_compute_cursor(app, buffer, seek_line_char(line_number, character_index)));
return(buffer_compute_cursor(app, buffer, seek_line_col(line_number, character_index)));
}
internal i64
get_line_side_pos(Application_Links *app, Buffer_ID buffer, i64 line_number, Side side){
i64 pos = -1;
Partial_Cursor partial_cursor = get_line_side(app, buffer, line_number, side);
if (partial_cursor.line != 0){
pos = partial_cursor.pos;
Buffer_Cursor cursor = get_line_side(app, buffer, line_number, side);
if (cursor.line != 0){
pos = cursor.pos;
}
return(pos);
}
internal Partial_Cursor
internal Buffer_Cursor
get_line_start(Application_Links *app, Buffer_ID buffer, i64 line_number){
return(get_line_side(app, buffer, line_number, Side_Min));
}
@ -513,7 +537,7 @@ get_line_start_pos(Application_Links *app, Buffer_ID buffer, i64 line_number){
// NOTE(allen): The position returned has the index of the terminating newline character,
// not one past the newline character.
internal Partial_Cursor
internal Buffer_Cursor
get_line_end(Application_Links *app, Buffer_ID buffer, i64 line_number){
return(get_line_side(app, buffer, line_number, Side_Max));
}
@ -523,10 +547,10 @@ get_line_end_pos(Application_Links *app, Buffer_ID buffer, i64 line_number){
}
// NOTE(allen): The range returned does not include the terminating newline character
internal Range_Partial_Cursor
internal Range_Cursor
get_line_range(Application_Links *app, Buffer_ID buffer, i64 line_number){
b32 success = false;
Range_Partial_Cursor result = {};
Range_Cursor result = {};
result.begin = get_line_start(app, buffer, line_number);
if (result.begin.line != 0){
result.end = get_line_end(app, buffer, line_number);
@ -543,7 +567,7 @@ get_line_range(Application_Links *app, Buffer_ID buffer, i64 line_number){
// NOTE(allen): The range returned does not include the terminating newline character
internal Range_i64
get_line_pos_range(Application_Links *app, Buffer_ID buffer, i64 line_number){
Range_Partial_Cursor range = get_line_range(app, buffer, line_number);
Range_Cursor range = get_line_range(app, buffer, line_number);
Range_i64 result = {};
if (range.begin.line != 0 && range.end.line != 0){
result = Ii64(range.begin.pos, range.end.pos);
@ -552,7 +576,7 @@ get_line_pos_range(Application_Links *app, Buffer_ID buffer, i64 line_number){
}
internal Range_i64
make_range_from_cursors(Range_Partial_Cursor range){
make_range_from_cursors(Range_Cursor range){
return(Ii64(range.begin.pos, range.end.pos));
}
@ -1406,7 +1430,7 @@ replace_in_range(Application_Links *app, Buffer_ID buffer, Range_i64 range, Stri
i64 pos = range.min - 1;
i64 new_pos = 0;
buffer_seek_string_forward(app, buffer, pos, range.end, needle, &new_pos);
i64 shift = replace_range_compute_shift(needle.size, string.size);
i64 shift = replace_range_shift(needle.size, string.size);
for (; new_pos + (imem)needle.size <= range.end;){
Range_i64 needle_range = Ii64(new_pos, new_pos + (i32)needle.size);
buffer_replace_range(app, buffer, needle_range, string);
@ -1435,7 +1459,7 @@ swap_lines(Application_Links *app, Buffer_ID buffer, i64 line_1, i64 line_2){
buffer_replace_range(app, buffer, range_1, text_2);
history_group_end(group);
i64 shift = replace_range_compute_shift(range_1, text_2.size);
i64 shift = replace_range_shift(range_1, text_2.size);
result.min = range_1.min;
result.max = range_2.min + shift;
}
@ -1521,11 +1545,10 @@ exec_command(Application_Links *app, Generic_Command cmd){
exec_command(app, cmd.command);
}
internal i32
internal b32
key_is_unmodified(Key_Event_Data *key){
int8_t *mods = key->modifiers;
i32 unmodified = (!mods[MDFR_CONTROL_INDEX] && !mods[MDFR_ALT_INDEX]);
return(unmodified);
b8 *mods = key->modifiers;
return(!mods[MDFR_CONTROL_INDEX] && !mods[MDFR_ALT_INDEX]);
}
internal u32

View File

@ -49,7 +49,7 @@ parse_buffer_to_jump_array(Application_Links *app, Arena *arena, Buffer_ID buffe
i32 colon_index = 0;
b32 is_sub_error = false;
Buffer_ID out_buffer_id = 0;
i32 out_pos = 0;
i64 out_pos = 0;
{
Scratch_Block line_auto_closer(arena);
@ -60,7 +60,7 @@ parse_buffer_to_jump_array(Application_Links *app, Arena *arena, Buffer_ID buffe
Buffer_ID jump_buffer = {};
if (open_file(app, &jump_buffer, parsed_jump.location.file, false, true)){
if (buffer_exists(app, jump_buffer)){
Partial_Cursor cursor = buffer_compute_cursor(app, jump_buffer, seek_jump(parsed_jump));
Buffer_Cursor cursor = buffer_compute_cursor(app, jump_buffer, seek_jump(parsed_jump));
if (cursor.line > 0){
out_buffer_id = jump_buffer;
out_pos = cursor.pos;
@ -359,7 +359,7 @@ CUSTOM_DOC("If the cursor is found to be on a jump location, parses the jump loc
Marker_List *list = get_or_make_list_for_buffer(app, heap, buffer);
i64 pos = view_get_cursor_pos(app, view);
Full_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos));
Buffer_Cursor cursor = buffer_compute_cursor(app, buffer, seek_pos(pos));
i32 list_index = get_index_exact_from_list(app, list, cursor.line);
@ -387,7 +387,7 @@ CUSTOM_DOC("If the cursor is found to be on a jump location, parses the jump loc
Marker_List *list = get_or_make_list_for_buffer(app, heap, buffer);
i64 pos = view_get_cursor_pos(app, view);
Full_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos));
Buffer_Cursor cursor = buffer_compute_cursor(app, buffer, seek_pos(pos));
i32 list_index = get_index_exact_from_list(app, list, cursor.line);
@ -440,7 +440,7 @@ goto_next_filtered_jump(Application_Links *app, Marker_List *list, View_ID jump_
if (!skip_this){
goto_jump_in_order(app, list, jump_view, location);
i64 updated_line = get_line_from_list(app, list, list_index);
view_set_cursor(app, jump_view, seek_line_char(updated_line, 1), true);
view_set_cursor(app, jump_view, seek_line_col(updated_line, 1), true);
break;
}
}
@ -459,7 +459,7 @@ get_locked_jump_state(Application_Links *app, Heap *heap){
result.list = get_or_make_list_for_buffer(app, heap, buffer);
i64 cursor_position = view_get_cursor_pos(app, result.view);
Full_Cursor cursor = view_compute_cursor(app, result.view, seek_pos(cursor_position));
Buffer_Cursor cursor = buffer_compute_cursor(app, buffer, seek_pos(cursor_position));
result.list_index = get_index_nearest_from_list(app, result.list, cursor.line);
}
return(result);
@ -473,10 +473,10 @@ CUSTOM_DOC("If a buffer containing jump locations has been locked in, goes to th
Locked_Jump_State jump_state = get_locked_jump_state(app, heap);
if (jump_state.view != 0){
i64 cursor_position = view_get_cursor_pos(app, jump_state.view);
Full_Cursor cursor = view_compute_cursor(app, jump_state.view, seek_pos(cursor_position));
Buffer_Cursor cursor = view_compute_cursor(app, jump_state.view, seek_pos(cursor_position));
i64 line = get_line_from_list(app, jump_state.list, jump_state.list_index);
if (line <= cursor.line){
++jump_state.list_index;
jump_state.list_index += 1;
}
goto_next_filtered_jump(app, jump_state.list, jump_state.view, jump_state.list_index, 1, true, true);
}
@ -503,7 +503,7 @@ CUSTOM_DOC("If a buffer containing jump locations has been locked in, goes to th
Locked_Jump_State jump_state = get_locked_jump_state(app, heap);
if (jump_state.view != 0){
i64 cursor_position = view_get_cursor_pos(app, jump_state.view);
Full_Cursor cursor = view_compute_cursor(app, jump_state.view, seek_pos(cursor_position));
Buffer_Cursor cursor = view_compute_cursor(app, jump_state.view, seek_pos(cursor_position));
i64 line = get_line_from_list(app, jump_state.list, jump_state.list_index);
if (line <= cursor.line){
++jump_state.list_index;
@ -538,7 +538,7 @@ CUSTOM_DOC("If a buffer containing jump locations has been locked in, goes to th
if (get_jump_from_list(app, jump_state.list, list_index, &location)){
goto_jump_in_order(app, jump_state.list, jump_state.view, location);
i64 updated_line = get_line_from_list(app, jump_state.list, list_index);
view_set_cursor(app, jump_state.view, seek_line_char(updated_line, 1), true);
view_set_cursor(app, jump_state.view, seek_line_col(updated_line, 1), true);
}
}
}

View File

@ -12,7 +12,7 @@ struct Sticky_Jump{
i64 list_colon_index;
b32 is_sub_error;
Buffer_ID jump_buffer_id;
i32 jump_pos;
i64 jump_pos;
};
struct Sticky_Jump_Stored{

View File

@ -246,7 +246,7 @@ set_view_to_location(Application_Links *app, View_ID view, Buffer_ID buffer, Buf
static void
jump_to_location(Application_Links *app, View_ID view, Buffer_ID buffer, Name_Line_Column_Location location){
view_set_active(app, view);
set_view_to_location(app, view, buffer, seek_line_char(location.line, location.column));
set_view_to_location(app, view, buffer, seek_line_col(location.line, location.column));
if (auto_center_after_jumps){
center_view(app);
}
@ -305,7 +305,7 @@ convert_name_based_to_id_based(Application_Links *app, Name_Line_Column_Location
static Parsed_Jump
seek_next_jump_in_view(Application_Links *app, Arena *arena, View_ID view, i32 skip_sub_errors, Scan_Direction direction, i64 *line_out){
i64 cursor_position = view_get_cursor_pos(app, view);
Full_Cursor cursor = view_compute_cursor(app, view, seek_pos(cursor_position));
Buffer_Cursor cursor = view_compute_cursor(app, view, seek_pos(cursor_position));
i64 line = cursor.line;
Buffer_ID buffer = view_get_buffer(app, view, AccessAll);
Parsed_Jump jump = seek_next_jump_in_buffer(app, arena, buffer, line + direction, skip_sub_errors, direction, &line);

View File

@ -137,7 +137,7 @@ heap_free(Heap *heap, void *memory){
}
}
#define heap_array(g, T, size) (T*)heap_allocate(g, sizeof(T)*(size))
#define heap_array(g, T, size) (T*)heap_allocate(g, (i32)(sizeof(T)*(size)))
// BOTTOM

View File

@ -71,10 +71,10 @@ CUSTOM_COMMAND_SIG(lister__wheel_scroll)
CUSTOM_DOC("A lister mode command that scrolls the list in response to the mouse wheel.")
{
View_ID view = get_active_view(app, AccessAll);
GUI_Scroll_Vars scroll = view_get_scroll_vars(app, view);
Basic_Scroll scroll = view_get_basic_scroll(app, view);
Mouse_State mouse = get_mouse_state(app);
scroll.target_y += mouse.wheel;
view_set_scroll(app, view, scroll);
scroll.target.y += mouse.wheel;
view_set_basic_scroll(app, view, scroll);
Lister_State *state = view_get_lister_state(view);
if (state->initialized){
lister_update_ui(app, view, state);

View File

@ -1010,7 +1010,7 @@ CUSTOM_DOC("Jump to the code that logged the event record at the mouse point in
view_end_ui_mode(app, target_view);
}
set_view_to_location(app, target_view, target_buffer,
seek_line_char(event->line_number, 1));
seek_line_col(event->line_number, 1));
}
}
}

View File

@ -5,7 +5,6 @@
// TOP
static b32 parse_statement_down(Application_Links *app, Statement_Parser *parser, Cpp_Token *token_out);
static f32 scope_center_threshold = 0.75f;
////////////////////////////////
@ -287,48 +286,53 @@ find_scope_range(Application_Links *app, Buffer_ID buffer, i64 start_pos, Range_
}
static void
view_set_to_region(Application_Links *app, View_ID view, i64 major_pos, i64 minor_pos, f32 normalized_threshold){
view_set_to_region(Application_Links *app, View_ID view, i64 major_pos, i64 minor_pos){
Range_i64 range = Ii64(major_pos, minor_pos);
b32 bottom_major = false;
if (major_pos == range.max){
bottom_major = true;
}
Full_Cursor top = view_compute_cursor(app, view, seek_pos(range.min));
Buffer_Cursor top = view_compute_cursor(app, view, seek_pos(range.min));
if (top.line > 0){
Full_Cursor bottom = view_compute_cursor(app, view, seek_pos(range.max));
Buffer_Cursor bottom = view_compute_cursor(app, view, seek_pos(range.max));
if (bottom.line > 0){
f32 top_y = top.wrapped_y;
f32 bottom_y = bottom.wrapped_y;
Rect_f32 region = view_get_buffer_region(app, view);
f32 view_height = rect_height(region);
f32 skirt_height = view_height*.1f;
Interval_f32 acceptable_y = If32(skirt_height, view_height*.9f);
GUI_Scroll_Vars scroll = view_get_scroll_vars(app, view);
f32 half_view_height = .5f*(f32)(rect_height(region));
f32 threshold = normalized_threshold * half_view_height;
f32 current_center_y = ((f32)scroll.target_y) + half_view_height;
f32 target_height = view_line_y_difference(app, view, bottom.line, top.line);
if (top_y < current_center_y - threshold || bottom_y > current_center_y + threshold){
f32 center_target_y = .5f*(top_y + bottom_y);
if (bottom_major){
if (center_target_y < bottom_y - half_view_height * .9f){
center_target_y = bottom_y - half_view_height * .9f;
if (target_height > view_height){
i64 major_line = bottom.line;
if (range.min == major_pos){
major_line = top.line;
}
Buffer_Scroll scroll = view_get_buffer_scroll(app, view);
scroll.target.line_number = major_line;
scroll.target.pixel_shift.y = -skirt_height;
view_set_buffer_scroll(app, view, scroll);
}
else{
if (center_target_y > top_y + half_view_height * .9f){
center_target_y = top_y + half_view_height * .9f;
Buffer_Scroll scroll = view_get_buffer_scroll(app, view);
Vec2_f32 top_p = view_relative_xy_of_pos(app, view, scroll.position.line_number, range.min);
top_p -= scroll.position.pixel_shift;
if (top_p.y < acceptable_y.min){
scroll.target.line_number = top.line;
scroll.target.pixel_shift.y = -skirt_height;
view_set_buffer_scroll(app, view, scroll);
}
else{
Vec2_f32 bot_p = view_relative_xy_of_pos(app, view, scroll.position.line_number, range.max);
bot_p -= scroll.position.pixel_shift;
if (bot_p.y > acceptable_y.max){
scroll.target.line_number = bottom.line;
scroll.target.pixel_shift.y = skirt_height - view_height;
view_set_buffer_scroll(app, view, scroll);
}
}
f32 target_y = center_target_y - half_view_height;
if (target_y < 0){
target_y = 0;
}
scroll.target_y = (i32)(target_y);
view_set_scroll(app, view, scroll);
}
}
}
@ -344,7 +348,7 @@ CUSTOM_DOC("Finds the scope enclosed by '{' '}' surrounding the cursor and puts
if (find_scope_range(app, buffer, pos, &range, FindScope_Brace)){
view_set_cursor(app, view, seek_pos(range.first), true);
view_set_mark(app, view, seek_pos(range.end));
view_set_to_region(app, view, range.first, range.end, scope_center_threshold);
view_set_to_region(app, view, range.first, range.end);
no_mark_snap_to_cursor(app, view);
}
}
@ -362,7 +366,7 @@ CUSTOM_DOC("Finds the first scope started by '{' after the cursor and puts the c
if (find_scope_bottom(app, buffer, top, FindScope_EndOfToken|FindScope_Brace, &bottom)){
view_set_cursor(app, view, seek_pos(top), true);
view_set_mark(app, view, seek_pos(bottom));
view_set_to_region(app, view, top, bottom, scope_center_threshold);
view_set_to_region(app, view, top, bottom);
no_mark_snap_to_cursor(app, view);
}
}
@ -381,7 +385,7 @@ CUSTOM_DOC("Finds the first scope started by '{' before the cursor and puts the
if (find_scope_bottom(app, buffer, top, FindScope_EndOfToken|FindScope_Brace, &bottom)){
view_set_cursor(app, view, seek_pos(top), true);
view_set_mark(app, view, seek_pos(bottom));
view_set_to_region(app, view, top, bottom, scope_center_threshold);
view_set_to_region(app, view, top, bottom);
no_mark_snap_to_cursor(app, view);
}
}
@ -466,18 +470,16 @@ CUSTOM_DOC("Deletes the braces surrounding the currently selected scope. Leaves
bot_len = 2;
}
Buffer_Edit edits[2];
edits[0].str_start = 0;
edits[0].len = 0;
edits[0].start = (i32)(range.min + 1 - top_len);
edits[0].end = (i32)(range.min + 1);
Batch_Edit batch_first = {};
Batch_Edit batch_last = {};
edits[1].str_start = 0;
edits[1].len = 0;
edits[1].start = (i32)(range.max - 1);
edits[1].end = (i32)(range.max - 1 + bot_len);
batch_first.edit.text = SCu8();
batch_first.edit.range = Ii64(range.min + 1 - top_len, range.min + 1);
batch_first.next = &batch_last;
batch_last.edit.text = SCu8();
batch_last.edit.range = Ii64((i32)(range.max - 1), (i32)(range.max - 1 + bot_len));
buffer_batch_edit(app, buffer, 0, edits, 2);
buffer_batch_edit(app, buffer, &batch_first);
}
}
@ -701,16 +703,16 @@ CUSTOM_DOC("If a scope is currently selected, and a statement or block statement
edit_str = push_u8_stringf(scratch, "%.*s\n", string_expand(string));
}
Buffer_Edit edits[2];
edits[0].str_start = 0;
edits[0].len = (i32)edit_str.size;
edits[0].start = (i32)(range.min - 1);
edits[0].end = (i32)(range.min - 1);
edits[1].str_start = 0;
edits[1].len = 0;
edits[1].start = (i32)(range.start);
edits[1].end = (i32)(range.end);
buffer_batch_edit(app, buffer, (char*)edit_str.str, edits, 2);
Batch_Edit batch_first = {};
Batch_Edit batch_last = {};
batch_first.edit.text = edit_str;
batch_first.edit.range = Ii64(range.min - 1, range.min - 1);
batch_first.next = &batch_last;
batch_last.edit.text = SCu8();
batch_last.edit.range = range;
buffer_batch_edit(app, buffer, &batch_first);
}
}

View File

@ -40,11 +40,13 @@ print_string_match_list_to_buffer(Application_Links *app, Buffer_ID out_buffer_i
}
}
Partial_Cursor partial_cursor = buffer_compute_cursor(app, current_buffer, seek_pos(node->range.first));
Buffer_Cursor cursor = buffer_compute_cursor(app, current_buffer, seek_pos(node->range.first));
Temp_Memory line_temp = begin_temp(scratch);
String_Const_u8 full_line_str = push_buffer_line(app, scratch, current_buffer, partial_cursor.line);
String_Const_u8 full_line_str = push_buffer_line(app, scratch, current_buffer, cursor.line);
String_Const_u8 line_str = string_skip_chop_whitespace(full_line_str);
insertf(&out, "%.*s:%d:%d: %.*s\n", string_expand(current_file_name), partial_cursor.line, partial_cursor.character, string_expand(line_str));
insertf(&out, "%.*s:%d:%d: %.*s\n",
string_expand(current_file_name), cursor.line, cursor.col,
string_expand(line_str));
end_temp(line_temp);
}
}

View File

@ -18,10 +18,11 @@ internal void
seek_pos_of_visual_line(Application_Links *app, Side side){
View_ID view = get_active_view(app, AccessProtected);
i64 pos = view_get_cursor_pos(app, view);
Full_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos));
f32 y = cursor.wrapped_y;
f32 x = (side == Side_Min)?(0.f):(max_f32);
view_set_cursor(app, view, seek_wrapped_xy(x, y, true), true);
Buffer_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos));
Vec2_f32 p = view_relative_xy_of_pos(app, view, cursor.line, pos);
p.x = (side == Side_Min)?(0.f):(max_f32);
i64 new_pos = view_pos_at_relative_xy(app, view, cursor.line, p);
view_set_cursor(app, view, seek_pos(new_pos), true);
no_mark_snap_to_cursor_if_shift(app, view);
}

View File

@ -6,7 +6,7 @@
internal u64
table_hash(Data key){
return(table_hash_u8((u8*)key.data, key.size) | bit_63);
return(table_hash_u8((u8*)key.data, key.size) | bit_64);
}
global_const u64 table_empty_slot = 0;
@ -154,11 +154,10 @@ table_insert(Table_u64_u64 *table, u64 key, u64 val){
}
internal b32
table_erase(Table_u64_u64 *table, u64 key){
table_erase(Table_u64_u64 *table, Table_Lookup lookup){
b32 result = false;
Table_Lookup lookup = table_lookup(table, key);
if (lookup.found_match){
table->keys[lookup.index] = 0;
table->keys[lookup.index] = table_erased_key;
table->vals[lookup.index] = 0;
table->used_count -= 1;
result = true;
@ -166,6 +165,18 @@ table_erase(Table_u64_u64 *table, u64 key){
return(result);
}
internal b32
table_erase(Table_u64_u64 *table, u64 key){
Table_Lookup lookup = table_lookup(table, key);
return(table_erase(table, lookup));
}
internal b32
table_clear(Table_u64_u64 *table){
block_zero_dynamic_array(table->keys, table->slot_count);
block_zero_dynamic_array(table->vals, table->slot_count);
}
////////////////////////////////
internal Table_u32_u16
@ -296,11 +307,10 @@ table_insert(Table_u32_u16 *table, u32 key, u16 val){
}
internal b32
table_erase(Table_u32_u16 *table, u32 key){
table_erase(Table_u32_u16 *table, Table_Lookup lookup){
b32 result = false;
Table_Lookup lookup = table_lookup(table, key);
if (lookup.found_match){
table->keys[lookup.index] = 0;
table->keys[lookup.index] = table_erased_u32_key;
table->vals[lookup.index] = 0;
table->used_count -= 1;
result = true;
@ -308,6 +318,18 @@ table_erase(Table_u32_u16 *table, u32 key){
return(result);
}
internal b32
table_erase(Table_u32_u16 *table, u32 key){
Table_Lookup lookup = table_lookup(table, key);
return(table_erase(table, lookup));
}
internal b32
table_clear(Table_u32_u16 *table){
block_zero_dynamic_array(table->keys, table->slot_count);
block_zero_dynamic_array(table->vals, table->slot_count);
}
////////////////////////////////
internal Table_Data_u64
@ -410,7 +432,7 @@ table_rehash(Table_Data_u64 *dst, Table_Data_u64 *src){
if ((dst->dirty_count + src->used_count)*8 < dst->slot_count*7){
u64 *src_hashes = src->hashes;
for (u32 i = 0; i < src_slot_count; i += 1){
if (HasFlag(src_hashes[i], bit_63)){
if (HasFlag(src_hashes[i], bit_64)){
Data key = src->keys[i];
Table_Lookup lookup = table_lookup(dst, key);
table_insert__inner(dst, lookup, key, src->vals[i]);
@ -458,6 +480,12 @@ table_erase(Table_Data_u64 *table, Data key){
return(result);
}
internal b32
table_clear(Table_Data_u64 *table){
block_zero_dynamic_array(table->keys, table->slot_count);
block_zero_dynamic_array(table->vals, table->slot_count);
}
////////////////////////////////
internal Table_u64_Data
@ -606,6 +634,12 @@ table_erase(Table_u64_Data *table, u64 key){
return(result);
}
internal b32
table_clear(Table_u64_Data *table){
block_zero_dynamic_array(table->keys, table->slot_count);
block_zero_dynamic_array(table->vals, table->slot_count);
}
////////////////////////////////
internal Table_Data_Data
@ -703,7 +737,7 @@ table_rehash(Table_Data_Data *dst, Table_Data_Data *src){
if ((dst->dirty_count + src->used_count)*8 < dst->slot_count*7){
u64 *src_hashes = src->hashes;
for (u32 i = 0; i < src_slot_count; i += 1){
if (HasFlag(src_hashes[i], bit_63)){
if (HasFlag(src_hashes[i], bit_64)){
Data key = src->keys[i];
Table_Lookup lookup = table_lookup(dst, key);
table_insert__inner(dst, lookup, key, src->vals[i]);
@ -751,4 +785,10 @@ table_erase(Table_Data_Data *table, Data key){
return(result);
}
internal b32
table_clear(Table_Data_Data *table){
block_zero_dynamic_array(table->keys, table->slot_count);
block_zero_dynamic_array(table->vals, table->slot_count);
}
// BOTTOM

View File

@ -160,75 +160,36 @@ ui_control_get_mouse_hit(UI_Data *data, Vec2_f32 view_p, Vec2_f32 panel_p){
return(result);
}
#if 0
static UI_Item*
ui_control_get_mouse_hit(UI_Data *data, i32 mx_scrolled, i32 my_scrolled, i32 mx_unscrolled, i32 my_unscrolled){
return(ui_control_get_mouse_hit(data, V2i32(mx_scrolled, my_scrolled), V2i32(mx_unscrolled, my_unscrolled)));
}
#endif
////////////////////////////////
static void
view_zero_scroll(Application_Links *app, View_ID view){
GUI_Scroll_Vars zero_scroll = {};
view_set_scroll(app, view, zero_scroll);
}
static void
view_set_vertical_focus(Application_Links *app, View_ID view, f32 y_top, f32 y_bot){
view_set_vertical_focus_basic(Application_Links *app, View_ID view, f32 y_top, f32 y_bot){
Rect_f32 buffer_region = view_get_buffer_region(app, view);
GUI_Scroll_Vars scroll = view_get_scroll_vars(app, view);
f32 view_y_top = (f32)scroll.target_y;
f32 view_y_dim = rect_height(buffer_region);
f32 view_y_bot = view_y_top + view_y_dim;
Basic_Scroll scroll = view_get_basic_scroll(app, view);
f32 view_height = rect_height(buffer_region);
Interval_f32 view_y = If32(scroll.target.y, scroll.target.y + view_height);
Interval_f32 acceptable_y = If32(lerp(view_y.min, 0.10f, view_y.max),
lerp(view_y.min, 0.90f, view_y.max));
f32 acceptable_height = range_size(acceptable_y);
f32 skirt_height = acceptable_y.min - view_y.min;
Buffer_ID buffer = view_get_buffer(app, view, AccessAll);
Face_ID face_id = get_face_id(app, buffer);
Face_Metrics metrics = get_face_metrics(app, face_id);
f32 line_dim = metrics.line_height;
f32 hot_y_top = view_y_top + line_dim*3;
f32 hot_y_bot = view_y_bot - line_dim*3;
if (hot_y_bot - hot_y_top < line_dim*6){
f32 quarter_view_y_dim = view_y_dim*.25f;
hot_y_top = view_y_top + quarter_view_y_dim;
hot_y_bot = view_y_bot - quarter_view_y_dim;
}
f32 hot_y_dim = hot_y_bot - hot_y_top;
f32 skirt_dim = hot_y_top - view_y_top;
f32 y_dim = y_bot - y_top;
if (y_dim > hot_y_dim){
scroll.target_y = (i32)(y_top - skirt_dim);
view_set_scroll(app, view, scroll);
f32 height = y_bot - y_top;
if (height > acceptable_height){
scroll.target.y = y_top - skirt_height;
view_set_basic_scroll(app, view, scroll);
}
else{
if (y_top < hot_y_top){
scroll.target_y = (i32)(y_top - skirt_dim);
view_set_scroll(app, view, scroll);
if (y_top < acceptable_y.min){
scroll.target.y = y_top - skirt_height;
view_set_basic_scroll(app, view, scroll);
}
else if (y_bot > hot_y_bot){
scroll.target_y = (i32)(y_bot + skirt_dim - view_y_dim);
view_set_scroll(app, view, scroll);
else if (y_bot > acceptable_y.max){
scroll.target.y = y_bot + skirt_height - view_height;
view_set_basic_scroll(app, view, scroll);
}
}
}
static Vec2_f32
view_space_from_screen_space(Vec2_f32 p, Vec2_f32 file_region_p0, Vec2_f32 scroll_p){
return(p - file_region_p0 + scroll_p);
}
static Vec2_f32
get_mouse_position_in_view_space(Mouse_State mouse, Vec2_f32 file_region_p0, Vec2_f32 scroll_p){
return(view_space_from_screen_space(V2f32(mouse.p), file_region_p0, scroll_p));
}
static Vec2_f32
get_mouse_position_in_view_space(Application_Links *app, Vec2_f32 file_region_p0, Vec2_f32 scroll_p){
return(get_mouse_position_in_view_space(get_mouse_state(app), file_region_p0, scroll_p));
}
static Vec2_f32
panel_space_from_screen_space(Vec2_f32 p, Vec2_f32 file_region_p0){
return(p - file_region_p0);
@ -244,16 +205,6 @@ get_mouse_position_in_panel_space(Application_Links *app, Vec2_f32 file_region_p
return(get_mouse_position_in_panel_space(get_mouse_state(app), file_region_p0));
}
static Vec2
panel_space_from_view_space(Vec2 p, Vec2 scroll_p){
return(p - scroll_p);
}
static Vec2_i32
panel_space_from_view_space(Vec2_i32 p, Vec2_i32 scroll_p){
return(p - scroll_p);
}
////////////////////////////////
// TODO(allen): VIEW_16_LIMIT
@ -298,12 +249,11 @@ lister_get_clicked_item(Application_Links *app, View_ID view_id){
UI_Data *ui_data = 0;
Arena *ui_arena = 0;
if (view_get_ui_data(app, view_id, ViewGetUIFlag_KeepDataAsIs, &ui_data, &ui_arena)){
GUI_Scroll_Vars scroll_vars = view_get_scroll_vars(app, view_id);
Mouse_State mouse = get_mouse_state(app);
Rect_f32 buffer_region = view_get_buffer_region(app, view_id);
Vec2_f32 region_p0 = buffer_region.p0;
Vec2_f32 m_view_space = get_mouse_position_in_view_space(mouse, region_p0, scroll_vars.scroll_p);
Vec2_f32 m_panel_space = get_mouse_position_in_panel_space(mouse, region_p0);
Rect_f32 region = view_get_buffer_region(app, view_id);
Vec2_f32 m_panel_space = get_mouse_position_in_panel_space(mouse, region.p0);
Basic_Scroll scroll = view_get_basic_scroll(app, view_id);
Vec2_f32 m_view_space = m_panel_space + scroll.position;
UI_Item *clicked = ui_control_get_mouse_hit(ui_data, m_view_space, m_panel_space);
if (clicked != 0){
result = *clicked;
@ -338,7 +288,7 @@ lister_update_ui(Application_Links *app, View_ID view, Lister_State *state){
Face_ID face_id = get_face_id(app, 0);
Face_Metrics metrics = get_face_metrics(app, face_id);
GUI_Scroll_Vars scroll_vars = view_get_scroll_vars(app, view);
Basic_Scroll scroll = view_get_basic_scroll(app, view);
f32 x0 = 0;
f32 x1 = (rect_width(screen_rect));
@ -349,9 +299,9 @@ lister_update_ui(Application_Links *app, View_ID view, Lister_State *state){
Arena *scratch = context_get_arena(app);
Temp_Memory full_temp = begin_temp(scratch);
// TODO(allen): switch to float
Rect_f32 buffer_region = view_get_buffer_region(app, view);
Vec2_f32 view_m = get_mouse_position_in_view_space(app, buffer_region.p0, scroll_vars.scroll_p);
Rect_f32 region = view_get_buffer_region(app, view);
Vec2_f32 view_m = get_mouse_position_in_panel_space(app, region.p0);
view_m += scroll.position;
f32 y_pos = text_field_height;
@ -494,7 +444,7 @@ lister_update_ui(Application_Links *app, View_ID view, Lister_State *state){
if (state->set_view_vertical_focus_to_item){
if (highlighted_item != 0){
view_set_vertical_focus(app, view,
view_set_vertical_focus_basic(app, view,
(f32)highlighted_item->rect_outer.y0,
(f32)highlighted_item->rect_outer.y1);
}

162
4ed.cpp
View File

@ -60,7 +60,7 @@ app_coroutine_handle_request(Models *models, Coroutine *co, u32 *vals){
{
Face_Description *description = ((Face_Description**)vals)[0];
Face_ID face_id = ((Face_ID*)vals)[3];
b32 success = alter_font_and_update_files(system, models, face_id, description);
b32 success = font_set_modify_face(&models->font_set, face_id, description);
result = coroutine_run(&models->coroutines, co, &success, vals);
}break;
}
@ -85,15 +85,15 @@ app_coroutine_run(Models *models, App_Coroutine_Purpose purpose, Coroutine *co,
internal void
output_file_append(Models *models, Editing_File *file, String_Const_u8 value){
i32 end = buffer_size(&file->state.buffer);
i64 end = buffer_size(&file->state.buffer);
Edit_Behaviors behaviors = {};
edit_single(models->system, models, file, make_range(end), value, behaviors);
edit_single(models, file, Ii64(end), value, behaviors);
}
internal void
file_cursor_to_end(System_Functions *system, Models *models, Editing_File *file){
Assert(file != 0);
i32 pos = buffer_size(&file->state.buffer);
i64 pos = buffer_size(&file->state.buffer);
Layout *layout = &models->layout;
for (Panel *panel = layout_get_first_open_panel(layout);
panel != 0;
@ -102,9 +102,8 @@ file_cursor_to_end(System_Functions *system, Models *models, Editing_File *file)
if (view->file != file){
continue;
}
Full_Cursor cursor = file_compute_cursor(models, file, seek_pos(pos));
view_set_cursor(system, models, view, cursor, true);
view->mark = cursor.pos;
view_set_cursor(models, view, pos);
view->mark = pos;
}
}
@ -129,17 +128,9 @@ file_cursor_to_end(System_Functions *system, Models *models, Editing_File *file)
#define REQ_FILE(n,v) Editing_File *n = (v)->file_data.file; if (n == 0) return
#define REQ_FILE_HISTORY(n,v) Editing_File *n = (v)->file_data.file; if (n == 0 || n->state.undo.undo.edits == 0) return
SCROLL_RULE_SIG(fallback_scroll_rule){
b32 result = false;
if (target_x != *scroll_x){
*scroll_x = target_x;
result = true;
}
if (target_y != *scroll_y){
*scroll_y = target_y;
result = true;
}
return(result);
DELTA_RULE_SIG(fallback_scroll_rule){
return(pending_delta);
}
#define DEFAULT_MAP_SIZE 10
@ -415,7 +406,7 @@ interpret_binding_buffer(Models *models, void *buffer, i32 size){
case special_hook_scroll_rule:
{
models->scroll_rule = (Scroll_Rule_Function*)unit->hook.func;
models->scroll_rule = (Delta_Rule_Function*)unit->hook.func;
}break;
case special_hook_buffer_name_resolver:
@ -738,23 +729,6 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings,
////////////////////////////////
internal Arena
make_arena_models(Models *models, umem chunk_size, umem align){
return(make_arena(models->base_allocator, chunk_size, align));
}
internal Arena
make_arena_models(Models *models, umem chunk_size){
return(make_arena(models->base_allocator, chunk_size, 8));
}
internal Arena
make_arena_models(Models *models){
return(make_arena(models->base_allocator, KB(16), 8));
}
////////////////////////////////
internal Models*
app_setup_memory(System_Functions *system, Application_Memory *memory){
Cursor cursor = make_cursor(memory->vars_memory, memory->vars_memory_size);
@ -931,7 +905,7 @@ App_Init_Sig(app_init){
// NOTE(allen):
global_history_init(&models->global_history);
text_layout_init(&models->app_links, &models->text_layouts);
text_layout_init(models, &models->text_layouts);
// NOTE(allen): clipboard setup
models->working_set.clipboard_max_size = ArrayCount(models->working_set.clipboards);
@ -978,7 +952,7 @@ App_Init_Sig(app_init){
}
File_Attributes attributes = {};
file_create_from_string(system, models, file, SCu8(), attributes);
file_create_from_string(models, file, SCu8(), attributes);
if (init_files[i].read_only){
file->settings.read_only = true;
history_free(&models->mem.heap, &file->state.history);
@ -986,7 +960,6 @@ App_Init_Sig(app_init){
file->settings.never_kill = true;
file_set_unimportant(file, true);
file->settings.unwrapped_lines = true;
}
// NOTE(allen): setup first panel
@ -1104,7 +1077,6 @@ App_Step_Sig(app_step){
mouse_event.keycode = key_mouse_left_release;
input->keys.keys[input->keys.count++] = mouse_event;
}
if (input->mouse.press_r){
mouse_event.keycode = key_mouse_right;
input->keys.keys[input->keys.count++] = mouse_event;
@ -1113,12 +1085,10 @@ App_Step_Sig(app_step){
mouse_event.keycode = key_mouse_right_release;
input->keys.keys[input->keys.count++] = mouse_event;
}
if (input->mouse.wheel != 0){
mouse_event.keycode = key_mouse_wheel;
input->keys.keys[input->keys.count++] = mouse_event;
}
if (input->mouse.p != models->prev_p){
b32 was_in_window = rect_contains_point(i32R(0, 0, prev_dim.x, prev_dim.y), models->prev_p);
b32 is_in_window = rect_contains_point(i32R(0, 0, current_dim.x, current_dim.y), input->mouse.p);
@ -1127,7 +1097,6 @@ App_Step_Sig(app_step){
input->keys.keys[input->keys.count++] = mouse_event;
}
}
if (models->animated_last_frame){
mouse_event.keycode = key_animate;
input->keys.keys[input->keys.count++] = mouse_event;
@ -1169,10 +1138,8 @@ App_Step_Sig(app_step){
if (models->hook_start != 0){
char **files = models->settings.init_files;
i32 files_count = models->settings.init_files_count;
char **flags = models->settings.custom_flags;
i32 flags_count = models->settings.custom_flags_count;
models->hook_start(&models->app_links, files, files_count, flags, flags_count);
}
}
@ -1303,39 +1270,17 @@ App_Step_Sig(app_step){
models->hooks[hook_buffer_viewer_update](&models->app_links);
}
// NOTE(allen): step panels
{
Panel *active_panel = layout_get_active_panel(layout);
for (Panel *panel = layout_get_first_open_panel(layout);
panel != 0;
panel = layout_get_next_open_panel(layout, panel)){
View *view = panel->view;
GUI_Scroll_Vars *scroll_vars = 0;
b32 file_scroll = false;
File_Edit_Positions edit_pos = view_get_edit_pos(view);
if (!view->ui_mode){
scroll_vars = &edit_pos.scroll;
file_scroll = true;
}
else{
scroll_vars = &view->ui_scroll;
file_scroll = false;
}
b32 active = (panel == active_panel);
GUI_Scroll_Vars new_scroll = do_step_file_view(system, models, view, panel->rect_inner, active, dt, *scroll_vars);
if (memcmp(scroll_vars, &new_scroll, sizeof(*scroll_vars)) != 0){
if (file_scroll){
view_set_scroll(system, models, view, new_scroll);
}
else{
*scroll_vars = new_scroll;
}
}
// NOTE(allen): dt
f32 literal_dt = 0.f;
u64 now_usecond_stamp = system->now_time();
if (!input->first_step){
u64 elapsed_useconds = now_usecond_stamp - models->last_render_usecond_stamp;
literal_dt = (f32)((f64)(elapsed_useconds)/1000000.f);
}
models->last_render_usecond_stamp = now_usecond_stamp;
f32 animation_dt = 0.f;
if (models->animated_last_frame){
animation_dt = literal_dt;
}
// NOTE(allen): on the first frame there should be no scrolling
@ -1344,11 +1289,57 @@ App_Step_Sig(app_step){
panel != 0;
panel = layout_get_next_open_panel(layout, panel)){
View *view = panel->view;
if (!view->ui_mode){
File_Edit_Positions edit_pos = view_get_edit_pos(view);
edit_pos.scroll.scroll_x = (f32)edit_pos.scroll.target_x;
edit_pos.scroll.scroll_y = (f32)edit_pos.scroll.target_y;
edit_pos.scroll.position = view_normalize_buffer_point(models, view, edit_pos.scroll.target);
block_zero_struct(&edit_pos.scroll.target);
view_set_edit_pos(view, edit_pos);
}
else{
view->ui_scroll.position = view->ui_scroll.target;
block_zero_struct(&view->ui_scroll.target);
}
}
}
// NOTE(allen): apply pending smooth deltas
{
Delta_Rule_Function *scroll_rule = models->scroll_rule;
for (Panel *panel = layout_get_first_open_panel(layout);
panel != 0;
panel = layout_get_next_open_panel(layout, panel)){
View *view = panel->view;
View_ID view_id = view_get_id(&models->live_set, view);
b32 new_target = (b32)view->new_scroll_target;
if (view->ui_mode){
Vec2_f32 pending = view->ui_scroll.target - view->ui_scroll.position;
if (!near_zero(pending, 0.5f)){
Vec2_f32 partial = scroll_rule(pending, view_id, new_target, animation_dt);
view->ui_scroll.position += partial;
models->animate_next_frame = true;
}
else{
view->ui_scroll.position = view->ui_scroll.target;
}
}
else{
File_Edit_Positions edit_pos = view_get_edit_pos(view);
Vec2_f32 pending = view_buffer_point_difference(models, view,
edit_pos.scroll.target, edit_pos.scroll.position);
if (!near_zero(pending, 0.5f)){
Vec2_f32 partial = scroll_rule(pending, view_id, new_target, animation_dt);
edit_pos.scroll.position = view_move_buffer_point(models, view,
edit_pos.scroll.position, partial);
view_set_edit_pos(view, edit_pos);
models->animate_next_frame = true;
}
else{
edit_pos.scroll.position = edit_pos.scroll.target;
view_set_edit_pos(view, edit_pos);
}
}
}
}
// NOTE(allen): hook for files reloaded
@ -1449,19 +1440,6 @@ App_Step_Sig(app_step){
// NOTE(allen): rendering
{
f32 literal_dt = 0.f;
u64 now_usecond_stamp = system->now_time();
if (!input->first_step){
u64 elapsed_useconds = now_usecond_stamp - models->last_render_usecond_stamp;
literal_dt = (f32)((f64)(elapsed_useconds)/1000000.f);
}
models->last_render_usecond_stamp = now_usecond_stamp;
f32 animation_dt = 0.f;
if (models->animated_last_frame){
animation_dt = literal_dt;
}
Frame_Info frame = {};
frame.index = models->frame_counter;
frame.literal_dt = literal_dt;

28
4ed_allocator_models.cpp Normal file
View File

@ -0,0 +1,28 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 27.08.2019
*
* Models based arena constructors
*
*/
// TOP
internal Arena
make_arena_models(Models *models, umem chunk_size, umem align){
return(make_arena(models->base_allocator, chunk_size, align));
}
internal Arena
make_arena_models(Models *models, umem chunk_size){
return(make_arena(models->base_allocator, chunk_size, 8));
}
internal Arena
make_arena_models(Models *models){
return(make_arena(models->base_allocator, KB(16), 8));
}
// BOTTOM

File diff suppressed because it is too large Load Diff

View File

@ -68,7 +68,7 @@ struct Models{
Command_Caller_Hook_Function *command_caller;
Render_Caller_Function *render_caller;
Input_Filter_Function *input_filter;
Scroll_Rule_Function *scroll_rule;
Delta_Rule_Function *scroll_rule;
Buffer_Name_Resolver_Function *buffer_name_resolver;
Modify_Color_Table_Function *modify_color_table;
Clipboard_Change_Hook_Function *clipboard_change;

View File

@ -59,7 +59,6 @@ struct Mem_Options{
#include "4ed_buffer.h"
#include "4ed_history.h"
#include "4ed_file.h"
#include "4ed_code_wrap.h"
#include "4ed_working_set.h"
#include "4ed_hot_directory.h"
@ -74,6 +73,7 @@ struct Mem_Options{
#include "4ed_log.h"
#include "4ed_app_models.h"
#include "4ed_allocator_models.cpp"
#include "4ed_log.cpp"
#include "4coder_log.cpp"
#include "4ed_coroutine.cpp"
@ -92,7 +92,6 @@ struct Mem_Options{
#include "4ed_history.cpp"
#include "4ed_file_lex.cpp"
#include "4ed_file.cpp"
#include "4ed_code_wrap.cpp"
#include "4ed_working_set.cpp"
#include "4ed_hot_directory.cpp"
#include "4ed_cli.cpp"
@ -101,7 +100,6 @@ struct Mem_Options{
#include "4coder_buffer_seek_constructors.cpp"
#include "4ed_view.cpp"
#include "4ed_edit.cpp"
#include "4ed_view_ui.cpp"
#include "4ed_text_layout.cpp"
#include "4ed.cpp"

File diff suppressed because it is too large Load Diff

View File

@ -12,235 +12,63 @@
#if !defined(FRED_BUFFER_H)
#define FRED_BUFFER_H
typedef i32 Buffer_Get_Chunk_Mode;
enum{
BufferGetChunk_Basic,
BufferGetChunk_ZeroTerminated,
};
struct Cursor_With_Index{
i64 pos;
i32 index;
};
struct Gap_Buffer{
char *data;
i32 size1;
i32 gap_size;
i32 size2;
i32 max;
Base_Allocator *allocator;
i32 *line_starts;
i32 line_count;
i32 line_max;
u8 *data;
i64 size1;
i64 gap_size;
i64 size2;
i64 max;
// NOTE(allen): If there are N lines I store N + 1 slots in this array with
// line_starts[N] = size of the buffer.
// The variable line_start_count stores N + 1; call buffer_line_count(buffer)
// to get "N" the actual number of lines.
i64 *line_starts;
i64 line_start_count;
i64 line_start_max;
};
struct Gap_Buffer_Init{
Gap_Buffer *buffer;
char *data;
i32 size;
};
struct Gap_Buffer_Stream{
Gap_Buffer *buffer;
char *data;
i32 end;
i32 separated;
i32 absolute_end;
b32 use_termination_character;
char terminator;
};
global Gap_Buffer_Stream null_buffer_stream = {};
struct Buffer_Chunk_Position{
i32 real_pos;
i32 chunk_pos;
i32 chunk_index;
};
struct Buffer_Batch_State{
i32 i;
i32 shift_total;
};
struct Buffer_Measure_Starts{
i32 i;
i32 count;
i32 start;
i64 real_pos;
i64 chunk_pos;
i64 chunk_index;
};
typedef u32 Buffer_Layout_Flag;
enum{
BLStatus_Finished,
BLStatus_NeedWrapLineShift,
BLStatus_NeedLineShift,
BLStatus_NeedWrapDetermination,
};
struct Buffer_Layout_Stop{
u32 status;
i32 line_index;
i32 wrap_line_index;
i32 pos;
i32 next_line_pos;
f32 x;
};
struct Buffer_Measure_Wrap_Params{
Gap_Buffer *buffer;
i32 *wrap_line_index;
System_Functions *system;
Face *face;
b32 virtual_white;
};
struct Buffer_Measure_Wrap_State{
Gap_Buffer_Stream stream;
i32 i;
i32 size;
b32 still_looping;
i32 line_index;
i32 current_wrap_index;
f32 current_adv;
f32 x;
b32 skipping_whitespace;
i32 wrap_unit_end;
b32 did_wrap;
b32 first_of_the_line;
Translation_State tran;
Translation_Emits emits;
u32 J;
Buffer_Model_Step step;
Buffer_Model_Behavior behavior;
i32 __pc__;
};
struct Buffer_Cursor_Seek_Params{
Gap_Buffer *buffer;
Buffer_Seek seek;
System_Functions *system;
Face *face;
i32 *wrap_line_index;
i32 *character_starts;
b32 virtual_white;
b32 return_hint;
Full_Cursor *cursor_out;
};
struct Buffer_Cursor_Seek_State{
Full_Cursor next_cursor;
Full_Cursor this_cursor;
Full_Cursor prev_cursor;
Gap_Buffer_Stream stream;
b32 still_looping;
i32 i;
i32 size;
i32 wrap_unit_end;
b32 first_of_the_line;
b32 xy_seek;
f32 ch_width;
i32 font_height;
Translation_State tran;
Translation_Emits emits;
u32 J;
Buffer_Model_Step step;
Buffer_Model_Behavior behavior;
i32 __pc__;
};
struct Buffer_Invert_Batch{
i32 i;
i32 shift_amount;
i32 len;
};
enum Buffer_Render_Flag{
BRFlag_Special_Character = (1 << 0),
BRFlag_Ghost_Character = (1 << 1)
};
struct Buffer_Render_Item{
i32 index;
struct Buffer_Layout_Item{
i64 index;
u32 codepoint;
u32 flags;
f32 x0;
f32 y0;
f32 x1;
f32 y1;
Buffer_Layout_Flag flags;
Rect_f32 rect;
};
struct Render_Item_Write{
Buffer_Render_Item *item;
Buffer_Render_Item *item_end;
f32 x;
f32 y;
System_Functions *system;
Face *face;
i32 font_height;
f32 x_min;
f32 x_max;
struct Buffer_Layout_Item_Block{
Buffer_Layout_Item_Block *next;
Buffer_Layout_Item *items;
i64 count;
i64 character_count;
};
struct Buffer_Render_Params{
Gap_Buffer *buffer;
Buffer_Render_Item *items;
i32 max;
i32 *count;
f32 port_x;
f32 port_y;
f32 clip_w;
f32 scroll_x;
f32 scroll_y;
f32 width;
struct Buffer_Layout_Item_List{
Buffer_Layout_Item_Block *first;
Buffer_Layout_Item_Block *last;
i32 node_count;
i32 total_count;
f32 height;
Full_Cursor start_cursor;
i32 wrapped;
System_Functions *system;
Face *face;
b32 virtual_white;
i32 wrap_slashes;
i32 one_past_last_abs_pos;
};
struct Buffer_Render_State{
Gap_Buffer_Stream stream;
b32 still_looping;
i32 i;
i32 size;
f32 shift_x;
f32 shift_y;
f32 ch_width;
Render_Item_Write write;
f32 byte_advance;
i32 line;
i32 wrap_line;
b8 skipping_whitespace;
b8 first_of_the_line;
b8 first_of_the_wrap;
i32 wrap_unit_end;
Translation_State tran;
Translation_Emits emits;
u32 J;
Buffer_Model_Step step;
Buffer_Model_Behavior behavior;
i32 __pc__;
i64 character_count;
Interval_i64 index_range;
};
#endif

View File

@ -1,941 +0,0 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 24.03.2018
*
* Code wrapping logic
*
*/
// TOP
internal void
wrap_state_init(Code_Wrap_State *state, Editing_File *file, Face *face){
state->token_array = file->state.token_array;
state->token_ptr = state->token_array.tokens;
state->end_token = state->token_ptr + state->token_array.count;
state->line_starts = file->state.buffer.line_starts;
state->line_count = file->state.buffer.line_count;
state->next_line_start = state->line_starts[1];
Gap_Buffer *buffer = &file->state.buffer;
i32 size = buffer_size(buffer);
buffer_stringify_loop(&state->stream, buffer, 0, size);
state->size = size;
state->i = 0;
state->face = face;
state->tab_indent_amount = font_get_glyph_advance(face, '\t');
state->byte_advance = face->byte_advance;
state->tran = null_buffer_translating_state;
}
internal void
wrap_state_set_top(Code_Wrap_State *state, f32 line_shift){
if (state->wrap_x.paren_nesting[state->wrap_x.paren_safe_top] > line_shift){
state->wrap_x.paren_nesting[state->wrap_x.paren_safe_top] = line_shift;
}
}
internal Code_Wrap_Step
wrap_state_consume_token(System_Functions *system, Face *face, Code_Wrap_State *state, i32 fixed_end_point){
Code_Wrap_Step result = {};
i32 i = state->i;
result.position_start = i;
Cpp_Token token = {};
token.start = state->size;
if (state->token_ptr < state->end_token){
token = *state->token_ptr;
}
if (state->consume_newline){
++i;
state->x = 0;
state->consume_newline = 0;
}
if (state->in_pp_body){
if (!(token.flags & CPP_TFLAG_PP_BODY)){
state->in_pp_body = false;
state->wrap_x = state->plane_wrap_x;
}
}
if (!state->in_pp_body){
if (token.flags & CPP_TFLAG_PP_DIRECTIVE){
state->in_pp_body = true;
state->plane_wrap_x = state->wrap_x;
state->wrap_x = null_wrap_x;
}
}
b32 skipping_whitespace = false;
if (i >= state->next_line_start){
state->x = state->wrap_x.paren_nesting[state->wrap_x.paren_safe_top];
state->x = state->wrap_x.paren_nesting[state->wrap_x.paren_safe_top];
skipping_whitespace = true;
}
// TODO(allen): exponential search this shit!
for (;i >= state->next_line_start;){
state->next_line_start = state->size;
if (state->line_index < state->line_count){
++state->line_index;
if (state->line_index + 1 < state->line_count){
state->next_line_start = state->line_starts[state->line_index + 1];
}
}
else{
break;
}
}
i32 line_start = state->size;
if (state->line_index < 0){
line_start = 0;
}
else if (state->line_index < state->line_count){
line_start = state->line_starts[state->line_index];
}
b32 still_looping = 0;
i32 end = token.start + token.size;
if (fixed_end_point >= 0 && end > fixed_end_point){
end = fixed_end_point;
}
i = clamp_bot(line_start, i);
if (i == line_start){
skipping_whitespace = true;
}
b32 recorded_start_x = false;
do{
for (; i < state->stream.end; ++i){
if (!(i < end)){
goto doublebreak;
}
u8 ch = (u8)state->stream.data[i];
translating_fully_process_byte(&state->tran, ch, i, state->size, &state->emits);
for (TRANSLATION_EMIT_LOOP(state->J, state->emits)){
TRANSLATION_GET_STEP(state->step, state->behavior, state->J, state->emits);
if (state->behavior.do_newline){
state->consume_newline = 1;
goto doublebreak;
}
else if(state->behavior.do_number_advance || state->behavior.do_codepoint_advance){
u32 n = state->step.value;
f32 adv = 0;
if (state->behavior.do_codepoint_advance){
adv = font_get_glyph_advance(state->face, n);
if (n != ' ' && n != '\t'){
skipping_whitespace = false;
}
}
else{
adv = state->byte_advance;
skipping_whitespace = false;
}
if (!skipping_whitespace){
if (!recorded_start_x){
result.start_x = state->x;
recorded_start_x = true;
}
state->x += adv;
}
}
}
}
still_looping = buffer_stringify_next(&state->stream);
}while(still_looping);
doublebreak:;
state->i = i;
b32 consume_token = false;
if (state->token_ptr < state->end_token && i >= token.start + token.size){
consume_token = true;
}
result.this_token = state->token_ptr;
if (consume_token){
Assert(state->token_ptr < state->end_token);
switch (state->token_ptr->type){
case CPP_TOKEN_BRACE_OPEN:
{
state->wrap_x.paren_nesting[state->wrap_x.paren_safe_top] += state->tab_indent_amount;
}break;
case CPP_TOKEN_BRACE_CLOSE:
{
state->wrap_x.paren_nesting[state->wrap_x.paren_safe_top] -= state->tab_indent_amount;
}break;
case CPP_TOKEN_PARENTHESE_OPEN:
case CPP_TOKEN_BRACKET_OPEN:
{
++state->wrap_x.paren_top;
i32 top = state->wrap_x.paren_top;
if (top >= ArrayCount(state->wrap_x.paren_nesting)){
top = ArrayCount(state->wrap_x.paren_nesting) - 1;
}
state->wrap_x.paren_safe_top = top;
state->wrap_x.paren_nesting[top] = state->x;
}break;
case CPP_TOKEN_PARENTHESE_CLOSE:
case CPP_TOKEN_BRACKET_CLOSE:
{
--state->wrap_x.paren_top;
if (state->wrap_x.paren_top < 0){
state->wrap_x.paren_top = 0;
}
i32 top = state->wrap_x.paren_top;
if (top >= ArrayCount(state->wrap_x.paren_nesting)){
top = ArrayCount(state->wrap_x.paren_nesting) - 1;
}
state->wrap_x.paren_safe_top = top;
}break;
}
++state->token_ptr;
if (state->token_ptr > state->end_token){
state->token_ptr = state->end_token;
}
}
result.position_end = state->i;
result.final_x = state->x;
if (!recorded_start_x){
result.start_x = state->x;
recorded_start_x = true;
}
return(result);
}
internal i32
stickieness_guess(Cpp_Token_Type type, Cpp_Token_Type other_type, u16 flags, u16 other_flags, b32 on_left){
i32 guess = 0;
b32 is_words = false;
b32 other_is_words = false;
Cpp_Token_Category cat = cpp_token_category_from_type(type);
Cpp_Token_Category other_cat = cpp_token_category_from_type(other_type);
if (type == CPP_TOKEN_IDENTIFIER || (CPP_TOKEN_CAT_TYPE <= cat && cat <= CPP_TOKEN_CAT_OTHER)){
is_words = true;
}
if (other_type == CPP_TOKEN_IDENTIFIER || (CPP_TOKEN_CAT_TYPE <= other_cat && other_cat <= CPP_TOKEN_CAT_OTHER)){
other_is_words = true;
}
b32 is_operator = 0, other_is_operator = 0;
if (flags & CPP_TFLAG_IS_OPERATOR){
is_operator = 1;
}
if (other_flags & CPP_TFLAG_IS_OPERATOR){
other_is_operator = 1;
}
i32 operator_side_bias = 70*(!on_left);
if (is_words && other_is_words){
guess = 200;
}
else if (type == CPP_TOKEN_PARENTHESE_OPEN){
if (on_left){
guess = 100;
}
else{
if (other_is_words){
guess = 100;
}
else{
guess = 0;
}
}
}
else if (type == CPP_TOKEN_SEMICOLON){
if (on_left){
guess = 0;
}
else{
guess = 1000;
}
}
else if (type == CPP_TOKEN_COMMA){
guess = 20;
}
else if (type == CPP_TOKEN_COLON ||
type == CPP_TOKEN_PARENTHESE_CLOSE ||
type == CPP_TOKEN_BRACKET_OPEN ||
type == CPP_TOKEN_BRACKET_CLOSE){
if (on_left){
guess = 20;
if (other_is_words){
guess = 100;
}
}
else{
guess = 100;
}
}
else if (type == CPP_PP_DEFINED){
if (on_left){
guess = 100;
}
else{
guess = 0;
}
}
else if (type == CPP_TOKEN_SCOPE){
guess = 90;
}
else if (type == CPP_TOKEN_MINUS){
if (on_left){
guess = 80;
}
else{
guess = 60;
}
}
else if (type == CPP_TOKEN_DOT ||
type == CPP_TOKEN_ARROW){
guess = 200;
}
else if (type == CPP_TOKEN_NOT ||
type == CPP_TOKEN_TILDE){
if (on_left){
guess = 80;
}
else{
guess = 20;
}
}
else if (type == CPP_TOKEN_INCREMENT ||
type == CPP_TOKEN_DECREMENT ||
type == CPP_TOKEN_STAR ||
type == CPP_TOKEN_AMPERSAND ||
(type >= CPP_TOKEN_POSTINC &&
type <= CPP_TOKEN_DELETE_ARRAY)){
guess = 80;
if (!on_left && other_is_operator){
guess = 20;
}
}
else if (type >= CPP_TOKEN_MUL && type <= CPP_TOKEN_MOD){
guess = 70;
}
else if (type == CPP_TOKEN_PLUS){
guess = 60 + operator_side_bias;
}
else if (type >= CPP_TOKEN_LSHIFT && type <= CPP_TOKEN_RSHIFT){
guess = 50;
}
else if (type >= CPP_TOKEN_LESS && type <= CPP_TOKEN_NOTEQ){
guess = 40 + operator_side_bias;
}
else if (type >= CPP_TOKEN_BIT_XOR && type <= CPP_TOKEN_BIT_OR){
guess = 40;
}
else if (type >= CPP_TOKEN_AND && type <= CPP_TOKEN_OR){
guess = 30 + operator_side_bias;
}
else if (type >= CPP_TOKEN_TERNARY_QMARK && type <= CPP_TOKEN_COLON){
guess = 20 + operator_side_bias;
}
else if (type == CPP_TOKEN_THROW){
if (on_left){
guess = 100;
}
else{
guess = 0;
}
}
else if (type >= CPP_TOKEN_EQ && type <= CPP_TOKEN_XOREQ){
guess = 15 + operator_side_bias;
}
return(guess);
}
internal Wrap_Current_Shift
get_current_shift(Code_Wrap_State *wrap_state, i32 next_line_start){
Wrap_Current_Shift result = {};
result.shift = wrap_state->wrap_x.paren_nesting[wrap_state->wrap_x.paren_safe_top];
Cpp_Token next_token = {};
if (wrap_state->token_ptr < wrap_state->end_token){
next_token = *wrap_state->token_ptr;
}
if (wrap_state->token_ptr > wrap_state->token_array.tokens){
Cpp_Token prev_token = *(wrap_state->token_ptr-1);
if (wrap_state->wrap_x.paren_safe_top != 0 && prev_token.type == CPP_TOKEN_PARENTHESE_OPEN){
result.shift = wrap_state->wrap_x.paren_nesting[wrap_state->wrap_x.paren_safe_top-1] + wrap_state->tab_indent_amount;
result.adjust_top_to_this = 1;
}
f32 statement_continuation_indent = 0.f;
if (result.shift != 0.f && wrap_state->wrap_x.paren_safe_top == 0){
if (!(prev_token.flags & (CPP_TFLAG_PP_DIRECTIVE|CPP_TFLAG_PP_BODY))){
switch (prev_token.type){
case CPP_TOKEN_BRACKET_OPEN:
case CPP_TOKEN_BRACE_OPEN:
case CPP_TOKEN_BRACE_CLOSE:
case CPP_TOKEN_SEMICOLON:
case CPP_TOKEN_COLON:
case CPP_TOKEN_COMMA:
case CPP_TOKEN_COMMENT: break;
default: statement_continuation_indent += wrap_state->tab_indent_amount; break;
}
}
}
switch (next_token.type){
case CPP_TOKEN_BRACE_CLOSE: case CPP_TOKEN_BRACE_OPEN: break;
default: result.shift += statement_continuation_indent; break;
}
}
if (next_token.start < next_line_start){
if (next_token.flags & CPP_TFLAG_PP_DIRECTIVE){
result.shift = 0;
}
else{
switch (next_token.type){
case CPP_TOKEN_BRACE_CLOSE:
{
if (wrap_state->wrap_x.paren_safe_top == 0){
result.shift -= wrap_state->tab_indent_amount;
}
}break;
}
}
}
result.shift = clamp_bot(0.f, result.shift);
return(result);
}
internal void
file_measure_wraps(System_Functions *system, Mem_Options *mem, Editing_File *file, Face *face){
Heap *heap = &mem->heap;
Arena *scratch = &mem->arena;
Temp_Memory temp = begin_temp(scratch);
file_allocate_wraps_as_needed(heap, file);
file_allocate_indents_as_needed(heap, file, file->state.buffer.line_count);
file_allocate_wrap_positions_as_needed(heap, file, file->state.buffer.line_count);
Buffer_Measure_Wrap_Params params;
params.buffer = &file->state.buffer;
params.wrap_line_index = file->state.wrap_line_index;
params.system = system;
params.face = face;
params.virtual_white = file->settings.virtual_white;
f32 width = (f32)file->settings.display_width;
f32 minimum_base_width = (f32)file->settings.minimum_base_display_width;
i32 size = buffer_size(params.buffer);
Buffer_Measure_Wrap_State state = {};
Buffer_Layout_Stop stop = {};
f32 edge_tolerance = 50.f;
edge_tolerance = clamp_top(edge_tolerance, 50.f);
f32 current_line_shift = 0.f;
b32 do_wrap = 0;
i32 wrap_unit_end = 0;
i32 wrap_position_index = 0;
file->state.wrap_positions[wrap_position_index++] = 0;
Code_Wrap_State wrap_state = {};
b32 use_tokens = false;
// TODO(allen): REWRITE REWRITE REWRITE
Wrap_Indent_Pair *wrap_indent_marks = 0;
Potential_Wrap_Indent_Pair *potential_marks = 0;
i32 max_wrap_indent_mark = Million(1);
if (params.virtual_white && file->state.token_array.tokens != 0){
wrap_state_init(&wrap_state, file, face);
use_tokens = true;
potential_marks = push_array(scratch, Potential_Wrap_Indent_Pair, floor32(width));
wrap_indent_marks = push_array(scratch, Wrap_Indent_Pair, max_wrap_indent_mark);
}
i32 real_count = 0;
i32 potential_count = 0;
i32 stage = 0;
do{
stop = buffer_measure_wrap_y(&state, params, current_line_shift, do_wrap, wrap_unit_end);
switch (stop.status){
case BLStatus_NeedWrapDetermination:
{
if (use_tokens){
if (stage == 0){
do_wrap = 0;
wrap_unit_end = wrap_indent_marks[stage+1].wrap_position;
++stage;
}
else{
do_wrap = 1;
wrap_unit_end = wrap_indent_marks[stage+1].wrap_position;
file_allocate_wrap_positions_as_needed(heap, file, wrap_position_index);
file->state.wrap_positions[wrap_position_index++] = stop.pos;
}
}
else{
Translation_State tran = {};
Translation_Emits emits = {};
Gap_Buffer_Stream stream = {};
i32 word_stage = 0;
i32 i = stop.pos;
f32 x = stop.x;
f32 self_x = 0;
i32 wrap_end_result = size;
if (buffer_stringify_loop(&stream, params.buffer, i, size)){
b32 still_looping = false;
do{
for (; i < stream.end; ++i){
{
u8 ch = stream.data[i];
translating_fully_process_byte(&tran, ch, i, size, &emits);
}
for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){
TRANSLATION_DECL_GET_STEP(step, behavior, J, emits);
u32 codepoint = step.value;
switch (word_stage){
case 0:
{
if (codepoint_is_whitespace(codepoint)){
word_stage = 1;
}
else{
f32 adv = font_get_glyph_advance(params.face, codepoint);
x += adv;
self_x += adv;
if (self_x > width){
wrap_end_result = step.i;
goto doublebreak;
}
}
}break;
case 1:
{
if (!codepoint_is_whitespace(codepoint)){
wrap_end_result = step.i;
goto doublebreak;
}
}break;
}
}
}
still_looping = buffer_stringify_next(&stream);
}while(still_looping);
}
doublebreak:;
wrap_unit_end = wrap_end_result;
if (x > width){
do_wrap = 1;
file_allocate_wrap_positions_as_needed(heap, file, wrap_position_index);
file->state.wrap_positions[wrap_position_index++] = stop.pos;
}
else{
do_wrap = 0;
}
}
}break;
case BLStatus_NeedWrapLineShift:
case BLStatus_NeedLineShift:
{
f32 current_width = width;
if (use_tokens){
Code_Wrap_State original_wrap_state = wrap_state;
i32 next_line_start = buffer_size(params.buffer);
if (stop.line_index+1 < params.buffer->line_count){
next_line_start = params.buffer->line_starts[stop.line_index+1];
}
f32 base_adjusted_width = wrap_state.wrap_x.base_x + minimum_base_width;
if (minimum_base_width != 0 && current_width < base_adjusted_width){
current_width = base_adjusted_width;
}
if (stop.status == BLStatus_NeedLineShift){
real_count = 0;
potential_count = 0;
stage = 0;
Wrap_Current_Shift current_shift = get_current_shift(&wrap_state, next_line_start);
if (current_shift.adjust_top_to_this){
wrap_state_set_top(&wrap_state, current_shift.shift);
}
wrap_indent_marks[real_count].wrap_position = 0;
wrap_indent_marks[real_count].line_shift =current_shift.shift;
++real_count;
wrap_state.wrap_x.base_x = wrap_state.wrap_x.paren_nesting[0];
for (; wrap_state.token_ptr < wrap_state.end_token; ){
Code_Wrap_Step step = {};
b32 emit_comment_position = false;
b32 first_word = true;
if (wrap_state.token_ptr->type == CPP_TOKEN_COMMENT || wrap_state.token_ptr->type == CPP_TOKEN_STRING_CONSTANT){
i32 i = wrap_state.token_ptr->start;
i32 end_i = i + wrap_state.token_ptr->size;
if (i < wrap_state.i){
i = wrap_state.i;
}
if (end_i > wrap_state.next_line_start){
end_i = wrap_state.next_line_start;
}
f32 x = wrap_state.x;
step.position_start = i;
step.start_x = x;
step.this_token = wrap_state.token_ptr;
Gap_Buffer_Stream stream = {};
Translation_State tran = {};
Translation_Emits emits = {};
Potential_Wrap_Indent_Pair potential_wrap = {};
potential_wrap.wrap_position = i;
potential_wrap.line_shift = x;
potential_wrap.wrappable_score = 5;
potential_wrap.wrap_x = x;
potential_wrap.adjust_top_to_this = 0;
if (buffer_stringify_loop(&stream, params.buffer, i, end_i)){
b32 still_looping = true;
while(still_looping){
for (; i < stream.end; ++i){
{
u8 ch = stream.data[i];
translating_fully_process_byte(&tran, ch, i, end_i, &emits);
}
for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){
TRANSLATION_DECL_GET_STEP(buffer_step, behav, J, emits);
if (!codepoint_is_whitespace(buffer_step.value)){
i = buffer_step.i;
goto doublebreak_stage_vspace;
}
}
}
still_looping = buffer_stringify_next(&stream);
}
doublebreak_stage_vspace:;
do{
i32 pos_end_i = end_i;
while (still_looping){
for (; i < stream.end; ++i){
{
u8 ch = stream.data[i];
translating_fully_process_byte(&tran, ch, i, end_i, &emits);
}
for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){
TRANSLATION_DECL_GET_STEP(buffer_step, behav, J, emits);
if (codepoint_is_whitespace(buffer_step.value)){
pos_end_i = buffer_step.i;
goto doublebreak_stage1;
}
f32 adv = font_get_glyph_advance(params.face, buffer_step.value);
x += adv;
if (!first_word && x > current_width){
pos_end_i = buffer_step.i;
emit_comment_position = true;
goto doublebreak_stage1;
}
}
}
still_looping = buffer_stringify_next(&stream);
}
doublebreak_stage1:;
first_word = 0;
if (emit_comment_position){
step.position_end = pos_end_i;
step.final_x = x;
goto finished_comment_split;
}
while(still_looping){
for (; i < stream.end; ++i){
{
u8 ch = stream.data[i];
translating_fully_process_byte(&tran, ch, i, end_i, &emits);
}
for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){
TRANSLATION_DECL_GET_STEP(buffer_step, behav, J, emits);
if (!codepoint_is_whitespace(buffer_step.value)){
pos_end_i = buffer_step.i;
goto doublebreak_stage2;
}
f32 adv = font_get_glyph_advance(params.face, buffer_step.value);
x += adv;
}
}
still_looping = buffer_stringify_next(&stream);
}
doublebreak_stage2:;
potential_wrap.wrap_position = pos_end_i;
potential_wrap.wrap_x = x;
}while(still_looping);
}
finished_comment_split:;
if (emit_comment_position){
potential_marks[potential_count] = potential_wrap;
++potential_count;
}
}
if (!emit_comment_position){
step = wrap_state_consume_token(system, face, &wrap_state, next_line_start);
}
b32 need_to_choose_a_wrap = false;
if (step.final_x > current_width){
need_to_choose_a_wrap = true;
}
current_shift = get_current_shift(&wrap_state, next_line_start);
b32 next_token_is_on_line = false;
if (wrap_state.token_ptr < wrap_state.end_token){
if (wrap_state.token_ptr->start < next_line_start){
next_token_is_on_line = true;
}
}
i32 next_wrap_position = step.position_end;
f32 wrap_x = step.final_x;
if (next_token_is_on_line){
if (wrap_state.token_ptr < wrap_state.end_token){
i32 pos_i = wrap_state.token_ptr->start;
if (pos_i > step.position_start && next_wrap_position < pos_i){
next_wrap_position = pos_i;
}
}
}
if (!need_to_choose_a_wrap){
i32 wrappable_score = 1;
Cpp_Token *this_token = step.this_token;
Cpp_Token *next_token = 0;
if (wrap_state.token_ptr < wrap_state.end_token){
next_token = wrap_state.token_ptr;
}
Cpp_Token_Type this_type = this_token->type;
Cpp_Token_Type next_type = CPP_TOKEN_JUNK;
u16 this_flags = this_token->flags;
u16 next_flags = 0;
if (this_token == next_token || !next_token_is_on_line){
next_token = 0;
}
if (next_token){
next_type = next_token->type;
next_flags = next_token->flags;
}
i32 this_stickieness = stickieness_guess(this_type, next_type, this_flags, next_flags, 1);
i32 next_stickieness = 0;
if (next_token){
next_stickieness = stickieness_guess(next_type, this_type, next_flags, this_flags, 0);
}
i32 heap_stickieness = this_stickieness;
if (heap_stickieness < next_stickieness){
heap_stickieness = next_stickieness;
}
if (wrap_state.wrap_x.paren_top != 0 && this_type == CPP_TOKEN_COMMA){
heap_stickieness = 0;
}
wrappable_score = 64*50;
wrappable_score += 101 - heap_stickieness - wrap_state.wrap_x.paren_safe_top*80;
potential_marks[potential_count].wrap_position = next_wrap_position;
potential_marks[potential_count].line_shift = current_shift.shift;
potential_marks[potential_count].wrappable_score = wrappable_score;
potential_marks[potential_count].wrap_x = wrap_x;
potential_marks[potential_count].adjust_top_to_this = current_shift.adjust_top_to_this;
++potential_count;
}
if (need_to_choose_a_wrap){
if (potential_count == 0){
wrap_indent_marks[real_count].wrap_position = next_wrap_position;
wrap_indent_marks[real_count].line_shift = current_shift.shift;
++real_count;
}
else{
i32 i = 0, best_i = 0;
i32 best_score = -1;
f32 best_x_shift = 0;
f32 x_gain_threshold = 18.f;
for (; i < potential_count; ++i){
i32 this_score = potential_marks[i].wrappable_score;
f32 x_shift = potential_marks[i].wrap_x - potential_marks[i].line_shift;
f32 x_shift_adjusted = x_shift - x_gain_threshold;
f32 x_left_over = step.final_x - x_shift;
if (x_shift_adjusted < 0){
this_score = 0;
}
else if (x_left_over <= x_gain_threshold){
this_score = 1;
}
if (this_score > best_score){
best_score = this_score;
best_x_shift = x_shift;
best_i = i;
}
else if (this_score == best_score && x_shift > best_x_shift){
best_x_shift = x_shift;
best_i = i;
}
}
i32 wrap_position = potential_marks[best_i].wrap_position;
f32 line_shift = potential_marks[best_i].line_shift;
b32 adjust_top_to_this = potential_marks[best_i].adjust_top_to_this;
wrap_indent_marks[real_count].wrap_position = wrap_position;
wrap_indent_marks[real_count].line_shift = line_shift;
++real_count;
potential_count = 0;
wrap_state = original_wrap_state;
for (;;){
step = wrap_state_consume_token(system, face, &wrap_state, wrap_position);
if (step.position_end >= wrap_position){
break;
}
}
wrap_state.x = line_shift;
wrap_state.i = wrap_position;
if (adjust_top_to_this){
wrap_state_set_top(&wrap_state, line_shift);
}
original_wrap_state = wrap_state;
}
}
if (step.position_end >= next_line_start-1){
break;
}
}
wrap_indent_marks[real_count].wrap_position = next_line_start;
wrap_indent_marks[real_count].line_shift = 0;
++real_count;
for (i32 l = 0; wrap_state.i < next_line_start && l < 3; ++l){
wrap_state_consume_token(system, face, &wrap_state, next_line_start);
}
}
current_line_shift = wrap_indent_marks[stage].line_shift;
if (stage > 0){
++stage;
}
current_line_shift = clamp_bot(0.f, current_line_shift);
}
else{
current_line_shift = 0.f;
}
current_line_shift = clamp_top(current_line_shift, current_width - edge_tolerance);
if (stop.wrap_line_index >= file->state.line_indent_max){
file_allocate_indents_as_needed(heap, file, stop.wrap_line_index);
}
file->state.line_indents[stop.wrap_line_index] = current_line_shift;
file->state.wrap_line_count = stop.wrap_line_index;
}break;
}
}while(stop.status != BLStatus_Finished);
++file->state.wrap_line_count;
file_allocate_wrap_positions_as_needed(heap, file, wrap_position_index);
file->state.wrap_positions[wrap_position_index++] = size;
file->state.wrap_position_count = wrap_position_index;
end_temp(temp);
}
// BOTTOM

View File

@ -1,77 +0,0 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 24.03.2018
*
* Code wrapping logic
*
*/
// TOP
#if !defined(FRED_CODE_WRAP_H)
#define FRED_CODE_WRAP_H
struct Code_Wrap_X{
f32 base_x;
f32 paren_nesting[32];
i32 paren_safe_top;
i32 paren_top;
};
global Code_Wrap_X null_wrap_x = {};
struct Code_Wrap_State{
Cpp_Token_Array token_array;
Cpp_Token *token_ptr;
Cpp_Token *end_token;
Code_Wrap_X wrap_x;
b32 in_pp_body;
Code_Wrap_X plane_wrap_x;
i32 *line_starts;
i32 line_count;
i32 line_index;
i32 next_line_start;
f32 x;
b32 consume_newline;
Gap_Buffer_Stream stream;
i32 size;
i32 i;
Face *face;
f32 tab_indent_amount;
f32 byte_advance;
Translation_State tran;
Translation_Emits emits;
u32 J;
Buffer_Model_Step step;
Buffer_Model_Behavior behavior;
};
struct Code_Wrap_Step{
i32 position_start;
i32 position_end;
f32 start_x;
f32 final_x;
Cpp_Token *this_token;
};
struct Wrap_Current_Shift{
f32 shift;
b32 adjust_top_to_this;
};
internal void
file_measure_wraps(System_Functions *system, Mem_Options *mem, Editing_File *file, Face *face);
#endif
// BOTTOM

View File

@ -14,18 +14,6 @@ edit_pre_state_change(Models *models, Heap *heap, Editing_File *file){
System_Functions *system = models->system;
file_add_dirty_flag(file, DirtyState_UnsavedChanges);
file_unmark_edit_finished(&models->working_set, file);
Layout *layout = &models->layout;
for (Panel *panel = layout_get_first_open_panel(layout);
panel != 0;
panel = layout_get_next_open_panel(layout, panel)){
View *view = panel->view;
if (view->file == file){
Full_Cursor render_cursor = view_get_render_cursor(models, view);
Full_Cursor target_cursor = view_get_render_cursor_target(models, view);
view->temp_view_top_left_pos = (i32)render_cursor.pos;
view->temp_view_top_left_target_pos = (i32)target_cursor.pos;
}
}
}
internal void
@ -83,7 +71,7 @@ edit_fix_markers__compute_scroll_y(i32 line_height, i32 old_y_val, f32 new_y_val
}
internal void
edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, Edit edit){
edit_fix_markers(Models *models, Editing_File *file, Edit edit){
Layout *layout = &models->layout;
Lifetime_Object *file_lifetime_object = file->lifetime_object;
@ -127,8 +115,6 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, E
File_Edit_Positions edit_pos = view_get_edit_pos(view);
write_cursor_with_index(cursors, &cursor_count, (i32)edit_pos.cursor_pos);
write_cursor_with_index(cursors, &cursor_count, (i32)view->mark);
write_cursor_with_index(cursors, &cursor_count, view->temp_view_top_left_pos);
write_cursor_with_index(cursors, &cursor_count, view->temp_view_top_left_target_pos);
}
}
@ -152,8 +138,8 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, E
if (cursor_count > 0 || r_cursor_count > 0){
buffer_sort_cursors( cursors, cursor_count);
buffer_sort_cursors(r_cursors, r_cursor_count);
buffer_update_cursors( cursors, cursor_count, edit.range.first, edit.range.one_past_last, edit.length, false);
buffer_update_cursors(r_cursors, r_cursor_count, edit.range.first, edit.range.one_past_last, edit.length, true);
buffer_update_cursors( cursors, cursor_count, edit.range.first, edit.range.one_past_last, edit.text.size, false);
buffer_update_cursors(r_cursors, r_cursor_count, edit.range.first, edit.range.one_past_last, edit.text.size, true);
buffer_unsort_cursors( cursors, cursor_count);
buffer_unsort_cursors(r_cursors, r_cursor_count);
@ -168,41 +154,9 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, E
View *view = panel->view;
if (view->file == file){
i64 cursor_pos = cursors[cursor_count++].pos;
Full_Cursor new_cursor = file_compute_cursor(models, file, seek_pos(cursor_pos));
File_Edit_Positions edit_pos = view_get_edit_pos(view);
GUI_Scroll_Vars scroll = edit_pos.scroll;
view->mark = cursors[cursor_count++].pos;
i32 line_height = (i32)face->height;
i64 top_left_pos = cursors[cursor_count++].pos;
i64 top_left_target_pos = cursors[cursor_count++].pos;
f32 new_y_val_aligned = 0;
if (view->temp_view_top_left_pos != top_left_pos){
Full_Cursor new_position_cursor = file_compute_cursor(models, file, seek_pos(top_left_pos));
if (file->settings.unwrapped_lines){
new_y_val_aligned = new_position_cursor.unwrapped_y;
}
else{
new_y_val_aligned = new_position_cursor.wrapped_y;
}
scroll.scroll_y = edit_fix_markers__compute_scroll_y(line_height, scroll.scroll_y, new_y_val_aligned);
}
if (view->temp_view_top_left_target_pos != top_left_target_pos){
if (top_left_target_pos != top_left_pos){
Full_Cursor new_position_cursor = file_compute_cursor(models, file, seek_pos(top_left_target_pos));
if (file->settings.unwrapped_lines){
new_y_val_aligned = new_position_cursor.unwrapped_y;
}
else{
new_y_val_aligned = new_position_cursor.wrapped_y;
}
}
scroll.target_y = edit_fix_markers__compute_scroll_y(line_height, scroll.target_y, new_y_val_aligned);
}
view_set_cursor_and_scroll(models, view, new_cursor, true, scroll);
File_Edit_Positions edit_pos = view_get_edit_pos(view);
view_set_cursor_and_scroll(models, view, cursor_pos, true, edit_pos.scroll);
}
}
@ -226,19 +180,18 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, E
}
internal void
edit_single(System_Functions *system, Models *models, Editing_File *file, Range range, String_Const_u8 string, Edit_Behaviors behaviors){
edit_single(Models *models, Editing_File *file, Interval_i64 range, String_Const_u8 string, Edit_Behaviors behaviors){
Edit edit = {};
edit.str = (char*)string.str;
edit.length = (i32)string.size;
edit.text = string;
edit.range = range;
Gap_Buffer *buffer = &file->state.buffer;
Assert(0 <= edit.range.first);
Assert(edit.range.first <= edit.range.one_past_last);
Assert(edit.range.one_past_last <= buffer_size(buffer));
Heap *heap = &models->mem.heap;
Arena *scratch = &models->mem.arena;
// NOTE(allen): history update
if (!behaviors.do_not_post_to_history){
@ -253,61 +206,34 @@ edit_single(System_Functions *system, Models *models, Editing_File *file, Range
// NOTE(allen): edit range hook
if (models->hook_file_edit_range != 0){
models->hook_file_edit_range(&models->app_links, file->id, edit.range, SCu8(edit.str, edit.length));
models->hook_file_edit_range(&models->app_links, file->id, edit.range, edit.text);
}
// NOTE(allen): expand spec, compute shift
i32 shift_amount = buffer_replace_range_compute_shift(edit.range.first, edit.range.one_past_last, edit.length);
i64 shift_amount = replace_range_shift(edit.range, (i64)edit.text.size);
// NOTE(allen): actual text replacement
i32 request_amount = 0;
for (;buffer_replace_range(buffer, edit.range.first, edit.range.one_past_last, edit.str, edit.length, shift_amount, &request_amount);){
void *new_data = 0;
if (request_amount > 0){
new_data = heap_allocate(heap, request_amount);
}
void *old_data = buffer_edit_provide_memory(buffer, new_data, request_amount);
if (old_data != 0){
heap_free(heap, old_data);
}
}
buffer_replace_range(buffer, edit.range, edit.text, shift_amount);
// NOTE(allen): line meta data
i32 line_start = buffer_get_line_number(buffer, edit.range.first);
i32 line_end = buffer_get_line_number(buffer, edit.range.one_past_last);
i32 replaced_line_count = line_end - line_start;
i32 new_line_count = buffer_count_newlines(buffer, edit.range.first, edit.range.first + edit.length);
i32 line_shift = new_line_count - replaced_line_count;
i64 line_start = buffer_get_line_index(buffer, edit.range.first);
i64 line_end = buffer_get_line_index(buffer, edit.range.one_past_last);
i64 replaced_line_count = line_end - line_start;
i64 new_line_count = buffer_count_newlines(scratch, buffer, edit.range.first, edit.range.first + edit.text.size);
i64 line_shift = new_line_count - replaced_line_count;
file_grow_starts_as_needed(heap, buffer, line_shift);
buffer_remeasure_starts(buffer, line_start, line_end, line_shift, shift_amount);
file_allocate_character_starts_as_needed(heap, file);
buffer_remeasure_character_starts(system, buffer, line_start, line_end, line_shift, file->state.character_starts, 0, file->settings.virtual_white);
buffer_remeasure_starts(scratch, buffer, Ii64(line_start, line_end + 1), line_shift, shift_amount);
// NOTE(allen): token fixing
if (file->settings.tokens_exist){
file_relex(system, models, file, edit.range.first, edit.range.one_past_last, shift_amount);
file_relex(models->system, models, file, edit.range.first, edit.range.one_past_last, shift_amount);
}
// NOTE(allen): wrap meta data
Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id);
Assert(face != 0);
file_measure_wraps(system, &models->mem, file, face);
// NOTE(allen): cursor fixing
edit_fix_markers(system, models, file, edit);
edit_fix_markers(models, file, edit);
// NOTE(allen): mark edit finished
if (file->settings.tokens_exist){
if (file->settings.virtual_white){
file_mark_edit_finished(&models->working_set, file);
}
}
else{
file_mark_edit_finished(&models->working_set, file);
}
}
internal void
@ -329,9 +255,9 @@ edit__apply_record_forward(System_Functions *system, Models *models, Editing_Fil
switch (record->kind){
case RecordKind_Single:
{
String_Const_u8 str = SCu8(record->single.str_forward, record->single.length_forward);
Range range = make_range(record->single.first, record->single.first + record->single.length_backward);
edit_single(system, models, file, range, str, behaviors_prototype);
String_Const_u8 str = record->single.forward_text;
Interval_i64 range = Ii64(record->single.first, record->single.first + record->single.backward_text.size);
edit_single(models, file, range, str, behaviors_prototype);
}break;
case RecordKind_Group:
@ -360,9 +286,9 @@ edit__apply_record_backward(System_Functions *system, Models *models, Editing_Fi
switch (record->kind){
case RecordKind_Single:
{
String_Const_u8 str = SCu8(record->single.str_backward, record->single.length_backward);
Range range = make_range(record->single.first, record->single.first + record->single.length_forward);
edit_single(system, models, file, range, str, behaviors_prototype);
String_Const_u8 str = record->single.backward_text;
Interval_i64 range = Ii64(record->single.first, record->single.first + record->single.forward_text.size);
edit_single(models, file, range, str, behaviors_prototype);
}break;
case RecordKind_Group:
@ -464,26 +390,28 @@ edit_merge_history_range(Models *models, Editing_File *file, History_Record_Inde
}
internal b32
edit_batch(System_Functions *system, Models *models, Editing_File *file, char *str, Buffer_Edit *edits, i32 edit_count, Edit_Behaviors behaviors){
edit_batch(Models *models, Editing_File *file, Batch_Edit *batch, Edit_Behaviors behaviors){
b32 result = true;
if (edit_count > 0){
if (batch != 0){
History_Record_Index start_index = 0;
if (history_is_activated(&file->state.history)){
start_index = file->state.current_record_index;
}
Buffer_Edit *edit_in = edits;
Buffer_Edit *one_past_last = edits + edit_count;
i32 shift = 0;
for (;edit_in < one_past_last; edit_in += 1){
String_Const_u8 insert_string = SCu8(str + edit_in->str_start, edit_in->len);
Range edit_range = make_range(edit_in->start, edit_in->end);
i64 shift = 0;
for (Batch_Edit *edit = batch;
edit != 0;
edit = edit->next){
String_Const_u8 insert_string = edit->edit.text;
Interval_i64 edit_range = edit->edit.range;
edit_range.first += shift;
edit_range.one_past_last += shift;
i32 size = buffer_size(&file->state.buffer);
if (0 <= edit_range.first && edit_range.first <= edit_range.one_past_last && edit_range.one_past_last <= size){
edit_single(system, models, file, edit_range, insert_string, behaviors);
shift += replace_range_compute_shift(edit_range, (i32)insert_string.size);
i64 size = buffer_size(&file->state.buffer);
if (0 <= edit_range.first &&
edit_range.first <= edit_range.one_past_last &&
edit_range.one_past_last <= size){
edit_single(models, file, edit_range, insert_string, behaviors);
shift += replace_range_shift(edit_range, insert_string.size);
}
else{
result = false;
@ -568,7 +496,7 @@ create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags)
String_Const_u8 front = string_front_of_path(file_name);
buffer_bind_name(models, heap, scratch, working_set, file, front);
File_Attributes attributes = {};
file_create_from_string(system, models, file, SCu8(""), attributes);
file_create_from_string(models, file, SCu8(""), attributes);
result = file;
}
}
@ -591,7 +519,7 @@ create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags)
file_bind_file_name(system, heap, working_set, file, string_from_file_name(&canon));
String_Const_u8 front = string_front_of_path(file_name);
buffer_bind_name(models, heap, scratch, working_set, file, front);
file_create_from_string(system, models, file, SCu8(buffer, (i32)attributes.size), attributes);
file_create_from_string(models, file, SCu8(buffer, (i32)attributes.size), attributes);
result = file;
}
}
@ -613,10 +541,10 @@ create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags)
}
if (file != 0 && HasFlag(flags, BufferCreate_AlwaysNew)){
i32 size = buffer_size(&file->state.buffer);
i64 size = buffer_size(&file->state.buffer);
if (size > 0){
Edit_Behaviors behaviors = {};
edit_single(system, models, file, make_range(0, size), string_u8_litexpr(""), behaviors);
edit_single(models, file, Ii64(0, size), string_u8_litexpr(""), behaviors);
if (has_canon_name){
buffer_is_for_new_file = true;
}

View File

@ -12,17 +12,6 @@
#if !defined(FRED_EDIT_H)
#define FRED_EDIT_H
struct Edit{
char *str;
i32 length;
Range range;
};
struct Edit_Array{
Edit *vals;
i32 count;
};
struct Edit_Behaviors{
b32 do_not_post_to_history;
};

View File

@ -17,14 +17,13 @@ string_from_file_name(Editing_File_Name *name){
////////////////////////////////
internal void
file_edit_positions_set_cursor(File_Edit_Positions *edit_pos, i32 pos){
file_edit_positions_set_cursor(File_Edit_Positions *edit_pos, i64 pos){
edit_pos->cursor_pos = pos;
edit_pos->last_set_type = EditPos_CursorSet;
}
internal void
file_edit_positions_set_scroll(File_Edit_Positions *edit_pos, GUI_Scroll_Vars scroll, i32 max_y){
scroll.target_y = clamp(0, scroll.target_y, max_y);
file_edit_positions_set_scroll(File_Edit_Positions *edit_pos, Buffer_Scroll scroll){
edit_pos->scroll = scroll;
edit_pos->last_set_type = EditPos_ScrollSet;
}
@ -152,35 +151,7 @@ save_file_to_name(System_Functions *system, Models *models, Editing_File *file,
Gap_Buffer *buffer = &file->state.buffer;
b32 dos_write_mode = file->settings.dos_write_mode;
i32 max = 0;
if (dos_write_mode){
max = buffer_size(buffer) + buffer->line_count + 1;
}
else{
max = buffer_size(buffer);
}
Arena *scratch = &mem->arena;
Temp_Memory temp = begin_temp(scratch);
char empty = 0;
char *data = 0;
if (max == 0){
data = &empty;
}
else{
data = (char*)push_array(scratch, char, max);
}
Assert(data != 0);
i32 size = 0;
if (dos_write_mode){
size = buffer_convert_out(buffer, data, max);
}
else{
size = max;
buffer_stringify(buffer, 0, size, data);
}
if (!using_actual_file_name){
String_Const_u8 s_file_name = SCu8(file_name);
String_Const_u8 canonical_file_name = system->get_canonical(scratch, s_file_name);
@ -189,7 +160,10 @@ save_file_to_name(System_Functions *system, Models *models, Editing_File *file,
}
}
File_Attributes new_attributes = system->save_file(scratch, (char*)file_name, data, size);
Temp_Memory temp = begin_temp(scratch);
String_Const_u8 saveable_string = buffer_stringify(scratch, buffer, Ii64(0, buffer_size(buffer)));
File_Attributes new_attributes = system->save_file(scratch, (char*)file_name, saveable_string);
if (new_attributes.last_write_time > 0){
if (using_actual_file_name){
file->state.ignore_behind_os = 1;
@ -208,233 +182,42 @@ save_file_to_name(System_Functions *system, Models *models, Editing_File *file,
internal b32
save_file(System_Functions *system, Models *models, Editing_File *file){
b32 result = save_file_to_name(system, models, file, 0);
return(result);
return(save_file_to_name(system, models, file, 0));
}
////////////////////////////////
internal Partial_Cursor
file_compute_partial_cursor(Editing_File *file, Buffer_Seek seek){
Partial_Cursor result = {};
internal Buffer_Cursor
file_compute_cursor(Editing_File *file, Buffer_Seek seek){
Buffer_Cursor result = {};
switch (seek.type){
case buffer_seek_pos:
{
result = buffer_partial_from_pos(&file->state.buffer, (i32)seek.pos);
result = buffer_cursor_from_pos(&file->state.buffer, seek.pos);
}break;
case buffer_seek_line_char:
case buffer_seek_line_col:
{
result = buffer_partial_from_line_character(&file->state.buffer, (i32)seek.line, (i32)seek.character);
result = buffer_cursor_from_line_col(&file->state.buffer, seek.line, seek.col);
}break;
// TODO(allen): do(support buffer_seek_character_pos and character_pos coordiantes in partial cursor system)
}
return(result);
}
internal Full_Cursor
file_compute_cursor__inner(Models *models, Editing_File *file, Buffer_Seek seek, b32 return_hint){
////////////////////////////////
internal void
file_create_from_string(Models *models, Editing_File *file, String_Const_u8 val, File_Attributes attributes){
System_Functions *system = models->system;
Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id);
Assert(face != 0);
Full_Cursor result = {};
Buffer_Cursor_Seek_Params params;
params.buffer = &file->state.buffer;
params.seek = seek;
params.system = system;
params.face = face;
params.wrap_line_index = file->state.wrap_line_index;
params.character_starts = file->state.character_starts;
params.virtual_white = file->settings.virtual_white;
params.return_hint = return_hint;
params.cursor_out = &result;
Buffer_Cursor_Seek_State state = {};
Buffer_Layout_Stop stop = {};
i32 size = buffer_size(params.buffer);
f32 line_shift = 0.f;
b32 do_wrap = false;
i32 wrap_unit_end = 0;
b32 first_wrap_determination = true;
i32 wrap_array_index = 0;
do{
stop = buffer_cursor_seek(&state, params, line_shift, do_wrap, wrap_unit_end);
switch (stop.status){
case BLStatus_NeedWrapDetermination:
{
if (stop.pos >= size){
do_wrap = false;
wrap_unit_end = max_i32;
}
else{
if (first_wrap_determination){
wrap_array_index = binary_search(file->state.wrap_positions, stop.pos, 0, file->state.wrap_position_count);
++wrap_array_index;
if (file->state.wrap_positions[wrap_array_index] == stop.pos){
do_wrap = true;
wrap_unit_end = file->state.wrap_positions[wrap_array_index];
}
else{
do_wrap = false;
wrap_unit_end = file->state.wrap_positions[wrap_array_index];
}
first_wrap_determination = false;
}
else{
Assert(stop.pos == wrap_unit_end);
do_wrap = true;
++wrap_array_index;
wrap_unit_end = file->state.wrap_positions[wrap_array_index];
}
}
}break;
case BLStatus_NeedWrapLineShift:
case BLStatus_NeedLineShift:
{
line_shift = file->state.line_indents[stop.wrap_line_index];
}break;
}
}while(stop.status != BLStatus_Finished);
return(result);
}
internal Full_Cursor
file_compute_cursor(Models *models, Editing_File *file, Buffer_Seek seek){
return(file_compute_cursor__inner(models, file, seek, false));
}
internal Full_Cursor
file_compute_cursor_hint(Models *models, Editing_File *file, Buffer_Seek seek){
return(file_compute_cursor__inner(models, file, seek, true));
}
////////////////////////////////
internal i32
file_grow_starts_as_needed(Heap *heap, Gap_Buffer *buffer, i32 additional_lines){
b32 result = GROW_NOT_NEEDED;
i32 max = buffer->line_max;
i32 count = buffer->line_count;
i32 target_lines = count + additional_lines;
if (target_lines > max || max == 0){
max = round_up_i32(target_lines + max, KB(1));
i32 *new_lines = heap_array(heap, i32, max);
if (new_lines != 0){
result = GROW_SUCCESS;
memcpy(new_lines, buffer->line_starts, sizeof(*new_lines)*count);
heap_free(heap, buffer->line_starts);
buffer->line_starts = new_lines;
buffer->line_max = max;
}
else{
result = GROW_FAILED;
}
}
return(result);
}
internal void
file_measure_starts(Heap *heap, Gap_Buffer *buffer){
if (buffer->line_starts == 0){
i32 max = buffer->line_max = KB(1);
buffer->line_starts = heap_array(heap, i32, max);
Assert(buffer->line_starts != 0);
}
Buffer_Measure_Starts state = {};
for (;buffer_measure_starts(&state, buffer);){
i32 count = state.count;
i32 max = ((buffer->line_max + 1) << 1);
i32 *new_lines = heap_array(heap, i32, max);
Assert(new_lines != 0);
memcpy(new_lines, buffer->line_starts, sizeof(*new_lines)*count);
heap_free(heap, buffer->line_starts);
buffer->line_starts = new_lines;
buffer->line_max = max;
}
}
internal void
file_allocate_metadata_as_needed(Heap *heap, Gap_Buffer *buffer, void **mem, i32 *mem_max_count, i32 count, i32 item_size){
if (*mem == 0){
i32 max = round_up_i32(((count + 1)*2), KB(1));
*mem = heap_allocate(heap, max*item_size);
*mem_max_count = max;
Assert(*mem != 0);
}
else if (*mem_max_count < count){
i32 old_max = *mem_max_count;
i32 max = round_up_i32(((count + 1)*2), KB(1));
void *new_mem = heap_allocate(heap, item_size*max);
memcpy(new_mem, *mem, item_size*old_max);
heap_free(heap, *mem);
*mem = new_mem;
*mem_max_count = max;
Assert(*mem != 0);
}
}
internal void
file_allocate_character_starts_as_needed(Heap *heap, Editing_File *file){
file_allocate_metadata_as_needed(heap,
&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(Heap *heap, Editing_File *file, i32 min_last_index){
i32 min_amount = min_last_index + 1;
file_allocate_metadata_as_needed(heap,
&file->state.buffer, (void**)&file->state.line_indents,
&file->state.line_indent_max, min_amount, sizeof(f32));
}
internal void
file_allocate_wraps_as_needed(Heap *heap, Editing_File *file){
file_allocate_metadata_as_needed(heap,
&file->state.buffer, (void**)&file->state.wrap_line_index,
&file->state.wrap_max, file->state.buffer.line_count + 1, sizeof(f32));
}
internal void
file_allocate_wrap_positions_as_needed(Heap *heap, Editing_File *file, i32 min_last_index){
i32 min_amount = min_last_index + 1;
file_allocate_metadata_as_needed(heap,
&file->state.buffer, (void**)&file->state.wrap_positions,
&file->state.wrap_position_max, min_amount, sizeof(f32));
}
////////////////////////////////
internal void
file_create_from_string(System_Functions *system, Models *models, Editing_File *file, String_Const_u8 val, File_Attributes attributes){
// TODO(allen): completely eliminate the heap, then clean up the implementation or remove it too!
Heap *heap = &models->mem.heap;
Arena *scratch = &models->mem.arena;
Application_Links *app_links = &models->app_links;
Base_Allocator *allocator = models->base_allocator;
block_zero_struct(&file->state);
Gap_Buffer_Init init = buffer_begin_init(&file->state.buffer, val.str, val.size);
for (;buffer_init_need_more(&init);){
i32 page_size = buffer_init_page_size(&init);
page_size = round_up_i32(page_size, KB(4));
if (page_size < KB(4)){
page_size = KB(4);
}
void *data = heap_allocate(heap, page_size);
buffer_init_provide_page(&init, data, page_size);
}
buffer_init(&file->state.buffer, val.str, val.size, allocator);
b32 init_success = buffer_end_init(&init);
Assert(init_success);
if (buffer_size(&file->state.buffer) < val.size){
if (buffer_size(&file->state.buffer) < (i64)val.size){
file->settings.dos_write_mode = true;
}
file_clear_dirty_flags(file);
@ -445,13 +228,7 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File *
Face *face = font_set_face_from_id(&models->font_set, font_id);
Assert(face != 0);
file_measure_starts(heap, &file->state.buffer);
file_allocate_character_starts_as_needed(heap, file);
buffer_measure_character_starts(system, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white);
file_measure_wraps(system, &models->mem, file, face);
//adjust_views_looking_at_files_to_new_cursor(system, models, file);
buffer_measure_starts(scratch, &file->state.buffer);
file->lifetime_object = lifetime_alloc_object(heap, &models->lifetime_allocator, DynamicWorkspace_Buffer, file);
history_init(&models->app_links, &file->state.history);
@ -475,6 +252,9 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File *
file_mark_edit_finished(&models->working_set, file);
}
file->state.cached_layouts_arena = make_arena(allocator);
file->state.line_layout_table = make_table_Data_u64(allocator, 500);
file->settings.is_initialized = true;
{
@ -498,16 +278,15 @@ file_free(System_Functions *system, Heap *heap, Lifetime_Allocator *lifetime_all
Gap_Buffer *buffer = &file->state.buffer;
if (buffer->data){
heap_free(heap, buffer->data);
heap_free(heap, buffer->line_starts);
base_free(buffer->allocator, buffer->data);
base_free(buffer->allocator, buffer->line_starts);
}
heap_free(heap, file->state.wrap_line_index);
heap_free(heap, file->state.character_starts);
heap_free(heap, file->state.line_indents);
history_free(heap, &file->state.history);
linalloc_clear(&file->state.cached_layouts_arena);
table_free(&file->state.line_layout_table);
file_unmark_edit_finished(working_set, file);
}
@ -533,5 +312,250 @@ file_get_managed_scope(Editing_File *file){
return(scope);
}
////////////////////////////////
internal Buffer_Layout_Item_List
file_get_line_layout(Models *models, Editing_File *file, f32 width, Face_ID face_id, i64 line_number){
Buffer_Layout_Item_List result = {};
i64 line_count = buffer_line_count(&file->state.buffer);
if (1 <= line_number && line_number <= line_count){
// TODO(allen): optimization: most places that CALL this do so in a LOOP, which could HOIST
// this font_set_face_from_id call OUTSIDE of the LOOP.
Face *face = font_set_face_from_id(&models->font_set, face_id);
if (face != 0){
Line_Layout_Key key = {};
key.face_id = face_id;
key.face_version_number = face->version_number;
key.width = width;
key.line_number = line_number;
Data key_data = make_data_struct(&key);
Buffer_Layout_Item_List *list = 0;
Table_Lookup lookup = table_lookup(&file->state.line_layout_table, key_data);
if (lookup.found_match){
u64 val = 0;
table_read(&file->state.line_layout_table, lookup, &val);
list = (Buffer_Layout_Item_List*)IntAsPtr(val);
}
else{
list = push_array(&file->state.cached_layouts_arena, Buffer_Layout_Item_List, 1);
Interval_i64 line_range = buffer_get_pos_range_from_line_number(&file->state.buffer, line_number);
*list = buffer_layout(&models->mem.arena, &file->state.cached_layouts_arena,
&file->state.buffer, line_range, face, width);
key_data = push_data_copy(&file->state.cached_layouts_arena, key_data);
table_insert(&file->state.line_layout_table, key_data, (u64)PtrAsInt(list));
}
block_copy_struct(&result, list);
}
}
return(result);
}
internal void
file_clear_layout_cache(Editing_File *file){
linalloc_clear(&file->state.cached_layouts_arena);
table_clear(&file->state.line_layout_table);
}
internal Line_Shift_Vertical
file_line_shift_y(Models *models, Editing_File *file, f32 width, Face_ID face_id, i64 line_number, f32 y_delta){
Line_Shift_Vertical result = {};
f32 line_y = 0.f;
if (y_delta < 0.f){
// NOTE(allen): Iterating upward
b32 has_result = false;
for (;;){
if (line_y <= y_delta){
has_result = true;
result.line = line_number;
result.y_delta = line_y;
break;
}
line_number -= 1;
if (line_number <= 0){
line_number = 1;
break;
}
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face_id, line_number);
line_y -= line.height;
}
if (!has_result){
result.line = line_number;
result.y_delta = line_y;
}
}
else{
// NOTE(allen): Iterating downward
b32 has_result = false;
i64 line_count = buffer_line_count(&file->state.buffer);
for (;;line_number += 1){
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face_id, line_number);
f32 next_y = line_y + line.height;
if (y_delta < next_y){
has_result = true;
result.line = line_number;
result.y_delta = line_y;
break;
}
if (line_number >= line_count){
break;
}
line_y = next_y;
}
if (!has_result){
result.line = line_number;
result.y_delta = line_y;
}
}
return(result);
}
internal f32
file_line_y_difference(Models *models, Editing_File *file, f32 width, Face_ID face_id, i64 line_a, i64 line_b){
f32 result = 0.f;
if (line_a != line_b){
Interval_i64 line_range = Ii64(line_a, line_b);
for (i64 i = line_range.min; i < line_range.max; i += 1){
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face_id, i);
result += line.height;
}
if (line_a < line_b){
result *= -1.f;
}
}
return(result);
}
internal i64
file_pos_at_relative_xy(Models *models, Editing_File *file, f32 width, Face_ID face_id, i64 base_line, Vec2_f32 relative_xy){
Line_Shift_Vertical shift = file_line_shift_y(models, file, width, face_id, base_line, relative_xy.y);
relative_xy.y -= shift.y_delta;
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face_id, shift.line);
return(buffer_layout_nearest_pos_to_xy(line, relative_xy));
}
internal Vec2_f32
file_relative_xy_of_pos(Models *models, Editing_File *file, f32 width, Face_ID face_id, i64 base_line, i64 pos){
i64 line_number = buffer_get_line_index(&file->state.buffer, pos) + 1;
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face_id, line_number);
Vec2_f32 result = buffer_layout_xy_center_of_pos(line, pos);
result.y += file_line_y_difference(models, file, width, face_id, line_number, base_line);
return(result);
}
internal Buffer_Point
file_normalize_buffer_point(Models *models, Editing_File *file, f32 width, Face_ID face_id, Buffer_Point point){
Line_Shift_Vertical shift = file_line_shift_y(models, file, width, face_id, point.line_number, point.pixel_shift.y);
point.line_number = shift.line;
point.pixel_shift.y -= shift.y_delta;
point.pixel_shift.x = clamp_bot(0.f, point.pixel_shift.x);
point.pixel_shift.y = clamp_bot(0.f, point.pixel_shift.y);
return(point);
}
internal Vec2_f32
file_buffer_point_difference(Models *models, Editing_File *file, f32 width, Face_ID face_id, Buffer_Point a, Buffer_Point b){
f32 y_difference = file_line_y_difference(models, file, width, face_id, a.line_number, b.line_number);
Vec2_f32 result = a.pixel_shift - b.pixel_shift;
result.y += y_difference;
return(result);
}
internal Line_Shift_Character
file_line_shift_characters(Models *models, Editing_File *file, f32 width, Face_ID face_id, i64 line_number, i64 character_delta){
Line_Shift_Character result = {};
i64 line_character = 0;
if (character_delta < 0){
// NOTE(allen): Iterating upward
b32 has_result = false;
for (;;){
if (line_character <= character_delta){
has_result = true;
result.line = line_number;
result.character_delta = line_character;
break;
}
line_number -= 1;
if (line_number <= 0){
line_number = 1;
break;
}
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face_id, line_number);
line_character -= line.character_count;
}
if (!has_result){
result.line = line_number;
result.character_delta = line_character;
}
}
else{
// NOTE(allen): Iterating downward
b32 has_result = false;
i64 line_count = buffer_line_count(&file->state.buffer);
for (;;line_number += 1){
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face_id, line_number);
i64 next_character = line_character + line.character_count;
if (character_delta < next_character){
has_result = true;
result.line = line_number;
result.character_delta = line_character;
break;
}
if (line_number >= line_count){
break;
}
line_character = next_character;
}
if (!has_result){
result.line = line_number;
result.character_delta = line_character;
}
}
return(result);
}
internal i64
file_line_character_difference(Models *models, Editing_File *file, f32 width, Face_ID face_id, i64 line_a, i64 line_b){
i64 result = 0;
if (line_a != line_b){
Interval_i64 line_range = Ii64(line_a, line_b);
for (i64 i = line_range.min; i < line_range.max; i += 1){
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face_id, i);
result += line.character_count;
}
if (line_a < line_b){
result *= -1;
}
}
return(result);
}
internal i64
file_pos_from_relative_character(Models *models, Editing_File *file, f32 width, Face_ID face_id, i64 base_line, i64 relative_character){
Line_Shift_Character shift = file_line_shift_characters(models, file, width, face_id, base_line, relative_character);
relative_character -= shift.character_delta;
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face_id, shift.line);
return(buffer_layout_get_pos_at_character(line, relative_character));
}
internal i64
file_relative_character_from_pos(Models *models, Editing_File *file, f32 width, Face_ID face_id, i64 base_line, i64 pos){
i64 line_number = buffer_get_line_index(&file->state.buffer, pos) + 1;
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face_id, line_number);
i64 result = buffer_layout_character_from_pos(line, pos);
result += file_line_character_difference(models, file, width, face_id, line_number, base_line);
return(result);
}
// BOTTOM

View File

@ -20,14 +20,14 @@ enum{
};
struct File_Edit_Positions{
Edit_Pos_Set_Type last_set_type;
GUI_Scroll_Vars scroll;
Buffer_Scroll scroll;
i64 cursor_pos;
};
// TODO(allen): do(replace Text_Effect with markers over time)
struct Text_Effect{
i32 start;
i32 end;
i64 start;
i64 end;
u32 color;
f32 seconds_down;
f32 seconds_max;
@ -35,43 +35,31 @@ struct Text_Effect{
struct Editing_File_Settings{
i32 base_map_id;
i32 display_width;
i32 minimum_base_display_width;
i32 wrap_indicator;
Parse_Context_ID parse_context_id;
b32 dos_write_mode;
Face_ID font_id;
b8 unwrapped_lines;
b8 tokens_exist;
b8 tokens_without_strings;
b8 is_initialized;
b8 unimportant;
b8 read_only;
b8 never_kill;
b8 virtual_white;
};
struct Line_Layout_Key{
Face_ID face_id;
i32 face_version_number;
f32 width;
i64 line_number;
};
struct Editing_File_State{
Gap_Buffer buffer;
i32 *wrap_line_index;
i32 wrap_max;
i32 *character_starts;
i32 character_start_max;
f32 *line_indents;
i32 line_indent_max;
i32 wrap_line_count;
i32 *wrap_positions;
i32 wrap_position_count;
i32 wrap_position_max;
History history;
i32 current_record_index;
// TODO(allen): eliminate this too
Cpp_Token_Array token_array;
b32 in_edit_handler;
@ -85,6 +73,9 @@ struct Editing_File_State{
i32 edit_pos_stack_top;
Child_Process_ID attached_child_process;
Arena cached_layouts_arena;
Table_Data_u64 line_layout_table;
};
struct Editing_File_Name{
@ -112,6 +103,11 @@ struct Editing_File{
Editing_File_Name canon;
};
struct Buffer_Point_Delta{
Buffer_Point new_point;
f32 y_shift;
};
#endif
// BOTTOM

View File

@ -34,7 +34,7 @@ file_first_lex_serial(System_Functions *system, Models *models, Editing_File *fi
Assert(parse_context.valid);
Gap_Buffer *buffer = &file->state.buffer;
i32 text_size = buffer_size(buffer);
i64 text_size = buffer_size(buffer);
// TODO(allen): REWRITE REWRITE REWRITE
Cpp_Token_Array new_tokens = {};
@ -46,25 +46,23 @@ file_first_lex_serial(System_Functions *system, Models *models, Editing_File *fi
Cpp_Lex_Data lex = cpp_lex_data_init(file->settings.tokens_without_strings, parse_context.kw_table, parse_context.pp_table);
String_Const_u8_Array chunk_space[3];
Cursor chunk_cursor = make_cursor(chunk_space, sizeof(chunk_space));
String_Const_u8_Array chunks = buffer_get_chunks(&chunk_cursor, buffer, BufferGetChunk_ZeroTerminated);
i32 chunk_index = 0;
List_String_Const_u8 chunks = buffer_get_chunks(scratch, buffer);
u8 null_terminator = 0;
string_list_push(scratch, &chunks, SCu8(&null_terminator, 1));
Cpp_Token_Array new_array = {};
do{
u8 *chunk = chunks.vals[chunk_index].str;
umem chunk_size = chunks.vals[chunk_index].size;
for (Node_String_Const_u8 *node = chunks.first;
node != 0;){
u8 *chunk = node->string.str;
umem chunk_size = node->string.size;
i32 result = cpp_lex_step(&lex, (char*)chunk, (i32)chunk_size, text_size, &new_tokens, NO_OUT_LIMIT);
i32 result = cpp_lex_step(&lex, (char*)chunk, (i32)chunk_size, (i32)text_size, &new_tokens, NO_OUT_LIMIT);
switch (result){
case LexResult_NeedChunk:
{
++chunk_index;
Assert(chunk_index < chunks.count);
node = node->next;
}break;
case LexResult_Finished:
@ -95,7 +93,11 @@ file_first_lex_serial(System_Functions *system, Models *models, Editing_File *fi
case LexResult_HitTokenLimit: InvalidPath;
}
} while (still_lexing);
if (!still_lexing){
break;
}
}
Cpp_Token_Array *token_array = &file->state.token_array;
token_array->count = new_array.count;
@ -116,7 +118,7 @@ file_first_lex_serial(System_Functions *system, Models *models, Editing_File *fi
}
internal b32
file_relex_serial(System_Functions *system, Models *models, Editing_File *file, i32 start_i, i32 end_i, i32 shift_amount){
file_relex_serial(System_Functions *system, Models *models, Editing_File *file, i64 start_i, i64 end_i, i64 shift_amount){
Mem_Options *mem = &models->mem;
Arena *scratch = &mem->arena;
Heap *heap = &mem->heap;
@ -137,35 +139,38 @@ file_relex_serial(System_Functions *system, Models *models, Editing_File *file,
relex_array.max_count = Million(1);
relex_array.tokens = push_array(scratch, Cpp_Token, relex_array.max_count);
i32 size = buffer_size(buffer);
i64 size = buffer_size(buffer);
Cpp_Relex_Data state = cpp_relex_init(array, start_i, end_i, shift_amount, file->settings.tokens_without_strings, parse_context.kw_table, parse_context.pp_table);
Cpp_Relex_Data state = cpp_relex_init(array, (i32)start_i, (i32)end_i, (i32)shift_amount, file->settings.tokens_without_strings, parse_context.kw_table, parse_context.pp_table);
String_Const_u8_Array chunk_space[3];
Cursor chunk_cursor = make_cursor(chunk_space, sizeof(chunk_space));
String_Const_u8_Array chunks = buffer_get_chunks(&chunk_cursor, buffer, BufferGetChunk_ZeroTerminated);
List_String_Const_u8 chunks = buffer_get_chunks(scratch, buffer);
u8 null_terminator = 0;
string_list_push(scratch, &chunks, SCu8(&null_terminator, 1));
Node_String_Const_u8 *node = chunks.first;
i32 chunk_index = 0;
u8 *chunk = chunks.vals[chunk_index].str;
umem chunk_size = chunks.vals[chunk_index].size;
for (;!cpp_relex_is_start_chunk(&state, (char*)chunk, (i32)chunk_size);){
++chunk_index;
Assert(chunk_index < chunks.count);
chunk = chunks.vals[chunk_index].str;
chunk_size = chunks.vals[chunk_index].size;
u8 *chunk = 0;
umem chunk_size = 0;
if (node != 0){
chunk = node->string.str;
chunk_size = node->string.size;
}
for (;!cpp_relex_is_start_chunk(&state, (char*)chunk, (i32)chunk_size);){
node = node->next;
Assert(node != 0);
chunk = node->string.str;
chunk_size = node->string.size;
}
for(;;){
Cpp_Lex_Result lex_result = cpp_relex_step(&state, (char*)chunk, (i32)chunk_size, size, array, &relex_array);
Cpp_Lex_Result lex_result = cpp_relex_step(&state, (char*)chunk, (i32)chunk_size, (i32)size, array, &relex_array);
switch (lex_result){
case LexResult_NeedChunk:
{
++chunk_index;
Assert(chunk_index < chunks.count);
chunk = chunks.vals[chunk_index].str;
chunk_size = chunks.vals[chunk_index].size;
node = node->next;
Assert(node != 0);
chunk = node->string.str;
chunk_size = node->string.size;
}break;
case LexResult_NeedTokenMemory: InvalidPath;
@ -199,7 +204,7 @@ file_first_lex(System_Functions *system, Models *models, Editing_File *file){
}
internal void
file_relex(System_Functions *system, Models *models, Editing_File *file, i32 start, i32 end, i32 shift_amount){
file_relex(System_Functions *system, Models *models, Editing_File *file, i64 start, i64 end, i64 shift_amount){
file_relex_serial(system, models, file, start, end, shift_amount);
}

View File

@ -40,6 +40,7 @@ struct Codepoint_Index_Map{
struct Face{
Face_Description description;
Face_ID id;
i32 version_number;
// NOTE(allen): Metrics
f32 height;

View File

@ -149,12 +149,14 @@ font_set_modify_face(Font_Set *set, Face_ID id, Face_Description *description){
b32 result = false;
Font_Face_Slot *slot = font_set__get_face_slot(set, id);
if (slot != 0){
i32 version_number = slot->face->version_number;
Arena arena = make_arena_system(set->system);
Face *face = set->system->font_make_face(&arena, description);
if (face != 0){
linalloc_clear(&slot->arena);
slot->arena = arena;
slot->face = face;
face->version_number = version_number + 1;
face->id = id;
result = true;
}

View File

@ -250,18 +250,10 @@ history_record_edit(Heap *heap, Global_History *global_history, History *history
new_record->kind = RecordKind_Single;
i32 length_forward = edit.length;
i32 length_backward = edit.range.one_past_last - edit.range.first;
new_record->single.str_forward = push_array(&history->arena, char, length_forward);
new_record->single.str_backward = push_array(&history->arena, char, length_backward);
new_record->single.length_forward = length_forward;
new_record->single.length_backward = length_backward;
new_record->single.forward_text = push_string_copy(&history->arena, edit.text);
new_record->single.backward_text = buffer_stringify(&history->arena, buffer, edit.range);
new_record->single.first = edit.range.first;
block_copy(new_record->single.str_forward, edit.str, length_forward);
buffer_stringify_range(buffer, edit.range, new_record->single.str_backward);
Assert(history->record_lookup.count == history->record_count);
}
}
@ -313,29 +305,29 @@ history__optimize_group(Arena *scratch, History *history, Record *record){
b32 do_merge = false;
Temp_Memory temp = begin_temp(scratch);
i32 new_length_forward = left->single.length_forward + right->single.length_forward ;
i32 new_length_backward = left->single.length_backward + right->single.length_backward;
i64 new_length_forward = left->single.forward_text.size + right->single.forward_text.size ;
i64 new_length_backward = left->single.backward_text.size + right->single.backward_text.size;
char *temp_str_forward = 0;
char *temp_str_backward = 0;
String_Const_u8 merged_forward = {};
String_Const_u8 merged_backward = {};
if (left->single.first + left->single.length_forward == right->single.first){
if (left->single.first + (i64)left->single.forward_text.size == right->single.first){
do_merge = true;
temp_str_forward = push_array(scratch, char, new_length_forward );
temp_str_backward = push_array(scratch, char, new_length_backward);
block_copy(temp_str_forward , left->single.str_forward , left->single.length_forward );
block_copy(temp_str_forward + left->single.length_forward, right->single.str_forward, right->single.length_forward);
block_copy(temp_str_backward , left->single.str_backward , left->single.length_backward );
block_copy(temp_str_backward + left->single.length_backward, right->single.str_backward, right->single.length_backward);
merged_forward = push_u8_stringf(scratch, "%.*s%.*s",
string_expand(left->single.forward_text),
string_expand(right->single.forward_text));
merged_backward = push_u8_stringf(scratch, "%.*s%.*s",
string_expand(left->single.backward_text),
string_expand(right->single.backward_text));
}
else if (right->single.first + right->single.length_backward == left->single.first){
else if (right->single.first + (i64)right->single.backward_text.size == left->single.first){
do_merge = true;
temp_str_forward = push_array(scratch, char, new_length_forward );
temp_str_backward = push_array(scratch, char, new_length_backward);
block_copy(temp_str_forward , right->single.str_forward, right->single.length_forward);
block_copy(temp_str_forward + right->single.length_forward, left->single.str_forward , left->single.length_forward );
block_copy(temp_str_backward , right->single.str_backward, right->single.length_backward);
block_copy(temp_str_backward + right->single.length_backward, left->single.str_backward , left->single.length_backward );
merged_forward = push_u8_stringf(scratch, "%.*s%.*s",
string_expand(right->single.forward_text),
string_expand(left->single.forward_text));
merged_backward = push_u8_stringf(scratch, "%.*s%.*s",
string_expand(right->single.backward_text),
string_expand(left->single.backward_text));
}
else{
break;
@ -344,17 +336,9 @@ history__optimize_group(Arena *scratch, History *history, Record *record){
if (do_merge){
end_temp(left->restore_point);
char *new_str_forward = push_array(&history->arena, char, new_length_forward );
char *new_str_backward = push_array(&history->arena, char, new_length_backward);
block_copy(new_str_forward , temp_str_forward , new_length_forward );
block_copy(new_str_backward, temp_str_backward, new_length_backward);
left->edit_number = right->edit_number;
left->single.str_forward = new_str_forward ;
left->single.str_backward = new_str_backward;
left->single.length_forward = new_length_forward ;
left->single.length_backward = new_length_backward;
left->single.forward_text = push_string_copy(&history->arena, merged_forward);
left->single.backward_text = push_string_copy(&history->arena, merged_backward);
history__free_single_node(history, &right->node);
record->group.count -= 1;

View File

@ -13,8 +13,8 @@
#define FRED_HISTORY_H
struct Record_Batch_Slot{
i32 length_forward;
i32 length_backward;
i64 length_forward;
i64 length_backward;
i32 first;
};
@ -25,13 +25,10 @@ struct Record{
Record_Kind kind;
union{
struct{
char *str_forward;
char *str_backward;
i32 length_forward;
i32 length_backward;
i32 first;
String_Const_u8 forward_text;
String_Const_u8 backward_text;
i64 first;
} single;
struct{
Node children;
i32 count;

View File

@ -67,21 +67,20 @@ string_compute_needle_jump_table(Arena *arena, String_Const_u8 needle, Scan_Dire
internal String_Match_List
find_all_matches_forward(Arena *arena, i32 maximum_output_count,
String_Const_u8_Array chunks, String_Const_u8 needle,
List_String_Const_u8 chunks, String_Const_u8 needle,
u64_Array jump_table, Character_Predicate *predicate,
u64 base_index, Buffer_ID buffer, i32 string_id){
String_Match_List list = {};
if (chunks.count > 0){
if (chunks.node_count > 0){
u64 i = 0;
u64 j = 0;
b8 current_l = false;
i64 last_insensitive = -1;
i64 last_boundary = -1;
i32 chunk_index = 0;
Node_String_Const_u8 *node = chunks.first;
i64 chunk_pos = 0;
String_Const_u8 chunk = chunks.strings[chunk_index];
i32 jump_back_code = 0;
@ -89,13 +88,10 @@ find_all_matches_forward(Arena *arena, i32 maximum_output_count,
iterate_forward:
i += 1;
chunk_pos += 1;
if (chunk_pos >= (i64)chunk.size){
if (chunk_pos >= (i64)node->string.size){
last_boundary = i;
chunk_pos = 0;
chunk_index += 1;
if (chunk_index < chunks.count){
chunk = chunks.strings[chunk_index];
}
node = node->next;
}
switch (jump_back_code){
@ -110,8 +106,8 @@ find_all_matches_forward(Arena *arena, i32 maximum_output_count,
}
}
for (;chunk_index < chunks.count;){
u8 c = chunk.str[chunk_pos];
for (;node != 0;){
u8 c = node->string.str[chunk_pos];
u64 n = i - j;
u8 needle_c = needle.str[n];
if (character_to_upper(c) == character_to_upper(needle_c)){
@ -135,8 +131,8 @@ find_all_matches_forward(Arena *arena, i32 maximum_output_count,
(u64)last_boundary < j + needle.size)){
AddFlag(flags, StringMatch_Straddled);
}
if (chunk_index < chunks.count){
u8 next_c = chunk.str[chunk_pos];
if (node != 0){
u8 next_c = node->string.str[chunk_pos];
if (character_predicate_check_character(*predicate, next_c)){
AddFlag(flags, StringMatch_RightSideSloppy);
}
@ -180,16 +176,15 @@ find_all_matches_forward(Arena *arena, i32 maximum_output_count,
internal String_Match_List
find_all_matches_backward(Arena *arena, i32 maximum_output_count,
String_Const_u8_Array chunks, String_Const_u8 needle,
List_String_Const_u8 chunks, String_Const_u8 needle,
u64_Array jump_table, Character_Predicate *predicate,
u64 base_index, Buffer_ID buffer, i32 string_id){
String_Match_List list = {};
if (chunks.count > 0){
i64 size = 0;
for (i32 i = 0; i < chunks.count; i += 1){
size += chunks.strings[i].size;
}
string_list_reverse(&chunks);
if (chunks.node_count > 0){
i64 size = (i64)chunks.total_size;
i64 i = size - 1;
i64 j = size - 1;
@ -197,9 +192,8 @@ find_all_matches_backward(Arena *arena, i32 maximum_output_count,
i64 last_insensitive = size;
i64 last_boundary = size;
i32 chunk_index = chunks.count - 1;
String_Const_u8 chunk = chunks.strings[chunk_index];
i64 chunk_pos = chunk.size - 1;
Node_String_Const_u8 *node = chunks.first;
i64 chunk_pos = node->string.size - 1;
i32 jump_back_code = 0;
@ -209,11 +203,7 @@ find_all_matches_backward(Arena *arena, i32 maximum_output_count,
chunk_pos -= 1;
if (chunk_pos < 0){
last_boundary = i;
chunk_index -= 1;
if (chunk_index >= 0){
chunk = chunks.strings[chunk_index];
chunk_pos = chunk.size - 1;
}
node = node->next;
}
switch (jump_back_code){
@ -228,8 +218,8 @@ find_all_matches_backward(Arena *arena, i32 maximum_output_count,
}
}
for (;chunk_index >= 0;){
u8 c = chunk.str[chunk_pos];
for (;node != 0;){
u8 c = node->string.str[chunk_pos];
u64 n = j - i;
u8 needle_c = needle.str[needle.size - 1 - n];
if (character_to_upper(c) == character_to_upper(needle_c)){
@ -253,8 +243,8 @@ find_all_matches_backward(Arena *arena, i32 maximum_output_count,
last_boundary > j - (i64)needle.size)){
AddFlag(flags, StringMatch_Straddled);
}
if (chunk_index >= 0){
u8 next_c = chunk.str[chunk_pos];
if (node != 0){
u8 next_c = node->string.str[chunk_pos];
if (character_predicate_check_character(*predicate, next_c)){
AddFlag(flags, StringMatch_LeftSideSloppy);
}
@ -296,12 +286,14 @@ find_all_matches_backward(Arena *arena, i32 maximum_output_count,
}
}
string_list_reverse(&chunks);
return(list);
}
internal String_Match_List
find_all_matches(Arena *arena, i32 maximum_output_count,
String_Const_u8_Array chunks, String_Const_u8 needle,
List_String_Const_u8 chunks, String_Const_u8 needle,
u64_Array jump_table, Character_Predicate *predicate,
Scan_Direction direction,
u64 base_index, Buffer_ID buffer, i32 string_id){

View File

@ -42,7 +42,7 @@ typedef Sys_Load_File_Sig(System_Load_File);
#define Sys_Load_Close_Sig(name) b32 name(Plat_Handle handle)
typedef Sys_Load_Close_Sig(System_Load_Close);
#define Sys_Save_File_Sig(name) File_Attributes name(Arena *scratch, char *filename, char *buffer, u32 size)
#define Sys_Save_File_Sig(name) File_Attributes name(Arena *scratch, char *filename, String_Const_u8 data)
typedef Sys_Save_File_Sig(System_Save_File);
// time

View File

@ -9,46 +9,57 @@
// TOP
// TODO(allen): REWRITE REWRITE REWRITE!!!
internal void
text_layout_init(Application_Links *app, Text_Layout_Container *container){
text_layout_init(Models *models, Text_Layout_Container *container){
block_zero_struct(container);
container->node_arena = make_arena_app_links(app);
container->node_arena = make_arena_models(models);
container->table = make_table_u64_u64(models->base_allocator, 20);
}
internal Text_Layout*
text_layout_new__alloc_layout(Text_Layout_Container *container){
Text_Layout_Node *node = container->free_nodes;
Text_Layout *node = container->free_nodes;
if (node == 0){
node = push_array(&container->node_arena, Text_Layout_Node, 1);
node = push_array(&container->node_arena, Text_Layout, 1);
}
else{
container->free_nodes = node->next;
sll_stack_pop(container->free_nodes);
}
return(&node->layout);
return(node);
}
internal void
text_layout_release(Text_Layout_Container *container, Text_Layout *layout){
linalloc_clear(&layout->arena);
sll_stack_push(container->free_nodes, layout);
}
internal Text_Layout_ID
text_layout_new(Heap *heap, Text_Layout_Container *container, Buffer_ID buffer_id, Buffer_Point point, Range on_screen_range, f32 height, Text_Layout_Coordinates coordinates, int_color *item_colors){
text_layout_new(Text_Layout_Container *container, Arena arena,
Buffer_ID buffer_id, Buffer_Point point,
Interval_i64 visible_range, Interval_i64 visible_line_number_range,
Rect_f32 rect, int_color *item_colors){
Text_Layout *new_layout_data = text_layout_new__alloc_layout(container);
new_layout_data->arena = arena;
new_layout_data->buffer_id = buffer_id;
new_layout_data->point = point;
new_layout_data->on_screen_range = on_screen_range;
new_layout_data->height = height;
new_layout_data->coordinates = coordinates;
new_layout_data->visible_range = visible_range;
new_layout_data->visible_line_number_range = visible_line_number_range;
new_layout_data->rect = rect;
new_layout_data->item_colors = item_colors;
Text_Layout_ID new_id = ++container->id_counter;
insert_u32_Ptr_table(heap, &container->table, new_id, new_layout_data);
table_insert(&container->table, new_id, (u64)PtrAsInt(new_layout_data));
return(new_id);
}
internal b32
text_layout_get(Text_Layout_Container *container, Text_Layout_ID id, Text_Layout *out){
b32 result = false;
void *ptr = 0;
if (lookup_u32_Ptr_table(&container->table, id, &ptr)){
block_copy(out, ptr, sizeof(*out));
result = true;
internal Text_Layout*
text_layout_get(Text_Layout_Container *container, Text_Layout_ID id){
Text_Layout *result = 0;
Table_Lookup lookup = table_lookup(&container->table, id);
if (lookup.found_match){
u64 ptr_val = 0;
table_read(&container->table, lookup, &ptr_val);
result = (Text_Layout*)IntAsPtr(ptr_val);
}
return(result);
}
@ -56,15 +67,73 @@ text_layout_get(Text_Layout_Container *container, Text_Layout_ID id, Text_Layout
internal b32
text_layout_erase(Text_Layout_Container *container, Text_Layout_ID id){
b32 result = false;
void *ptr = 0;
if (lookup_u32_Ptr_table(&container->table, id, &ptr)){
erase_u32_Ptr_table(&container->table, id);
Text_Layout_Node *node = CastFromMember(Text_Layout_Node, layout, ptr);
node->next = container->free_nodes;
container->free_nodes = node;
Table_Lookup lookup = table_lookup(&container->table, id);
if (lookup.found_match){
u64 ptr_val = 0;
table_read(&container->table, lookup, &ptr_val);
Text_Layout *ptr = (Text_Layout*)IntAsPtr(ptr_val);
text_layout_release(container, ptr);
table_erase(&container->table, lookup);
result = true;
}
return(result);
}
////////////////////////////////
internal void
text_layout_render(Models *models, Text_Layout *layout){
Editing_File *file = imp_get_file(models, layout->buffer_id);
if (file != 0){
Arena *scratch = &models->mem.arena;
Render_Target *target = models->target;
Color_Table color_table = models->color_table;
Font_Set *font_set = &models->font_set;
Face_ID font_id = file->settings.font_id;
f32 width = rect_width(layout->rect);
u32 special_color = color_table.vals[Stag_Special_Character];
u32 ghost_color = color_table.vals[Stag_Ghost_Character];
Vec2_f32 shift_p = layout->rect.p0 - layout->point.pixel_shift;
i64 first_index = layout->visible_range.first;
i64 line_number = layout->visible_line_number_range.min;
i64 line_number_last = layout->visible_line_number_range.max;
for (;line_number <= line_number_last; line_number += 1){
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, font_id, line_number);
for (Buffer_Layout_Item_Block *block = line.first;
block != 0;
block = block->next){
Buffer_Layout_Item *item = block->items;
i64 count = block->count;
int_color *item_colors = layout->item_colors;
for (i32 i = 0; i < count; i += 1, item += 1){
if (item->codepoint != 0){
int_color symbol_color = item_colors[item->index - first_index];
u32 color = 0;
if (symbol_color == Stag_Default){
if (HasFlag(item->flags, BRFlag_Special_Character)){
color = special_color;
}
else if (HasFlag(item->flags, BRFlag_Ghost_Character)){
color = ghost_color;
}
else{
color = finalize_color(color_table, symbol_color);
}
}
else{
color = finalize_color(color_table, symbol_color);
}
Vec2_f32 p = item->rect.p0 + shift_p;
draw_font_glyph(target, font_set, font_id, item->codepoint, p.x, p.y, color, GlyphFlag_None);
}
}
}
shift_p.y += line.height;
}
}
}
// BOTTOM

View File

@ -12,33 +12,24 @@
#if !defined(FRED_TEXT_LAYOUT_H)
#define FRED_TEXT_LAYOUT_H
struct Text_Layout{
// NOTE(allen): This is not a _real_ text layout yet.
// The eventual destiny of this type is that it will store the fairly
// costly to generate results of the text layout engine.
// For now, since the engine cannot be easily consolidated,
// this just stores the parameters that should be handed to any
// system that attempts to query the layout for hit testing.
View_ID view_id;
union Text_Layout{
Text_Layout *next;
struct{
Arena arena;
Buffer_ID buffer_id;
Buffer_Point point;
Range on_screen_range;
f32 height;
Text_Layout_Coordinates coordinates;
Interval_i64 visible_range;
Interval_i64 visible_line_number_range;
Rect_f32 rect;
int_color *item_colors;
};
union Text_Layout_Node{
Text_Layout_Node *next;
Text_Layout layout;
};
};
struct Text_Layout_Container{
Arena node_arena;
Text_Layout_Node *free_nodes;
u32_Ptr_Table table;
u32 id_counter;
Text_Layout *free_nodes;
Table_u64_u64 table;
Text_Layout_ID id_counter;
};
#endif

View File

@ -9,6 +9,31 @@
// TOP
// TODO(allen): I don't like this code _AT ALL_
// unravel the mess!
//
//
// So what happened here was I thought, "Hey I have text in non-contiguous chunks and now I
// need to translates it into unicode codepoints (interpreting it as utf8), so I should make
// a system that translates utf-8 by taking in one byte at a time then emitting one or more
// codepoints whenever there is enough information, all the while ensuring there is no backtracking"
//
// Even though this may make the iteration sound nice, it's a HUGE FREAKING PAIN IN THE ASS.
// You can't optimize it very well, the code is inscrutible both on the implementation side
// and the calling side. Besides the fact that I "got it working" there isn't one good thing
// about this code.
//
// My next idea would be to try to make translation systems that take in the chunks themselves as
// a linked list, and then just does the WHOLE translation, MAYBE with optional "stop conditions".
// This way someone can actually optimize the translation loop by hand in _ONE SPOT_. The downside
// is that the caller will have to put up with maybe more translation work than they needed, but that
// translation work will be so much cheaper, and easier to maintain, that the caller will be happier
// overall.
//
//
// If this comment is still here, then I haven't fixed any of this garbage yet, but it should really
// be fixed!
#define ERROR_BYTE (max_u8-1)
#define CONTINUATION_BYTE max_u8

View File

@ -18,7 +18,6 @@ struct Translation_State{
u8 fill_i;
u8 fill_expected;
};
global_const Translation_State null_buffer_translating_state = {};
enum{
TranLBH_None,

View File

@ -34,9 +34,9 @@ view_get_index(Live_Views *live_set, View *view){
return((i32)(view - live_set->views));
}
internal i32
internal View_ID
view_get_id(Live_Views *live_set, View *view){
return((i32)(view - live_set->views) + 1);
return((View_ID)(view - live_set->views) + 1);
}
internal View*
@ -80,6 +80,8 @@ view_get_edit_pos(View *view){
internal void
view_set_edit_pos(View *view, File_Edit_Positions edit_pos){
edit_pos.scroll.position.line_number = clamp_bot(1, edit_pos.scroll.position.line_number);
edit_pos.scroll.target.line_number = clamp_bot(1, edit_pos.scroll.target.line_number);
view->edit_pos_ = edit_pos;
view->file->state.edit_pos_most_recent = edit_pos;
}
@ -116,179 +118,225 @@ view_height(Models *models, View *view){
return(rect_height(view_get_buffer_rect(models, view)));
}
internal Vec2_i32
view_get_cursor_xy(Models *models, View *view){
File_Edit_Positions edit_pos = view_get_edit_pos(view);
Full_Cursor cursor = file_compute_cursor(models, view->file, seek_pos(edit_pos.cursor_pos));
Vec2_i32 result = {};
if (view->file->settings.unwrapped_lines){
result = V2i32((i32)cursor.unwrapped_x, (i32)cursor.unwrapped_y);
}
else{
result = V2i32((i32)cursor.wrapped_x, (i32)cursor.wrapped_y);
}
return(result);
}
////////////////////////////////
internal Cursor_Limits
view_cursor_limits(Models *models, View *view){
internal Buffer_Layout_Item_List
view_get_line_layout(Models *models, View *view, i64 line_number){
Editing_File *file = view->file;
Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id);
i32 line_height = (i32)face->height;
i32 visible_height = (i32)view_height(models, view);
Cursor_Limits limits = {};
limits.min = line_height*2;
limits.max = visible_height - line_height*3;
if (limits.max - limits.min <= line_height){
if (visible_height >= line_height){
limits.max = visible_height - line_height;
}
else{
limits.max = visible_height;
}
limits.min = 0;
}
limits.min = clamp(0, limits.min, limits.max);
limits.max = clamp_bot(0, limits.max);
limits.delta = clamp_top(line_height*5, (limits.max - limits.min + 1)/2);
return(limits);
Face_ID face = file->settings.font_id;
f32 width = view_width(models, view);
return(file_get_line_layout(models, file, width, face, line_number));
}
internal i32
view_compute_max_target_y_from_bottom_y(Models *models, View *view, f32 max_item_y, f32 line_height){
f32 height = clamp_bot(line_height, view_height(models, view));
f32 max_target_y = clamp_bot(0.f, max_item_y - height*0.5f);
return(ceil32(max_target_y));
}
internal i32
view_compute_max_target_y(Models *models, View *view){
internal Line_Shift_Vertical
view_line_shift_y(Models *models, View *view, i64 line_number, f32 y_delta){
Editing_File *file = view->file;
Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id);
f32 line_height = face->height;
Gap_Buffer *buffer = &file->state.buffer;
i32 lowest_line = buffer->line_count;
if (!file->settings.unwrapped_lines){
lowest_line = file->state.wrap_line_index[buffer->line_count];
}
return(view_compute_max_target_y_from_bottom_y(models, view, (lowest_line + 0.5f)*line_height, line_height));
Face_ID face = file->settings.font_id;
f32 width = view_width(models, view);
return(file_line_shift_y(models, file, width, face, line_number, y_delta));
}
internal f32
view_line_y_difference(Models *models, View *view, i64 line_a, i64 line_b){
Editing_File *file = view->file;
Face_ID face = file->settings.font_id;
f32 width = view_width(models, view);
return(file_line_y_difference(models, file, width, face, line_a, line_b));
}
internal i64
view_pos_at_relative_xy(Models *models, View *view, i64 base_line, Vec2_f32 relative_xy){
Editing_File *file = view->file;
Face_ID face = file->settings.font_id;
f32 width = view_width(models, view);
return(file_pos_at_relative_xy(models, file, width, face, base_line, relative_xy));
}
internal Vec2_f32
view_relative_xy_of_pos(Models *models, View *view, i64 base_line, i64 pos){
Editing_File *file = view->file;
Face_ID face = file->settings.font_id;
f32 width = view_width(models, view);
return(file_relative_xy_of_pos(models, file, width, face, base_line, pos));
}
internal Buffer_Point
view_normalize_buffer_point(Models *models, View *view, Buffer_Point point){
Editing_File *file = view->file;
Face_ID face = file->settings.font_id;
f32 width = view_width(models, view);
return(file_normalize_buffer_point(models, file, width, face, point));
}
internal Vec2_f32
view_buffer_point_difference(Models *models, View *view, Buffer_Point a, Buffer_Point b){
Editing_File *file = view->file;
Face_ID face = file->settings.font_id;
f32 width = view_width(models, view);
return(file_buffer_point_difference(models, file, width, face, a, b));
}
internal Buffer_Point
view_move_buffer_point(Models *models, View *view, Buffer_Point buffer_point, Vec2_f32 delta){
delta += buffer_point.pixel_shift;
Line_Shift_Vertical shift = view_line_shift_y(models, view, buffer_point.line_number, delta.y);
buffer_point.line_number = shift.line;
buffer_point.pixel_shift = V2f32(delta.x, delta.y - shift.y_delta);
return(buffer_point);
}
internal Line_Shift_Character
view_line_shift_characters(Models *models, View *view, i64 line_number, i64 character_delta){
Editing_File *file = view->file;
Face_ID face = file->settings.font_id;
f32 width = view_width(models, view);
return(file_line_shift_characters(models, file, width, face, line_number, character_delta));
}
internal i64
view_line_character_difference(Models *models, View *view, i64 line_a, i64 line_b){
Editing_File *file = view->file;
Face_ID face = file->settings.font_id;
f32 width = view_width(models, view);
return(file_line_character_difference(models, file, width, face, line_a, line_b));
}
internal i64
view_pos_from_relative_character(Models *models, View *view, i64 base_line, i64 relative_character){
Editing_File *file = view->file;
Face_ID face = file->settings.font_id;
f32 width = view_width(models, view);
return(file_pos_from_relative_character(models, file, width, face, base_line, relative_character));
}
internal i64
view_relative_character_from_pos(Models *models, View *view, i64 base_line, i64 pos){
Editing_File *file = view->file;
Face_ID face = file->settings.font_id;
f32 width = view_width(models, view);
return(file_relative_character_from_pos(models, file, width, face, base_line, pos));
}
////////////////////////////////
internal b32
view_move_view_to_cursor(Models *models, View *view, GUI_Scroll_Vars *scroll){
System_Functions *system = models->system;
b32 result = false;
i32 max_x = (i32)view_width(models, view);
i32 max_y = view_compute_max_target_y(models, view);
Vec2_i32 cursor = view_get_cursor_xy(models, view);
GUI_Scroll_Vars scroll_vars = *scroll;
i32 target_x = scroll_vars.target_x;
i32 target_y = scroll_vars.target_y;
Cursor_Limits limits = view_cursor_limits(models, view);
if (target_y < cursor.y - limits.max){
target_y = cursor.y - limits.max + limits.delta;
internal Interval_f32
view_acceptable_y(f32 view_height, f32 line_height){
Interval_f32 acceptable_y = {};
if (view_height <= line_height*5.f){
if (view_height < line_height){
acceptable_y.max = view_height;
}
if (target_y > cursor.y - limits.min){
target_y = cursor.y - limits.min - limits.delta;
else{
acceptable_y.max = view_height - line_height;
}
target_y = clamp(0, target_y, max_y);
if (cursor.x >= target_x + max_x){
target_x = cursor.x - max_x/2;
}
else if (cursor.x < target_x){
target_x = clamp_bot(0, cursor.x - max_x/2);
else{
acceptable_y = If32(line_height*2.f, view_height - line_height*2.f);
}
return(acceptable_y);
}
if (target_x != scroll_vars.target_x || target_y != scroll_vars.target_y){
scroll->target_x = target_x;
scroll->target_y = target_y;
result = true;
}
return(result);
internal Vec2_f32
view_safety_margin(f32 view_width, f32 acceptable_y_height, f32 line_height, f32 typical_advance){
Vec2_f32 safety = {};
safety.y = min(line_height*5.f, (acceptable_y_height + 1.f)*0.5f);
safety.x = min(view_width*0.5f, typical_advance*8.f);
return(safety);
}
internal b32
view_move_cursor_to_view(Models *models, View *view, GUI_Scroll_Vars scroll, i32 *pos_in_out, f32 preferred_x){
System_Functions *system = models->system;
view_move_view_to_cursor(Models *models, View *view, Buffer_Scroll *scroll){
Editing_File *file = view->file;
Full_Cursor cursor = file_compute_cursor(models, file, seek_pos(*pos_in_out));
Face *face = font_set_face_from_id(&models->font_set, file->settings.font_id);
Face_ID face_id = file->settings.font_id;
Rect_f32 rect = view_get_buffer_rect(models, view);
Vec2_f32 view_dim = rect_dim(rect);
File_Edit_Positions edit_pos = view_get_edit_pos(view);
Vec2_f32 p = file_relative_xy_of_pos(models, file, view_dim.x, face_id, scroll->target.line_number,
edit_pos.cursor_pos);
p -= scroll->target.pixel_shift;
Face *face = font_set_face_from_id(&models->font_set, face_id);
f32 line_height = face->height;
f32 old_cursor_y = 0.f;
if (file->settings.unwrapped_lines){
old_cursor_y = cursor.unwrapped_y;
f32 typical_advance = face->typical_advance;
Interval_f32 acceptable_y = view_acceptable_y(view_dim.y, line_height);
Vec2_f32 safety = view_safety_margin(view_dim.x, range_size(acceptable_y), line_height, typical_advance);
Vec2_f32 target_p_relative = {};
if (p.y < acceptable_y.min){
target_p_relative.y = p.y - safety.y;
}
else if (p.y > acceptable_y.max){
target_p_relative.y = (p.y + safety.y) - view_dim.y;
}
if (p.x < 0.f){
target_p_relative.x = p.x - safety.x;
}
else if (p.x > view_dim.x){
target_p_relative.x = (p.x + safety.x) - view_dim.x;
}
scroll->target.pixel_shift = target_p_relative;
scroll->target = view_normalize_buffer_point(models, view, scroll->target);
scroll->target.pixel_shift.x = f32_round32(scroll->target.pixel_shift.x);
scroll->target.pixel_shift.y = f32_round32(scroll->target.pixel_shift.y);
return(target_p_relative != V2f32(0.f, 0.f));
}
internal b32
view_move_cursor_to_view(Models *models, View *view, Buffer_Scroll scroll, i64 *pos_in_out, f32 preferred_x){
Editing_File *file = view->file;
Face_ID face_id = file->settings.font_id;
Rect_f32 rect = view_get_buffer_rect(models, view);
Vec2_f32 view_dim = rect_dim(rect);
Vec2_f32 p = file_relative_xy_of_pos(models, file, view_dim.x, face_id, scroll.target.line_number, *pos_in_out);
p -= scroll.target.pixel_shift;
Face *face = font_set_face_from_id(&models->font_set, face_id);
f32 line_height = face->height;
Interval_f32 acceptable_y = view_acceptable_y(view_dim.y, line_height);
Vec2_f32 safety = view_safety_margin(view_dim.x, range_size(acceptable_y),
line_height, face->typical_advance);
b32 adjusted_y = true;
if (p.y < acceptable_y.min){
p.y = acceptable_y.min + safety.y;
}
else if (p.y > acceptable_y.max){
p.y = acceptable_y.max - safety.y;
}
else{
old_cursor_y = cursor.wrapped_y;
}
f32 cursor_y = old_cursor_y;
f32 target_y = (f32)scroll.target_y;
Cursor_Limits limits = view_cursor_limits(models, view);
if (cursor_y > target_y + limits.max){
cursor_y = target_y + limits.max;
}
if (target_y != 0 && cursor_y < target_y + limits.min){
cursor_y = target_y + limits.min;
adjusted_y = false;
}
b32 result = false;
if (cursor_y != old_cursor_y){
if (cursor_y > old_cursor_y){
cursor_y += line_height;
}
else{
cursor_y -= line_height;
}
Buffer_Seek seek = seek_xy(preferred_x, cursor_y, false, file->settings.unwrapped_lines);
cursor = file_compute_cursor(models, file, seek);
*pos_in_out = (i32)cursor.pos;
if (adjusted_y){
p += scroll.target.pixel_shift;
*pos_in_out = file_pos_at_relative_xy(models, file, view_dim.x, face_id, scroll.target.line_number, p);
result = true;
}
return(result);
}
internal b32
view_has_unwrapped_lines(View *view){
return(view->file->settings.unwrapped_lines);
}
internal void
view_set_preferred_x(View *view, Full_Cursor cursor){
if (view_has_unwrapped_lines(view)){
view->preferred_x = cursor.unwrapped_x;
}
else{
view->preferred_x = cursor.wrapped_x;
}
}
internal void
view_set_preferred_x_to_current_position(Models *models, View *view){
view->preferred_x = 0.f;
#if 0
File_Edit_Positions edit_pos = view_get_edit_pos(view);
Full_Cursor cursor = file_compute_cursor(models, view->file, seek_pos(edit_pos.cursor_pos));
view_set_preferred_x(view, cursor);
#endif
}
internal void
view_set_cursor(System_Functions *system, Models *models, View *view, Full_Cursor cursor, b32 set_preferred_x){
view_set_cursor(Models *models, View *view, i64 pos){
File_Edit_Positions edit_pos = view_get_edit_pos(view);
file_edit_positions_set_cursor(&edit_pos, (i32)cursor.pos);
if (set_preferred_x){
view_set_preferred_x(view, cursor);
}
file_edit_positions_set_cursor(&edit_pos, pos);
view->preferred_x = 0.f;
view_set_edit_pos(view, edit_pos);
GUI_Scroll_Vars scroll = edit_pos.scroll;
Buffer_Scroll scroll = edit_pos.scroll;
if (view_move_view_to_cursor(models, view, &scroll)){
edit_pos.scroll = scroll;
view_set_edit_pos(view, edit_pos);
@ -296,32 +344,27 @@ view_set_cursor(System_Functions *system, Models *models, View *view, Full_Curso
}
internal void
view_set_scroll(System_Functions *system, Models *models, View *view, GUI_Scroll_Vars scroll){
view_set_scroll(Models *models, View *view, Buffer_Scroll scroll){
File_Edit_Positions edit_pos = view_get_edit_pos(view);
file_edit_positions_set_scroll(&edit_pos, scroll, view_compute_max_target_y(models, view));
file_edit_positions_set_scroll(&edit_pos, scroll);
view_set_edit_pos(view, edit_pos);
i32 pos = (i32)edit_pos.cursor_pos;
if (view_move_cursor_to_view(models, view, edit_pos.scroll, &pos, view->preferred_x)){
Full_Cursor cursor = file_compute_cursor(models, view->file, seek_pos(pos));
edit_pos.cursor_pos = cursor.pos;
if (view_move_cursor_to_view(models, view, edit_pos.scroll, &edit_pos.cursor_pos, view->preferred_x)){
view_set_edit_pos(view, edit_pos);
}
}
internal void
view_set_cursor_and_scroll(Models *models, View *view, Full_Cursor cursor, b32 set_preferred_x, GUI_Scroll_Vars scroll){
view_set_cursor_and_scroll(Models *models, View *view, i64 pos, b32 set_preferred_x, Buffer_Scroll scroll){
File_Edit_Positions edit_pos = view_get_edit_pos(view);
file_edit_positions_set_cursor(&edit_pos, (i32)cursor.pos);
if (set_preferred_x){
view_set_preferred_x(view, cursor);
}
file_edit_positions_set_scroll(&edit_pos, scroll, view_compute_max_target_y(models, view));
file_edit_positions_set_cursor(&edit_pos, pos);
view->preferred_x = 0.f;
file_edit_positions_set_scroll(&edit_pos, scroll);
edit_pos.last_set_type = EditPos_None;
view_set_edit_pos(view, edit_pos);
}
internal void
view_post_paste_effect(View *view, f32 seconds, i32 start, i32 size, u32 color){
view_post_paste_effect(View *view, f32 seconds, i64 start, i64 size, u32 color){
Editing_File *file = view->file;
file->state.paste_effect.start = start;
file->state.paste_effect.end = start + size;
@ -381,24 +424,14 @@ adjust_views_looking_at_file_to_new_cursor(System_Functions *system, Models *mod
View *view = panel->view;
if (view->file == file){
File_Edit_Positions edit_pos = view_get_edit_pos(view);
Full_Cursor cursor = file_compute_cursor(models, file, seek_pos(edit_pos.cursor_pos));
view_set_cursor(system, models, view, cursor, true);
view_set_cursor(models, view, edit_pos.cursor_pos);
}
}
}
internal void
file_full_remeasure(System_Functions *system, Models *models, Editing_File *file){
Face_ID font_id = file->settings.font_id;
Face *face = font_set_face_from_id(&models->font_set, font_id);
file_measure_wraps(system, &models->mem, file, face);
adjust_views_looking_at_file_to_new_cursor(system, models, file);
}
internal void
file_set_font(System_Functions *system, Models *models, Editing_File *file, Face_ID font_id){
file->settings.font_id = font_id;
file_full_remeasure(system, models, file);
}
internal void
@ -412,23 +445,6 @@ global_set_font_and_update_files(System_Functions *system, Models *models, Face_
models->global_font_id = font_id;
}
internal b32
alter_font_and_update_files(System_Functions *system, Models *models, Face_ID face_id, Face_Description *new_description){
b32 success = false;
if (font_set_modify_face(&models->font_set, face_id, new_description)){
success = true;
for (Node *node = models->working_set.active_file_sentinel.next;
node != &models->working_set.active_file_sentinel;
node = node->next){
Editing_File *file = CastFromMember(Editing_File, main_chain_node, node);
if (file->settings.font_id == face_id){
file_full_remeasure(system, models, file);
}
}
}
return(success);
}
internal b32
release_font_and_update_files(System_Functions *system, Models *models, Face_ID font_id, Face_ID replacement_id){
b32 success = false;
@ -511,110 +527,57 @@ get_token_color(Color_Table color_table, Cpp_Token token){
return(result);
}
internal void
view_quit_ui(System_Functions *system, Models *models, View *view){
Assert(view != 0);
view->ui_mode = false;
if (view->ui_quit != 0){
view->ui_quit(&models->app_links, view_get_id(&models->live_set, view));
view->ui_quit = 0;
}
}
////////////////////////////////
internal View*
imp_get_view(Models *models, View_ID view_id){
Live_Views *live_set = &models->live_set;
View *view = 0;
view_id -= 1;
if (0 <= view_id && view_id < live_set->max){
view = live_set->views + view_id;
if (!view->in_use){
view = 0;
}
}
return(view);
}
////////////////////////////////
#if 0
internal void
render_loaded_file_in_view__inner(Models *models, Render_Target *target, View *view,
Rect_i32 rect, Full_Cursor render_cursor, Range on_screen_range,
Buffer_Render_Item *items, int_color *item_colors, i32 item_count){
Editing_File *file = view->file;
Arena *scratch = &models->mem.arena;
Color_Table color_table = models->color_table;
Font_Set *font_set = &models->font_set;
Assert(file != 0);
Assert(buffer_good(&file->state.buffer));
Rect_i32 rect,
Full_Cursor render_cursor,
Interval_i64 on_screen_range,
Buffer_Layout_Item_List list,
int_color *item_colors){
Cpp_Token_Array token_array = file->state.token_array;
b32 tokens_use = (token_array.tokens != 0);
b32 wrapped = (!file->settings.unwrapped_lines);
Face_ID font_id = file->settings.font_id;
i64 token_i = 0;
i32 *line_starts = file->state.buffer.line_starts;
i32 line_count = file->state.buffer.line_count;
i32 line_scan_index = (i32)render_cursor.line - 1;
i32 first_byte_index_of_next_line = 0;
if (line_scan_index + 1 < line_count){
first_byte_index_of_next_line = line_starts[line_scan_index + 1];
}
else{
first_byte_index_of_next_line = max_i32;
}
i32 *wrap_starts = file->state.wrap_positions;
i32 wrap_count = file->state.wrap_position_count;
if (wrap_count > 0 && wrap_starts[wrap_count - 1] == buffer_size(&file->state.buffer)){
wrap_count -= 1;
}
i32 wrap_scan_index = (i32)render_cursor.wrap_line - (i32)render_cursor.line;
i32 first_byte_index_of_next_wrap = 0;
if (wrap_scan_index + 1 < wrap_count){
first_byte_index_of_next_wrap = wrap_starts[wrap_scan_index + 1];
}
else{
first_byte_index_of_next_wrap = max_i32;
}
i32 visual_markers_scan_index = 0;
i32 visual_line_markers_scan_index = 0;
u32 visual_line_markers_color = 0;
i32 visual_range_markers_scan_index = 0;
i32 visual_line_range_markers_scan_index = 0;
i32 token_i = 0;
u32 main_color = color_table.vals[Stag_Default];
u32 special_color = color_table.vals[Stag_Special_Character];
u32 ghost_color = color_table.vals[Stag_Ghost_Character];
if (tokens_use){
Cpp_Get_Token_Result result = cpp_get_token(token_array, items->index);
Cpp_Get_Token_Result result = cpp_get_token(token_array, (i32)items->index);
main_color = get_token_color(color_table, token_array.tokens[result.token_index]);
token_i = result.token_index + 1;
}
Buffer_Render_Item *item = items;
Buffer_Render_Item *item_end = item + item_count;
i32 prev_ind = -1;
u32 highlight_color = 0;
for (i32 i = 0; item < item_end; item += 1, i += 1){
i32 ind = item->index;
// NOTE(allen): Line scanning
b32 is_new_line = false;
for (; line_scan_index < line_count;){
if (ind < first_byte_index_of_next_line){
break;
}
line_scan_index += 1;
is_new_line = true;
if (line_scan_index + 1 < line_count){
first_byte_index_of_next_line = line_starts[line_scan_index + 1];
}
else{
first_byte_index_of_next_line = max_i32;
}
}
if (item == items){
is_new_line = true;
}
// NOTE(allen): Wrap scanning
b32 is_new_wrap = false;
if (wrapped){
for (; wrap_scan_index < wrap_count;){
if (ind < first_byte_index_of_next_wrap){
break;
}
wrap_scan_index += 1;
is_new_wrap = true;
if (wrap_scan_index + 1 < wrap_count){
first_byte_index_of_next_wrap = wrap_starts[wrap_scan_index + 1];
}
else{
first_byte_index_of_next_wrap = max_i32;
}
}
}
{
i64 ind = item->index;
// NOTE(allen): Token scanning
u32 highlight_this_color = 0;
@ -641,12 +604,9 @@ render_loaded_file_in_view__inner(Models *models, Render_Target *target, View *v
}
}
if (item->y1 > 0){
Rect_f32 char_rect = f32R(item->x0, item->y0, item->x1, item->y1);
u32 char_color = main_color;
if (on_screen_range.min <= ind && ind < on_screen_range.max){
i32 index_shifted = ind - on_screen_range.min;
i64 index_shifted = ind - on_screen_range.min;
if (item_colors[index_shifted] != 0){
char_color = finalize_color(color_table, item_colors[index_shifted]);
}
@ -690,77 +650,15 @@ render_loaded_file_in_view__inner(Models *models, Render_Target *target, View *v
fade_amount /= file->state.paste_effect.seconds_max;
}
char_color = color_blend(char_color, fade_amount, fade_color);
if (item->codepoint != 0){
draw_font_glyph(target, font_set, font_id, item->codepoint, item->x0, item->y0, char_color, GlyphFlag_None);
}
if (color_wireframe != 0){
draw_rectangle_outline(target, char_rect, color_wireframe);
}
}
prev_ind = ind;
}
}
internal Full_Cursor
file_get_render_cursor(Models *models, Editing_File *file, f32 scroll_y){
Full_Cursor result = {};
if (file->settings.unwrapped_lines){
result = file_compute_cursor_hint(models, file, seek_unwrapped_xy(0, scroll_y, false));
}
else{
result = file_compute_cursor(models, file, seek_wrapped_xy(0, scroll_y, false));
}
return(result);
}
internal Full_Cursor
view_get_render_cursor(Models *models, View *view, f32 scroll_y){
return(file_get_render_cursor(models, view->file, scroll_y));
}
internal Full_Cursor
view_get_render_cursor(Models *models, View *view){
File_Edit_Positions edit_pos = view_get_edit_pos(view);
f32 scroll_y = edit_pos.scroll.scroll_y;
//scroll_y += view->widget_height;
return(view_get_render_cursor(models, view, scroll_y));
}
internal Full_Cursor
view_get_render_cursor_target(Models *models, View *view){
File_Edit_Positions edit_pos = view_get_edit_pos(view);
f32 scroll_y = (f32)edit_pos.scroll.target_y;
//scroll_y += view->widget_height;
return(view_get_render_cursor(models, view, scroll_y));
}
internal void
view_quit_ui(System_Functions *system, Models *models, View *view){
Assert(view != 0);
view->ui_mode = false;
if (view->ui_quit != 0){
view->ui_quit(&models->app_links, view_get_id(&models->live_set, view));
view->ui_quit = 0;
}
}
////////////////////////////////
internal View*
imp_get_view(Models *models, View_ID view_id){
Live_Views *live_set = &models->live_set;
View *view = 0;
view_id -= 1;
if (0 <= view_id && view_id < live_set->max){
view = live_set->views + view_id;
if (!view->in_use){
view = 0;
}
}
return(view);
}
#endif
// BOTTOM

View File

@ -25,36 +25,24 @@ struct View{
i64 mark;
f32 preferred_x;
// TODO(allen): ELIMINATE THESE
i32 temp_view_top_left_pos;
i32 temp_view_top_left_target_pos;
b32 ui_mode;
b8 new_scroll_target;
b8 ui_mode;
i32 ui_map_id;
GUI_Scroll_Vars ui_scroll;
Basic_Scroll ui_scroll;
UI_Quit_Function_Type *ui_quit;
Vec2_i32 prev_target;
b32 hide_scrollbar;
b32 hide_file_bar;
b32 show_whitespace;
b8 hide_scrollbar;
b8 hide_file_bar;
b8 show_whitespace;
// misc
Query_Set query_set;
// Render Context
Arena layout_arena;
struct{
Rect_i32 view_rect;
Rect_i32 buffer_rect;
Full_Cursor cursor;
Range range;
Buffer_Render_Item *items;
int_color *item_colors;
i32 item_count;
} render;
};
struct Live_Views{
@ -64,12 +52,6 @@ struct Live_Views{
i32 max;
};
struct Cursor_Limits{
i32 min;
i32 max;
i32 delta;
};
enum{
GROW_FAILED,
GROW_NOT_NEEDED,

View File

@ -1,180 +0,0 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* ??.??.2018
*
* View GUI layouts and implementations
*
*/
// TOP
internal GUI_Scroll_Vars
do_step_file_view(System_Functions *system, Models *models, View *view, i32_Rect rect, b32 is_active, f32 dt, GUI_Scroll_Vars scroll){
Editing_File *file = view->file;
// TODO(allen): do(eliminate the built in paste_effect)
if (!file->is_loading && file->state.paste_effect.seconds_down > 0.f){
file->state.paste_effect.seconds_down -= dt;
models->animate_next_frame = true;
}
// NOTE(allen): call scroll rule hook
b32 is_new_target = (scroll.target_x != view->prev_target.x || scroll.target_y != view->prev_target.y);
f32 target_x = (f32)scroll.target_x;
f32 target_y = (f32)scroll.target_y;
View_ID view_id = view_get_id(&models->live_set, view);
if (models->scroll_rule(target_x, target_y, &scroll.scroll_x, &scroll.scroll_y, view_id, is_new_target, dt)){
models->animate_next_frame = true;
}
view->prev_target.x = scroll.target_x;
view->prev_target.y = scroll.target_y;
return(scroll);
}
////////////////////////////////
#if 0
internal void
do_render_file_view(System_Functions *system, View *view, Models *models, GUI_Scroll_Vars *scroll, View *active, i32_Rect rect, b32 is_active, Render_Target *target){
Editing_File *file = view->file;
Assert(file != 0);
draw_push_clip(target, rect);
if (!view->ui_mode){
if (file_is_ready(file)){
Rect_i32 buffer_rect = view_get_buffer_rect(models, view);
//render_loaded_file_in_view(system, view, models, buffer_rect, is_active, target);
Editing_File *file = view->file;
i32 line_height = view->line_height;
f32 max_x = (f32)file->settings.display_width;
i32 max_y = buffer_rect.y1 - buffer_rect.y0 + line_height;
Assert(file != 0);
Assert(!file->is_dummy);
Assert(buffer_good(&file->state.buffer));
Partition *part = &models->mem.part;
Temp_Memory temp = begin_temp_memory(part);
push_align(part, 4);
f32 left_side_space = 0;
i32 max = part_remaining(part)/sizeof(Buffer_Render_Item);
Buffer_Render_Item *items = push_array(part, Buffer_Render_Item, 0);
b32 wrapped = !file->settings.unwrapped_lines;
Face_ID font_id = file->settings.font_id;
Font_Pointers font = system->font.get_pointers_by_id(font_id);
File_Edit_Positions edit_pos = view_get_edit_pos(view);
f32 scroll_x = edit_pos.scroll.scroll_x;
f32 scroll_y = edit_pos.scroll.scroll_y;
Full_Cursor render_cursor = view_get_render_cursor(system, view);
i32 item_count = 0;
i32 end_pos = 0;
{
Buffer_Render_Params params;
params.buffer = &file->state.buffer;
params.items = items;
params.max = max;
params.count = &item_count;
params.port_x = (f32)buffer_rect.x0 + left_side_space;
params.port_y = (f32)buffer_rect.y0;
params.clip_w = view_width(models, view) - left_side_space;
params.scroll_x = scroll_x;
params.scroll_y = scroll_y;
params.width = max_x;
params.height = (f32)max_y;
params.start_cursor = render_cursor;
params.wrapped = wrapped;
params.system = system;
params.font = font;
params.virtual_white = file->settings.virtual_white;
params.wrap_slashes = file->settings.wrap_indicator;
Buffer_Render_State state = {};
Buffer_Layout_Stop stop = {};
f32 line_shift = 0.f;
b32 do_wrap = false;
i32 wrap_unit_end = 0;
b32 first_wrap_determination = true;
i32 wrap_array_index = 0;
do{
stop = buffer_render_data(&state, params, line_shift, do_wrap, wrap_unit_end);
switch (stop.status){
case BLStatus_NeedWrapDetermination:
{
if (first_wrap_determination){
wrap_array_index = binary_search(file->state.wrap_positions, stop.pos, 0, file->state.wrap_position_count);
++wrap_array_index;
if (file->state.wrap_positions[wrap_array_index] == stop.pos){
do_wrap = true;
wrap_unit_end = file->state.wrap_positions[wrap_array_index];
}
else{
do_wrap = false;
wrap_unit_end = file->state.wrap_positions[wrap_array_index];
}
first_wrap_determination = false;
}
else{
Assert(stop.pos == wrap_unit_end);
do_wrap = true;
++wrap_array_index;
wrap_unit_end = file->state.wrap_positions[wrap_array_index];
}
}break;
case BLStatus_NeedWrapLineShift:
case BLStatus_NeedLineShift:
{
line_shift = file->state.line_indents[stop.wrap_line_index];
}break;
}
}while(stop.status != BLStatus_Finished);
end_pos = state.i;
}
push_array(part, Buffer_Render_Item, item_count);
Range on_screen_range = {};
on_screen_range.first = render_cursor.pos;
on_screen_range.one_past_last = end_pos;
////////////////////////////////
if (models->render_caller != 0){
view_call_render_caller(models, target, view, buffer_rect, render_cursor, on_screen_range, items, item_count, do_core_render);
}
else{
render_loaded_file_in_view__inner(models, target, view, buffer_rect, render_cursor, on_screen_range, items, item_count);
}
end_temp_memory(temp);
}
}
else{
Full_Cursor render_cursor = {};
Range on_screen_range = {};
if (models->render_caller != 0){
view_call_render_caller(models, target, view, buffer_rect, render_cursor, on_screen_range, 0, 0, dont_do_core_render);
}
}
draw_pop_clip(target);
}
#endif
// BOTTOM

View File

@ -12,9 +12,9 @@
internal void
working_set_file_default_settings(Working_Set *working_set, Editing_File *file){
block_zero_struct(&file->settings);
file->settings.display_width = working_set->default_display_width;
file->settings.minimum_base_display_width = working_set->default_minimum_base_display_width;
file->settings.wrap_indicator = WrapIndicator_Show_At_Wrap_Edge;
//file->settings.display_width = working_set->default_display_width;
//file->settings.minimum_base_display_width = working_set->default_minimum_base_display_width;
//file->settings.wrap_indicator = WrapIndicator_Show_At_Wrap_Edge;
}
////////////////////////////////

View File

@ -13,11 +13,6 @@
#include "../4coder_base_types.h"
#if 0
# define FSTRING_IMPLEMENTATION
# include "../4coder_lib/4coder_string.h"
#endif
#define FTECH_FILE_MOVING_IMPLEMENTATION
#include "4ed_file_moving.h"
@ -584,12 +579,14 @@ build_main(Arena *arena, char *cdir, b32 update_local_theme, u32 flags, u32 arch
internal void
standard_build(Arena *arena, char *cdir, u32 flags, u32 arch){
fsm_generator(arena, cdir);
//fsm_generator(arena, cdir);
metagen(arena, cdir);
//do_buildsuper(arena, cdir, fm_str(arena, custom_files[Custom_Default]), arch);
do_buildsuper(arena, cdir, fm_str(arena, custom_files[Custom_Experiments]), arch);
//do_buildsuper(arena, cdir, fm_str(arena, custom_files[Custom_Casey]), arch);
//do_buildsuper(arena, cdir, fm_str(arena, custom_files[Custom_ChronalVim]), arch);
build_main(arena, cdir, true, flags, arch);
}

View File

@ -1,245 +0,0 @@
// old string api
// TOP
#if !defined(OLD_STRING_API_H)
#define OLD_STRING_API_H
struct String_OLD{
char *str;
i32 size;
i32 memory_size;
};
static String null_string = {};
FSTRING_INLINE b32_4tech char_is_slash(char c);
FSTRING_INLINE b32_4tech char_is_upper(char c);
FSTRING_INLINE b32_4tech char_is_upper_utf8(char c);
FSTRING_INLINE b32_4tech char_is_lower(char c);
FSTRING_INLINE b32_4tech char_is_lower_utf8(u8_4tech c);
FSTRING_INLINE char char_to_upper(char c);
FSTRING_INLINE char char_to_lower(char c);
FSTRING_INLINE b32_4tech char_is_whitespace(char c);
FSTRING_INLINE b32_4tech char_is_alpha_numeric(char c);
FSTRING_INLINE b32_4tech char_is_alpha_numeric_utf8(u8_4tech c);
FSTRING_INLINE b32_4tech char_is_alpha_numeric_true(char c);
FSTRING_INLINE b32_4tech char_is_alpha_numeric_true_utf8(u8_4tech c);
FSTRING_INLINE b32_4tech char_is_alpha(char c);
FSTRING_INLINE b32_4tech char_is_alpha_utf8(u8_4tech c);
FSTRING_INLINE b32_4tech char_is_alpha_true(char c);
FSTRING_INLINE b32_4tech char_is_alpha_true_utf8(u8_4tech c);
FSTRING_INLINE b32_4tech char_is_hex(char c);
FSTRING_INLINE b32_4tech char_is_hex_utf8(u8_4tech c);
FSTRING_INLINE b32_4tech char_is_numeric(char c);
FSTRING_INLINE b32_4tech char_is_numeric_utf8(u8_4tech c);
FSTRING_INLINE String make_string_cap(void *str, i32_4tech size, i32_4tech mem_size);
FSTRING_INLINE String make_string(void *str, i32_4tech size);
#ifndef make_lit_string
# define make_lit_string(s) (make_string_cap((char*)(s), sizeof(s)-1, sizeof(s)))
#endif
#ifndef lit
# define lit(s) make_lit_string(s)
#endif
#ifndef make_fixed_width_string
# define make_fixed_width_string(s) (make_string_cap((char*)(s), 0, sizeof(s)))
#endif
#ifndef expand_str
# define expand_str(s) ((s).str), ((s).size)
#endif
FSTRING_LINK i32_4tech str_size(char *str);
FSTRING_INLINE String make_string_slowly(void *str);
FSTRING_INLINE String substr_tail(String str, i32_4tech start);
FSTRING_INLINE String substr(String str, i32_4tech start, i32_4tech size);
FSTRING_LINK String skip_whitespace(String str);
FSTRING_LINK String skip_whitespace_measure(String str, i32_4tech *skip_length);
FSTRING_LINK String chop_whitespace(String str);
FSTRING_LINK String skip_chop_whitespace(String str);
FSTRING_LINK String skip_chop_whitespace_measure(String str, i32_4tech *skip_length);
FSTRING_INLINE String tailstr(String str);
FSTRING_LINK b32_4tech match_cc(char *a, char *b);
FSTRING_LINK b32_4tech match_sc(String a, char *b);
FSTRING_INLINE b32_4tech match_cs(char *a, String b);
FSTRING_LINK b32_4tech match_ss(String a, String b);
FSTRING_LINK b32_4tech match_part_ccl(char *a, char *b, i32_4tech *len);
FSTRING_LINK b32_4tech match_part_scl(String a, char *b, i32_4tech *len);
FSTRING_INLINE b32_4tech match_part_cc(char *a, char *b);
FSTRING_INLINE b32_4tech match_part_sc(String a, char *b);
FSTRING_LINK b32_4tech match_part_cs(char *a, String b);
FSTRING_LINK b32_4tech match_part_ss(String a, String b);
FSTRING_LINK b32_4tech match_insensitive_cc(char *a, char *b);
FSTRING_LINK b32_4tech match_insensitive_sc(String a, char *b);
FSTRING_INLINE b32_4tech match_insensitive_cs(char *a, String b);
FSTRING_LINK b32_4tech match_insensitive_ss(String a, String b);
FSTRING_LINK b32_4tech match_part_insensitive_ccl(char *a, char *b, i32_4tech *len);
FSTRING_LINK b32_4tech match_part_insensitive_scl(String a, char *b, i32_4tech *len);
FSTRING_INLINE b32_4tech match_part_insensitive_cc(char *a, char *b);
FSTRING_INLINE b32_4tech match_part_insensitive_sc(String a, char *b);
FSTRING_LINK b32_4tech match_part_insensitive_cs(char *a, String b);
FSTRING_LINK b32_4tech match_part_insensitive_ss(String a, String b);
FSTRING_LINK i32_4tech compare_cc(char *a, char *b);
FSTRING_LINK i32_4tech compare_sc(String a, char *b);
FSTRING_INLINE i32_4tech compare_cs(char *a, String b);
FSTRING_LINK i32_4tech compare_ss(String a, String b);
FSTRING_LINK i32_4tech find_c_char(char *str, i32_4tech start, char character);
FSTRING_LINK i32_4tech find_s_char(String str, i32_4tech start, char character);
FSTRING_LINK i32_4tech rfind_s_char(String str, i32_4tech start, char character);
FSTRING_LINK i32_4tech find_c_chars(char *str, i32_4tech start, char *characters);
FSTRING_LINK i32_4tech find_s_chars(String str, i32_4tech start, char *characters);
FSTRING_LINK i32_4tech find_substr_c(char *str, i32_4tech start, String seek);
FSTRING_LINK i32_4tech find_substr_s(String str, i32_4tech start, String seek);
FSTRING_LINK i32_4tech rfind_substr_s(String str, i32_4tech start, String seek);
FSTRING_LINK i32_4tech find_substr_insensitive_c(char *str, i32_4tech start, String seek);
FSTRING_LINK i32_4tech find_substr_insensitive_s(String str, i32_4tech start, String seek);
FSTRING_INLINE b32_4tech has_substr_c(char *s, String seek);
FSTRING_INLINE b32_4tech has_substr_s(String s, String seek);
FSTRING_INLINE b32_4tech has_substr_insensitive_c(char *s, String seek);
FSTRING_INLINE b32_4tech has_substr_insensitive_s(String s, String seek);
FSTRING_LINK i32_4tech copy_fast_unsafe_cc(char *dest, char *src);
FSTRING_LINK i32_4tech copy_fast_unsafe_cs(char *dest, String src);
FSTRING_LINK b32_4tech copy_checked_ss(String *dest, String src);
FSTRING_LINK b32_4tech copy_checked_cs(char *dest, i32_4tech dest_cap, String src);
FSTRING_LINK b32_4tech copy_partial_sc(String *dest, char *src);
FSTRING_LINK b32_4tech copy_partial_ss(String *dest, String src);
FSTRING_LINK b32_4tech copy_partial_cs(char *dest, i32_4tech dest_cap, String src);
FSTRING_INLINE i32_4tech copy_cc(char *dest, char *src);
FSTRING_INLINE void copy_ss(String *dest, String src);
FSTRING_INLINE void copy_sc(String *dest, char *src);
FSTRING_LINK b32_4tech append_checked_ss(String *dest, String src);
FSTRING_LINK b32_4tech append_partial_sc(String *dest, char *src);
FSTRING_LINK b32_4tech append_partial_ss(String *dest, String src);
FSTRING_LINK b32_4tech append_s_char(String *dest, char c);
FSTRING_INLINE b32_4tech append_ss(String *dest, String src);
FSTRING_INLINE b32_4tech append_sc(String *dest, char *src);
FSTRING_LINK b32_4tech terminate_with_null(String *str);
FSTRING_LINK b32_4tech append_padding(String *dest, char c, i32_4tech target_size);
FSTRING_LINK void string_interpret_escapes(String src, char *dst);
FSTRING_LINK void replace_char(String *str, char replace, char with);
FSTRING_LINK void replace_str_ss(String *str, String replace, String with);
FSTRING_LINK void replace_str_sc(String *str, String replace, char *with);
FSTRING_LINK void replace_str_cs(String *str, char *replace, String with);
FSTRING_LINK void replace_str_cc(String *str, char *replace, char *with);
FSTRING_LINK void to_lower_cc(char *src, char *dst);
FSTRING_LINK void to_lower_ss(String *dst, String src);
FSTRING_LINK void to_lower_s(String *str);
FSTRING_LINK void to_upper_cc(char *src, char *dst);
FSTRING_LINK void to_upper_ss(String *dst, String src);
FSTRING_LINK void to_upper_s(String *str);
FSTRING_LINK void to_camel_cc(char *src, char *dst);
FSTRING_LINK i32_4tech int_to_str_size(i32_4tech x);
FSTRING_LINK b32_4tech int_to_str(String *dest, i32_4tech x);
FSTRING_LINK b32_4tech append_int_to_str(String *dest, i32_4tech x);
FSTRING_LINK i32_4tech u64_to_str_size(uint64_t x);
FSTRING_LINK b32_4tech u64_to_str(String *dest, uint64_t x);
FSTRING_LINK b32_4tech append_u64_to_str(String *dest, uint64_t x);
FSTRING_LINK i32_4tech float_to_str_size(float x);
FSTRING_LINK b32_4tech append_float_to_str(String *dest, float x);
FSTRING_LINK b32_4tech float_to_str(String *dest, float x);
FSTRING_LINK i32_4tech str_is_int_c(char *str);
FSTRING_LINK b32_4tech str_is_int_s(String str);
FSTRING_LINK i32_4tech str_to_int_c(char *str);
FSTRING_LINK i32_4tech str_to_int_s(String str);
FSTRING_LINK i32_4tech hexchar_to_int(char c);
FSTRING_LINK char int_to_hexchar(i32_4tech x);
FSTRING_LINK u32_4tech hexstr_to_int(String str);
FSTRING_LINK b32_4tech color_to_hexstr(String *s, u32_4tech color);
FSTRING_LINK b32_4tech hexstr_to_color(String s, u32_4tech *out);
FSTRING_LINK i32_4tech reverse_seek_slash_pos(String str, i32_4tech pos);
FSTRING_INLINE i32_4tech reverse_seek_slash(String str);
FSTRING_INLINE String front_of_directory(String dir);
FSTRING_INLINE String path_of_directory(String dir);
FSTRING_LINK b32_4tech set_last_folder_sc(String *dir, char *folder_name, char slash);
FSTRING_LINK b32_4tech set_last_folder_ss(String *dir, String folder_name, char slash);
FSTRING_LINK String file_extension(String str);
FSTRING_LINK b32_4tech remove_extension(String *str);
FSTRING_LINK b32_4tech remove_last_folder(String *str);
FSTRING_LINK b32_4tech string_set_match_table(void *str_set, i32_4tech item_size, i32_4tech count, String str, i32_4tech *match_index);
FSTRING_LINK b32_4tech string_set_match(String *str_set, i32_4tech count, String str, i32_4tech *match_index);
FSTRING_LINK String get_first_double_line(String source);
FSTRING_LINK String get_next_double_line(String source, String line);
FSTRING_LINK String get_next_word(String source, String prev_word);
FSTRING_LINK String get_first_word(String source);
FSTRING_LINK String string_push(Partition *part, i32_4tech size);
FSTRING_LINK String string_push_copy(Partition *part, String str);
FSTRING_INLINE String make_string(void *str, i32_4tech size, i32_4tech mem_size){return(make_string_cap(str,size,mem_size));}
FSTRING_INLINE String substr(String str, i32_4tech start){return(substr_tail(str,start));}
FSTRING_LINK String skip_whitespace(String str, i32_4tech *skip_length){return(skip_whitespace_measure(str,skip_length));}
FSTRING_LINK String skip_chop_whitespace(String str, i32_4tech *skip_length){return(skip_chop_whitespace_measure(str,skip_length));}
FSTRING_LINK b32_4tech match(char *a, char *b){return(match_cc(a,b));}
FSTRING_LINK b32_4tech match(String a, char *b){return(match_sc(a,b));}
FSTRING_INLINE b32_4tech match(char *a, String b){return(match_cs(a,b));}
FSTRING_LINK b32_4tech match(String a, String b){return(match_ss(a,b));}
FSTRING_LINK b32_4tech match_part(char *a, char *b, i32_4tech *len){return(match_part_ccl(a,b,len));}
FSTRING_LINK b32_4tech match_part(String a, char *b, i32_4tech *len){return(match_part_scl(a,b,len));}
FSTRING_INLINE b32_4tech match_part(char *a, char *b){return(match_part_cc(a,b));}
FSTRING_INLINE b32_4tech match_part(String a, char *b){return(match_part_sc(a,b));}
FSTRING_LINK b32_4tech match_part(char *a, String b){return(match_part_cs(a,b));}
FSTRING_LINK b32_4tech match_part(String a, String b){return(match_part_ss(a,b));}
FSTRING_LINK b32_4tech match_insensitive(char *a, char *b){return(match_insensitive_cc(a,b));}
FSTRING_LINK b32_4tech match_insensitive(String a, char *b){return(match_insensitive_sc(a,b));}
FSTRING_INLINE b32_4tech match_insensitive(char *a, String b){return(match_insensitive_cs(a,b));}
FSTRING_LINK b32_4tech match_insensitive(String a, String b){return(match_insensitive_ss(a,b));}
FSTRING_LINK b32_4tech match_part_insensitive(char *a, char *b, i32_4tech *len){return(match_part_insensitive_ccl(a,b,len));}
FSTRING_LINK b32_4tech match_part_insensitive(String a, char *b, i32_4tech *len){return(match_part_insensitive_scl(a,b,len));}
FSTRING_INLINE b32_4tech match_part_insensitive(char *a, char *b){return(match_part_insensitive_cc(a,b));}
FSTRING_INLINE b32_4tech match_part_insensitive(String a, char *b){return(match_part_insensitive_sc(a,b));}
FSTRING_LINK b32_4tech match_part_insensitive(char *a, String b){return(match_part_insensitive_cs(a,b));}
FSTRING_LINK b32_4tech match_part_insensitive(String a, String b){return(match_part_insensitive_ss(a,b));}
FSTRING_LINK i32_4tech compare(char *a, char *b){return(compare_cc(a,b));}
FSTRING_LINK i32_4tech compare(String a, char *b){return(compare_sc(a,b));}
FSTRING_INLINE i32_4tech compare(char *a, String b){return(compare_cs(a,b));}
FSTRING_LINK i32_4tech compare(String a, String b){return(compare_ss(a,b));}
FSTRING_LINK i32_4tech find(char *str, i32_4tech start, char character){return(find_c_char(str,start,character));}
FSTRING_LINK i32_4tech find(String str, i32_4tech start, char character){return(find_s_char(str,start,character));}
FSTRING_LINK i32_4tech rfind(String str, i32_4tech start, char character){return(rfind_s_char(str,start,character));}
FSTRING_LINK i32_4tech find(char *str, i32_4tech start, char *characters){return(find_c_chars(str,start,characters));}
FSTRING_LINK i32_4tech find(String str, i32_4tech start, char *characters){return(find_s_chars(str,start,characters));}
FSTRING_LINK i32_4tech find_substr(char *str, i32_4tech start, String seek){return(find_substr_c(str,start,seek));}
FSTRING_LINK i32_4tech find_substr(String str, i32_4tech start, String seek){return(find_substr_s(str,start,seek));}
FSTRING_LINK i32_4tech rfind_substr(String str, i32_4tech start, String seek){return(rfind_substr_s(str,start,seek));}
FSTRING_LINK i32_4tech find_substr_insensitive(char *str, i32_4tech start, String seek){return(find_substr_insensitive_c(str,start,seek));}
FSTRING_LINK i32_4tech find_substr_insensitive(String str, i32_4tech start, String seek){return(find_substr_insensitive_s(str,start,seek));}
FSTRING_INLINE b32_4tech has_substr(char *s, String seek){return(has_substr_c(s,seek));}
FSTRING_INLINE b32_4tech has_substr(String s, String seek){return(has_substr_s(s,seek));}
FSTRING_INLINE b32_4tech has_substr_insensitive(char *s, String seek){return(has_substr_insensitive_c(s,seek));}
FSTRING_INLINE b32_4tech has_substr_insensitive(String s, String seek){return(has_substr_insensitive_s(s,seek));}
FSTRING_LINK i32_4tech copy_fast_unsafe(char *dest, char *src){return(copy_fast_unsafe_cc(dest,src));}
FSTRING_LINK i32_4tech copy_fast_unsafe(char *dest, String src){return(copy_fast_unsafe_cs(dest,src));}
FSTRING_LINK b32_4tech copy_checked(String *dest, String src){return(copy_checked_ss(dest,src));}
FSTRING_LINK b32_4tech copy_checked(char *dest, i32_4tech dest_cap, String src){return(copy_checked_cs(dest,dest_cap,src));}
FSTRING_LINK b32_4tech copy_partial(String *dest, char *src){return(copy_partial_sc(dest,src));}
FSTRING_LINK b32_4tech copy_partial(String *dest, String src){return(copy_partial_ss(dest,src));}
FSTRING_LINK b32_4tech copy_partial(char *dest, i32_4tech dest_cap, String src){return(copy_partial_cs(dest,dest_cap,src));}
FSTRING_INLINE i32_4tech copy(char *dest, char *src){return(copy_cc(dest,src));}
FSTRING_INLINE void copy(String *dest, String src){return(copy_ss(dest,src));}
FSTRING_INLINE void copy(String *dest, char *src){return(copy_sc(dest,src));}
FSTRING_LINK b32_4tech append_checked(String *dest, String src){return(append_checked_ss(dest,src));}
FSTRING_LINK b32_4tech append_partial(String *dest, char *src){return(append_partial_sc(dest,src));}
FSTRING_LINK b32_4tech append_partial(String *dest, String src){return(append_partial_ss(dest,src));}
FSTRING_LINK b32_4tech append(String *dest, char c){return(append_s_char(dest,c));}
FSTRING_INLINE b32_4tech append(String *dest, String src){return(append_ss(dest,src));}
FSTRING_INLINE b32_4tech append(String *dest, char *src){return(append_sc(dest,src));}
FSTRING_LINK void replace_str(String *str, String replace, String with){return(replace_str_ss(str,replace,with));}
FSTRING_LINK void replace_str(String *str, String replace, char *with){return(replace_str_sc(str,replace,with));}
FSTRING_LINK void replace_str(String *str, char *replace, String with){return(replace_str_cs(str,replace,with));}
FSTRING_LINK void replace_str(String *str, char *replace, char *with){return(replace_str_cc(str,replace,with));}
FSTRING_LINK void to_lower(char *src, char *dst){return(to_lower_cc(src,dst));}
FSTRING_LINK void to_lower(String *dst, String src){return(to_lower_ss(dst,src));}
FSTRING_LINK void to_lower(String *str){return(to_lower_s(str));}
FSTRING_LINK void to_upper(char *src, char *dst){return(to_upper_cc(src,dst));}
FSTRING_LINK void to_upper(String *dst, String src){return(to_upper_ss(dst,src));}
FSTRING_LINK void to_upper(String *str){return(to_upper_s(str));}
FSTRING_LINK void to_camel(char *src, char *dst){return(to_camel_cc(src,dst));}
FSTRING_LINK i32_4tech str_is_int(char *str){return(str_is_int_c(str));}
FSTRING_LINK b32_4tech str_is_int(String str){return(str_is_int_s(str));}
FSTRING_LINK i32_4tech str_to_int(char *str){return(str_to_int_c(str));}
FSTRING_LINK i32_4tech str_to_int(String str){return(str_to_int_s(str));}
FSTRING_LINK i32_4tech reverse_seek_slash(String str, i32_4tech pos){return(reverse_seek_slash_pos(str,pos));}
FSTRING_LINK b32_4tech set_last_folder(String *dir, char *folder_name, char slash){return(set_last_folder_sc(dir,folder_name,slash));}
FSTRING_LINK b32_4tech set_last_folder(String *dir, String folder_name, char slash){return(set_last_folder_ss(dir,folder_name,slash));}
FSTRING_LINK b32_4tech string_set_match(void *str_set, i32_4tech item_size, i32_4tech count, String str, i32_4tech *match_index){return(string_set_match_table(str_set,item_size,count,str,match_index));}
#endif
// BOTTOM

View File

@ -317,16 +317,20 @@ Sys_Save_File_Sig(system_save_file){
HANDLE file = CreateFile_utf8(scratch, (u8*)filename, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (file != INVALID_HANDLE_VALUE){
DWORD written_total = 0;
DWORD written_size = 0;
u64 written_total = 0;
b32 success = true;
for (;written_total < size;){
if (!WriteFile(file, buffer + written_total, size - written_total, &written_size, 0)){
for (;written_total < data.size;){
DWORD read_size = max_u32;
DWORD write_size = 0;
if ((data.size - written_total) < max_u32){
read_size = (DWORD)data.size;
}
if (!WriteFile(file, data.str + written_total, read_size, &write_size, 0)){
success = false;
break;
}
written_total += written_size;
written_total += write_size;
}
if (success){