moved line wrapping rules 100 to buffer datastructures

This commit is contained in:
Allen Webster 2016-09-21 20:01:12 -04:00
parent 69699db27a
commit a5768e457c
10 changed files with 244 additions and 361 deletions

View File

@ -12,6 +12,7 @@
#define BUFFER_REPLACE_RANGE_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *str, int32_t len)
#define BUFFER_COMPUTE_CURSOR_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out)
#define BUFFER_BATCH_EDIT_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type)
#define BUFFER_GET_SETTING_SIG(n) int32_t n(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting)
#define BUFFER_SET_SETTING_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t value)
#define BUFFER_TOKEN_COUNT_SIG(n) int32_t n(Application_Links *app, Buffer_Summary *buffer)
#define BUFFER_READ_TOKENS_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, int32_t start_token, int32_t end_token, Cpp_Token *tokens_out)
@ -74,6 +75,7 @@ typedef BUFFER_READ_RANGE_SIG(Buffer_Read_Range_Function);
typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function);
typedef BUFFER_COMPUTE_CURSOR_SIG(Buffer_Compute_Cursor_Function);
typedef BUFFER_BATCH_EDIT_SIG(Buffer_Batch_Edit_Function);
typedef BUFFER_GET_SETTING_SIG(Buffer_Get_Setting_Function);
typedef BUFFER_SET_SETTING_SIG(Buffer_Set_Setting_Function);
typedef BUFFER_TOKEN_COUNT_SIG(Buffer_Token_Count_Function);
typedef BUFFER_READ_TOKENS_SIG(Buffer_Read_Tokens_Function);
@ -138,6 +140,7 @@ Buffer_Read_Range_Function *buffer_read_range;
Buffer_Replace_Range_Function *buffer_replace_range;
Buffer_Compute_Cursor_Function *buffer_compute_cursor;
Buffer_Batch_Edit_Function *buffer_batch_edit;
Buffer_Get_Setting_Function *buffer_get_setting;
Buffer_Set_Setting_Function *buffer_set_setting;
Buffer_Token_Count_Function *buffer_token_count;
Buffer_Read_Tokens_Function *buffer_read_tokens;
@ -201,6 +204,7 @@ Buffer_Read_Range_Function *buffer_read_range_;
Buffer_Replace_Range_Function *buffer_replace_range_;
Buffer_Compute_Cursor_Function *buffer_compute_cursor_;
Buffer_Batch_Edit_Function *buffer_batch_edit_;
Buffer_Get_Setting_Function *buffer_get_setting_;
Buffer_Set_Setting_Function *buffer_set_setting_;
Buffer_Token_Count_Function *buffer_token_count_;
Buffer_Read_Tokens_Function *buffer_read_tokens_;
@ -272,6 +276,7 @@ app_links->buffer_read_range_ = Buffer_Read_Range;\
app_links->buffer_replace_range_ = Buffer_Replace_Range;\
app_links->buffer_compute_cursor_ = Buffer_Compute_Cursor;\
app_links->buffer_batch_edit_ = Buffer_Batch_Edit;\
app_links->buffer_get_setting_ = Buffer_Get_Setting;\
app_links->buffer_set_setting_ = Buffer_Set_Setting;\
app_links->buffer_token_count_ = Buffer_Token_Count;\
app_links->buffer_read_tokens_ = Buffer_Read_Tokens;\
@ -335,6 +340,7 @@ static inline bool32 buffer_read_range(Application_Links *app, Buffer_Summary *b
static inline bool32 buffer_replace_range(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *str, int32_t len){return(app->buffer_replace_range(app, buffer, start, end, str, len));}
static inline bool32 buffer_compute_cursor(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out){return(app->buffer_compute_cursor(app, buffer, seek, cursor_out));}
static inline bool32 buffer_batch_edit(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type){return(app->buffer_batch_edit(app, buffer, str, str_len, edits, edit_count, type));}
static inline int32_t buffer_get_setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting){return(app->buffer_get_setting(app, buffer, setting));}
static inline bool32 buffer_set_setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t value){return(app->buffer_set_setting(app, buffer, setting, value));}
static inline int32_t buffer_token_count(Application_Links *app, Buffer_Summary *buffer){return(app->buffer_token_count(app, buffer));}
static inline bool32 buffer_read_tokens(Application_Links *app, Buffer_Summary *buffer, int32_t start_token, int32_t end_token, Cpp_Token *tokens_out){return(app->buffer_read_tokens(app, buffer, start_token, end_token, tokens_out));}
@ -398,6 +404,7 @@ static inline bool32 buffer_read_range(Application_Links *app, Buffer_Summary *b
static inline bool32 buffer_replace_range(Application_Links *app, Buffer_Summary *buffer, int32_t start, int32_t end, char *str, int32_t len){return(app->buffer_replace_range_(app, buffer, start, end, str, len));}
static inline bool32 buffer_compute_cursor(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out){return(app->buffer_compute_cursor_(app, buffer, seek, cursor_out));}
static inline bool32 buffer_batch_edit(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type){return(app->buffer_batch_edit_(app, buffer, str, str_len, edits, edit_count, type));}
static inline int32_t buffer_get_setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting){return(app->buffer_get_setting_(app, buffer, setting));}
static inline bool32 buffer_set_setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t value){return(app->buffer_set_setting_(app, buffer, setting, value));}
static inline int32_t buffer_token_count(Application_Links *app, Buffer_Summary *buffer){return(app->buffer_token_count_(app, buffer));}
static inline bool32 buffer_read_tokens(Application_Links *app, Buffer_Summary *buffer, int32_t start_token, int32_t end_token, Cpp_Token *tokens_out){return(app->buffer_read_tokens_(app, buffer, start_token, end_token, tokens_out));}

View File

@ -2657,21 +2657,23 @@ CUSTOM_COMMAND_SIG(toggle_line_wrap){
Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected);
bool32 unwrapped = view.unwrapped_lines;
view_set_setting(app, &view, ViewSetting_WrapLine, unwrapped);
buffer_set_setting(app, &buffer, BufferSetting_WrapLine, unwrapped);
}
CUSTOM_COMMAND_SIG(increase_line_wrap){
View_Summary view = get_active_view(app, AccessProtected);
int32_t wrap = view_get_setting(app, &view, ViewSetting_WrapPosition);
view_set_setting(app, &view, ViewSetting_WrapPosition, wrap + 10);
Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected);
int32_t wrap = buffer_get_setting(app, &buffer, BufferSetting_WrapPosition);
buffer_set_setting(app, &buffer, BufferSetting_WrapPosition, wrap + 10);
}
CUSTOM_COMMAND_SIG(decrease_line_wrap){
View_Summary view = get_active_view(app, AccessProtected);
int32_t wrap = view_get_setting(app, &view, ViewSetting_WrapPosition);
view_set_setting(app, &view, ViewSetting_WrapPosition, wrap - 10);
Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected);
int32_t wrap = buffer_get_setting(app, &buffer, BufferSetting_WrapPosition);
buffer_set_setting(app, &buffer, BufferSetting_WrapPosition, wrap - 10);
}
CUSTOM_COMMAND_SIG(toggle_show_whitespace){

View File

@ -137,6 +137,14 @@ ENUM(int32_t, Buffer_Setting_ID){
being tied to the buffer.) */
BufferSetting_WrapLine,
/* DOC(The BufferSetting_WrapPosition setting determines after how many pixels
a line will wrap. A view set's this value from the global default value
when the view is created. This value cannot be set to less than 48, any value passed
below 48 will cause the position to be set to 48. This is a potentially expensive
operation because the wrap positions of the file have to be reindexed. For
best behavior try to only set this setting once per frame, if possible.) */
BufferSetting_WrapPosition,
/* DOC(The BufferSetting_MapID setting specifies the id of the command map that should be
active when a buffer is active.) */
BufferSetting_MapID,
@ -160,20 +168,6 @@ ENUM(int32_t, View_Setting_ID){
/* DOC(ViewSetting_Null is not a valid setting, it is reserved to detect errors.) */
ViewSetting_Null,
/* DOC(The ViewSetting_WrapLine setting determines whether the view applies line wrapping
at the border of the panel for long lines. Whenever the view switches to a new buffer it
will reset this setting to match the 'preferred' line wrapping setting of the buffer.) */
ViewSetting_WrapLine,
/* DOC(The ViewSetting_WrapPosition setting determines after how many pixels
a line will wrap. A view set's this value from the global default value
when the view is created. The global default can be changed at startup with
a flag (TODO). This value cannot be set to less than 48, any value passed
below 48 will cause the position to be set to 48. This is a potentially expensive
operation because the wrap positions of the file have to be reindexed, for
best behavior try to only set this setting once per frame, if possible.) */
ViewSetting_WrapPosition,
/* DOC(The ViewSetting_ShowWhitespace setting determines whether the view highlights
whitespace in a file. Whenever the view switches to a new buffer this setting is turned off.) */
ViewSetting_ShowWhitespace,

14
4ed.cpp
View File

@ -11,6 +11,8 @@
// App Structs
#define DEFAULT_DISPLAY_WIDTH 672
typedef enum App_State{
APP_STATE_EDIT,
APP_STATE_RESIZING,
@ -396,7 +398,7 @@ COMMAND_DECL(reopen){
view_compute_cursor_from_line_pos(vptrs[i], line, column);
view_set_cursor(vptrs[i], cursor, true,
view->file_data.unwrapped_lines);
file->settings.unwrapped_lines);
}
}
}
@ -470,14 +472,12 @@ COMMAND_DECL(toggle_line_wrap){
// TODO(allen): WHAT TO DO HERE???
Relative_Scrolling scrolling = view_get_relative_scrolling(view);
if (view->file_data.unwrapped_lines){
view->file_data.unwrapped_lines = 0;
if (file->settings.unwrapped_lines){
file->settings.unwrapped_lines = 0;
view->edit_pos->scroll.target_x = 0;
view_cursor_move(view, view->edit_pos->cursor.pos);
}
else{
view->file_data.unwrapped_lines = 1;
file->settings.unwrapped_lines = 1;
view_cursor_move(view, view->edit_pos->cursor.pos);
}
@ -681,7 +681,7 @@ COMMAND_DECL(page_down){
f32 x = view->edit_pos->preferred_x;
Full_Cursor cursor = view_compute_cursor_from_xy(view, x, y+height);
view_set_cursor(view, cursor, false, view->file_data.unwrapped_lines);
view_set_cursor(view, cursor, false, view->file_data.file->settings.unwrapped_lines);
}
COMMAND_DECL(page_up){
@ -694,7 +694,7 @@ COMMAND_DECL(page_up){
f32 x = view->edit_pos->preferred_x;
Full_Cursor cursor = view_compute_cursor_from_xy(view, x, y-height);
view_set_cursor(view, cursor, false, view->file_data.unwrapped_lines);
view_set_cursor(view, cursor, false, view->file_data.file->settings.unwrapped_lines);
}
COMMAND_DECL(open_color_tweaker){
@ -1365,7 +1365,6 @@ App_Init_Sig(app_init){
App_Vars *vars = (App_Vars*)memory->vars_memory;
Models *models = &vars->models;
models->keep_playing = 1;
models->default_display_width = 672;
app_links_init(system, &models->app_links, memory->user_memory, memory->user_memory_size);
@ -1660,6 +1659,7 @@ App_Init_Sig(app_init){
// NOTE(allen): file setup
working_set_init(&models->working_set, partition, &vars->models.mem.general);
models->working_set.default_display_width = DEFAULT_DISPLAY_WIDTH;
// NOTE(allen): clipboard setup
models->working_set.clipboard_max_size = ArrayCount(models->working_set.clipboards);

View File

@ -70,26 +70,27 @@ fill_view_summary(View_Summary *view, View *vptr, Live_Views *live_set, Working_
if (vptr->in_use){
view->exists = 1;
view->view_id = (int32_t)(vptr - live_set->views) + 1;
view->line_height = (float)(vptr->line_height);
view->unwrapped_lines = vptr->file_data.unwrapped_lines;
view->show_whitespace = vptr->file_data.show_whitespace;
view->line_height = (f32)(vptr->line_height);
view->unwrapped_lines = data->file->settings.unwrapped_lines;
view->show_whitespace = data->show_whitespace;
view->lock_flags = view_lock_flags(vptr);
if (data->file){
buffer_id = vptr->file_data.file->id.id;
Assert(data->file);
view->buffer_id = buffer_id;
buffer_id = vptr->file_data.file->id.id;
view->mark = view_compute_cursor_from_pos(vptr, vptr->edit_pos->mark);
view->cursor = vptr->edit_pos->cursor;
view->preferred_x = vptr->edit_pos->preferred_x;
view->buffer_id = buffer_id;
view->file_region = vptr->file_region;
view->scroll_vars = vptr->edit_pos->scroll;
}
view->mark = view_compute_cursor_from_pos(vptr, vptr->edit_pos->mark);
view->cursor = vptr->edit_pos->cursor;
view->preferred_x = vptr->edit_pos->preferred_x;
view->file_region = vptr->file_region;
view->scroll_vars = vptr->edit_pos->scroll;
}
}
inline void
fill_view_summary(View_Summary *view, View *vptr, Command_Data *cmd){
fill_view_summary(view, vptr, &cmd->vars->live_set, &cmd->models->working_set);
@ -701,6 +702,27 @@ DOC_SEE(Buffer_Batch_Edit_Type)
return(result);
}
API_EXPORT int32_t
Buffer_Get_Setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting){
Command_Data *cmd = (Command_Data*)app->cmd_context;
Editing_File *file = imp_get_file(cmd, buffer);
int32_t result = -1;
if (file){
switch (setting){
case BufferSetting_Lex: result = file->settings.tokens_exist; break;
case BufferSetting_WrapLine: result = !file->settings.unwrapped_lines; break;
case BufferSetting_WrapPosition: result = file->settings.display_width; break;
case BufferSetting_MapID: result = file->settings.base_map_id; break;
case BufferSetting_Eol: result = file->settings.dos_write_mode; break;
case BufferSetting_Unimportant: result = file->settings.unimportant; break;
case BufferSetting_ReadOnly: result = file->settings.read_only; break;
}
}
return(result);
}
API_EXPORT bool32
Buffer_Set_Setting(Application_Links *app, Buffer_Summary *buffer, Buffer_Setting_ID setting, int32_t value)
/*
@ -740,6 +762,20 @@ DOC_SEE(Buffer_Setting_ID)
file->settings.unwrapped_lines = !value;
}break;
case BufferSetting_WrapPosition:
{
i32 new_value = value;
if (new_value < 48){
new_value = 48;
}
if (new_value != file->settings.display_width){
i16 font_id = file->settings.font_id;
Render_Font *font = get_font_info(models->font_set, font_id)->font;
file_set_display_width(&models->mem.general, file, new_value,
(f32)font->height, font->advance_data);
}
}break;
case BufferSetting_MapID:
{
if (value == mapid_global){
@ -773,20 +809,20 @@ DOC_SEE(Buffer_Setting_ID)
case BufferSetting_Unimportant:
{
if (value){
file->settings.unimportant = true;
file->settings.unimportant = 1;
}
else{
file->settings.unimportant = false;
file->settings.unimportant = 0;
}
}break;
case BufferSetting_ReadOnly:
{
if (value){
file->settings.read_only = true;
file->settings.read_only = 1;
}
else{
file->settings.read_only = false;
file->settings.read_only = 0;
}
}break;
}
@ -1379,8 +1415,6 @@ View_Get_Setting(Application_Links *app, View_Summary *view, View_Setting_ID set
if (vptr){
switch (setting){
case ViewSetting_WrapLine: result = !vptr->file_data.unwrapped_lines; break;
case ViewSetting_WrapPosition: result = vptr->display_width; break;
case ViewSetting_ShowWhitespace: result = vptr->file_data.show_whitespace; break;
case ViewSetting_ShowScrollbar: result = !vptr->hide_scrollbar; break;
}
@ -1398,45 +1432,12 @@ DOC_RETURN(This call returns non-zero on success.)
DOC_SEE(View_Setting_ID)
*/{
Command_Data *cmd = (Command_Data*)app->cmd_context;
System_Functions *system = cmd->system;
View *vptr = imp_get_view(cmd, view);
bool32 result = false;
if (vptr){
result = true;
switch (setting){
case ViewSetting_WrapLine:
{
Relative_Scrolling scrolling = view_get_relative_scrolling(vptr);
if (value){
if (vptr->file_data.unwrapped_lines){
vptr->file_data.unwrapped_lines = 0;
vptr->edit_pos->scroll.target_x = 0;
view_cursor_move(vptr, vptr->edit_pos->cursor.pos);
view_set_relative_scrolling(vptr, scrolling);
}
}
else{
if (!vptr->file_data.unwrapped_lines){
vptr->file_data.unwrapped_lines = 1;
view_cursor_move(vptr, vptr->edit_pos->cursor.pos);
view_set_relative_scrolling(vptr, scrolling);
}
}
}break;
case ViewSetting_WrapPosition:
{
if (value < 48){
value = 48;
}
if (value != vptr->display_width){
vptr->display_width = value;
remeasure_file_view(system, vptr);
}
}break;
case ViewSetting_ShowWhitespace:
{
vptr->file_data.show_whitespace = value;
@ -1542,14 +1543,14 @@ DOC_SEE(Buffer_Seek)
if (vptr){
file = vptr->file_data.file;
if (file && !file->is_loading){
Assert(file);
if (!file->is_loading){
result = true;
if (seek.type == buffer_seek_line_char && seek.character <= 0){
seek.character = 1;
}
Full_Cursor cursor = view_compute_cursor(vptr, seek);
view_set_cursor(vptr, cursor, set_preferred_x,
vptr->file_data.unwrapped_lines);
view_set_cursor(vptr, cursor, set_preferred_x, file->settings.unwrapped_lines);
fill_view_summary(view, vptr, cmd);
}
}

View File

@ -80,7 +80,6 @@ struct Models{
struct Live_Views *live_set;
Editing_File *message_buffer;
Editing_File *scratch_buffer;
i32 default_display_width;
char hot_dir_base_[256];
Hot_Directory hot_directory;

View File

@ -90,6 +90,7 @@ struct Text_Effect{
// for the initial allocation of the file.
struct Editing_File_Settings{
i32 base_map_id;
i32 display_width;
i32 dos_write_mode;
i16 font_id;
b8 unwrapped_lines;
@ -99,6 +100,7 @@ struct Editing_File_Settings{
b8 read_only;
b8 never_kill;
};
static Editing_File_Settings null_editing_file_settings = {0};
// NOTE(allen): This part of the Editing_File is cleared whenever
// the contents of the file is set.
@ -122,6 +124,7 @@ struct Editing_File_State{
File_Edit_Positions *edit_poss[16];
i32 edit_poss_count;
};
static Editing_File_State null_editing_file_state = {0};
struct Editing_File_Name{
char live_name_[256];
@ -196,6 +199,8 @@ struct Working_Set{
u64 unique_file_counter;
File_Node *sync_check_iter;
i32 default_display_width;
};
//
@ -321,6 +326,88 @@ edit_pos_get_new(Editing_File *file, i32 index){
return(result);
}
//
// Buffer Metadata Measuring
//
internal void
file_measure_starts(System_Functions *system, General_Memory *general, Buffer_Type *buffer){
if (!buffer->line_starts){
i32 max = buffer->line_max = Kbytes(1);
buffer->line_starts = (i32*)general_memory_allocate(general, max*sizeof(i32));
TentativeAssert(buffer->line_starts);
// TODO(allen): when unable to allocate?
}
Buffer_Measure_Starts state = {0};
while (buffer_measure_starts(&state, buffer)){
i32 count = state.count;
i32 max = buffer->line_max;
max = ((max + 1) << 1);
{
i32 *new_lines = (i32*)general_memory_reallocate(
general, buffer->line_starts, sizeof(i32)*count, sizeof(i32)*max);
// TODO(allen): when unable to grow?
TentativeAssert(new_lines);
buffer->line_starts = new_lines;
buffer->line_max = max;
}
}
buffer->line_count = state.count;
}
internal void
file_measure_wraps(General_Memory *general, Editing_File *file, f32 font_height, f32 *adv){
Buffer_Type *buffer = &file->state.buffer;
if (buffer->wraps == 0){
i32 max = ((buffer->line_count+1)*2);
max = (max+(0x1FF))&(~(0x1FF));
buffer->wraps = (f32*)general_memory_allocate(general, max*sizeof(f32));
buffer->wrap_max = max;
}
else if (buffer->wrap_max < buffer->line_count){
i32 old_max = buffer->wrap_max;
i32 max = ((buffer->line_count+1)*2);
max = (max+(0x1FF))&(~(0x1FF));
f32 *new_wraps = (f32*)general_memory_reallocate(
general, buffer->wraps, sizeof(f32)*old_max, sizeof(f32)*max);
TentativeAssert(new_wraps);
buffer->wraps = new_wraps;
buffer->wrap_max = max;
}
buffer_measure_wrap_y(buffer, font_height, adv, (f32)file->settings.display_width);
}
internal void
file_set_display_width(General_Memory *general, Editing_File *file, i32 display_width, f32 font_height, f32 *adv){
file->settings.display_width = display_width;
file_measure_wraps(general, file, font_height, adv);
}
internal i32
file_compute_lowest_line(Editing_File *file, f32 font_height){
i32 lowest_line = 0;
Buffer_Type *buffer = &file->state.buffer;
if (file->settings.unwrapped_lines){
lowest_line = buffer->line_count - 1;
}
else{
f32 term_line_y = buffer->wraps[buffer->line_count];
lowest_line = CEIL32((term_line_y/font_height) - 1);
}
return(lowest_line);
}
//
// Working_Set stuff
//
@ -392,6 +479,7 @@ working_set_alloc(Working_Set *working_set){
result->id = id;
result->unique_buffer_id = ++working_set->unique_file_counter;
dll_insert(&working_set->used_sentinel, node);
result->settings.display_width = working_set->default_display_width;
++working_set->file_count;
}
@ -766,22 +854,10 @@ file_is_ready(Editing_File *file){
return(result);
}
inline Editing_File_State
editing_file_state_zero(){
Editing_File_State state={0};
return(state);
}
inline Editing_File_Settings
editing_file_settings_zero(){
Editing_File_Settings settings={0};
return(settings);
}
inline void
file_set_to_loading(Editing_File *file){
file->state = editing_file_state_zero();
file->settings = editing_file_settings_zero();
file->state = null_editing_file_state;
file->settings = null_editing_file_settings;
file->is_loading = 1;
}

View File

@ -150,12 +150,8 @@ struct File_Viewing_Data{
i32 temp_highlight_end_pos;
b32 show_temp_highlight;
b32 unwrapped_lines;
b32 show_whitespace;
b32 file_locked;
i32 line_count, line_max;
f32 *line_wrap_y;
};
inline File_Viewing_Data
file_viewing_data_zero(){
@ -250,6 +246,9 @@ struct View{
i32 color_cursor;
// misc
// TODO(allen): Can we burn line_height to the ground now?
// It's what I've always wanted!!!! :D
i32 line_height;
// TODO(allen): Do I still use mode?
@ -260,8 +259,6 @@ struct View{
b32 reinit_scrolling;
Debug_Vars debug_vars;
i32 display_width;
};
inline void*
@ -285,7 +282,8 @@ view_width(View *view){
inline f32
view_file_display_width(View *view){
f32 result = (f32)view->display_width;
Editing_File *file = view->file_data.file;
f32 result = (f32)file->settings.display_width;
return(result);
}
@ -322,7 +320,7 @@ view_get_cursor_x(View *view){
if (cursor){
result = cursor->wrapped_x;
if (view->file_data.unwrapped_lines){
if (view->file_data.file->settings.unwrapped_lines){
result = cursor->unwrapped_x;
}
}
@ -344,7 +342,7 @@ view_get_cursor_y(View *view){
if (cursor){
result = cursor->wrapped_y;
if (view->file_data.unwrapped_lines){
if (view->file_data.file->settings.unwrapped_lines){
result = cursor->unwrapped_y;
}
}
@ -429,8 +427,8 @@ view_compute_cursor_from_pos(View *view, i32 pos){
Full_Cursor result = {};
if (font){
f32 max_width = view_file_display_width(view);
result = buffer_cursor_from_pos(&file->state.buffer, pos, view->file_data.line_wrap_y,
max_width, (f32)view->line_height, font->advance_data);
result = buffer_cursor_from_pos(&file->state.buffer, pos, max_width,
(f32)view->line_height, font->advance_data);
}
return result;
}
@ -445,7 +443,7 @@ view_compute_cursor_from_unwrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 ro
if (font){
f32 max_width = view_file_display_width(view);
result = buffer_cursor_from_unwrapped_xy(&file->state.buffer, seek_x, seek_y,
round_down, view->file_data.line_wrap_y, max_width, (f32)view->line_height, font->advance_data);
round_down, max_width, (f32)view->line_height, font->advance_data);
}
return result;
@ -460,8 +458,7 @@ view_compute_cursor_from_wrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 roun
Full_Cursor result = {};
if (font){
f32 max_width = view_file_display_width(view);
result = buffer_cursor_from_wrapped_xy(&file->state.buffer, seek_x, seek_y,
round_down, view->file_data.line_wrap_y,
result = buffer_cursor_from_wrapped_xy(&file->state.buffer, seek_x, seek_y, round_down,
max_width, (f32)view->line_height, font->advance_data);
}
@ -478,7 +475,7 @@ view_compute_cursor_from_line_pos(View *view, i32 line, i32 pos){
if (font){
f32 max_width = view_file_display_width(view);
result = buffer_cursor_from_line_character(&file->state.buffer, line, pos,
view->file_data.line_wrap_y, max_width, (f32)view->line_height, font->advance_data);
max_width, (f32)view->line_height, font->advance_data);
}
return (result);
@ -512,7 +509,7 @@ view_compute_cursor(View *view, Buffer_Seek seek){
inline Full_Cursor
view_compute_cursor_from_xy(View *view, f32 seek_x, f32 seek_y){
Full_Cursor result;
if (view->file_data.unwrapped_lines){
if (view->file_data.file->settings.unwrapped_lines){
result = view_compute_cursor_from_unwrapped_xy(view, seek_x, seek_y);
}
else{
@ -528,27 +525,6 @@ view_wrapped_line_span(f32 line_width, f32 max_width){
return(line_count);
}
internal i32
view_compute_lowest_line(View *view){
i32 lowest_line = 0;
i32 last_line = view->file_data.line_count - 1;
if (last_line > 0){
if (view->file_data.unwrapped_lines){
lowest_line = last_line;
}
else{
// TODO(allen): Actually what I should do to get the "line span"
// is I should store the "final" wrap position. The position the
// next line of the file would have started at, if it had existed.
// Then line_span is just line_span = FLOOR32((wrap_y - wrap_final_y)/view->line_height);
f32 wrap_y = view->file_data.line_wrap_y[last_line];
i32 line_span = 40;
lowest_line = FLOOR32(wrap_y / view->line_height) + line_span - 1;
}
}
return(lowest_line);
}
inline i32
view_compute_max_target_y(i32 lowest_line, i32 line_height, f32 view_height){
f32 max_target_y = ((lowest_line+.5f)*line_height) - view_height*.5f;
@ -558,8 +534,8 @@ view_compute_max_target_y(i32 lowest_line, i32 line_height, f32 view_height){
inline i32
view_compute_max_target_y(View *view){
i32 lowest_line = view_compute_lowest_line(view);
i32 line_height = view->line_height;
i32 lowest_line = file_compute_lowest_line(view->file_data.file, (f32)line_height);
f32 view_height = clamp_bottom((f32)line_height, view_file_height(view));
i32 max_target_y = view_compute_max_target_y(lowest_line, line_height, view_height);
return(max_target_y);
@ -623,7 +599,7 @@ view_move_cursor_to_view(View *view, GUI_Scroll_Vars scroll,
if (view->edit_pos){
i32 line_height = view->line_height;
f32 old_cursor_y = cursor->wrapped_y;
if (view->file_data.unwrapped_lines){
if (view->file_data.file->settings.unwrapped_lines){
old_cursor_y = cursor->unwrapped_y;
}
f32 cursor_y = old_cursor_y;
@ -931,63 +907,6 @@ file_grow_starts_as_needed(General_Memory *general, Buffer_Type *buffer, i32 add
return(result);
}
internal void
file_measure_starts(System_Functions *system, General_Memory *general, Buffer_Type *buffer){
if (!buffer->line_starts){
i32 max = buffer->line_max = Kbytes(1);
buffer->line_starts = (i32*)general_memory_allocate(general, max*sizeof(i32));
TentativeAssert(buffer->line_starts);
// TODO(allen): when unable to allocate?
}
Buffer_Measure_Starts state = {};
while (buffer_measure_starts(&state, buffer)){
i32 count = state.count;
i32 max = buffer->line_max;
max = ((max + 1) << 1);
{
i32 *new_lines = (i32*)general_memory_reallocate(
general, buffer->line_starts, sizeof(i32)*count, sizeof(i32)*max);
// TODO(allen): when unable to grow?
TentativeAssert(new_lines);
buffer->line_starts = new_lines;
buffer->line_max = max;
}
}
buffer->line_count = state.count;
}
internal void
view_measure_wraps(Models *models, General_Memory *general, View *view){
Editing_File *file = view->file_data.file;
Buffer_Type *buffer = &file->state.buffer;
i32 line_count = buffer->line_count;
if (view->file_data.line_max < line_count){
i32 max = view->file_data.line_max = LargeRoundUp(line_count, Kbytes(1));
if (view->file_data.line_wrap_y){
view->file_data.line_wrap_y = (f32*)
general_memory_reallocate_nocopy(general, view->file_data.line_wrap_y, sizeof(f32)*max);
}
else{
view->file_data.line_wrap_y = (f32*)
general_memory_allocate(general, sizeof(f32)*max);
}
}
Render_Font *font = get_font_info(models->font_set, file->settings.font_id)->font;
f32 *adv = font->advance_data;
f32 line_height = (f32)view->line_height;
f32 max_width = view_file_display_width(view);
buffer_measure_wrap_y(buffer, view->file_data.line_wrap_y, line_height,
adv, max_width);
view->file_data.line_count = line_count;
}
internal void
file_create_from_string(System_Functions *system, Models *models,
Editing_File *file, String val, b8 read_only = 0){
@ -997,7 +916,7 @@ file_create_from_string(System_Functions *system, Models *models,
Partition *part = &models->mem.part;
Buffer_Init_Type init;
file->state = editing_file_state_zero();
file->state = null_editing_file_state;
init = buffer_begin_init(&file->state.buffer, val.str, val.size);
for (; buffer_init_need_more(&init); ){
@ -1018,13 +937,13 @@ file_create_from_string(System_Functions *system, Models *models,
}
file_synchronize_times(system, file);
file_measure_starts(system, general, &file->state.buffer);
i16 font_id = models->global_font.font_id;
file->settings.font_id = font_id;
Render_Font *font = get_font_info(font_set, font_id)->font;
float *advance_data = 0;
if (font) advance_data = font->advance_data;
file_measure_starts(system, general, &file->state.buffer);
file_measure_wraps(general, file, (f32)font->height, font->advance_data);
file->settings.read_only = read_only;
if (!read_only){
@ -1654,15 +1573,12 @@ view_set_temp_highlight(View *view, i32 pos, i32 end_pos){
view->file_data.show_temp_highlight = 1;
view_set_cursor(view, view->file_data.temp_highlight,
0, view->file_data.unwrapped_lines);
0, view->file_data.file->settings.unwrapped_lines);
}
// TODO(allen): burn this shit to the ground yo!
inline void
file_view_nullify_file(View *view){
General_Memory *general = &view->persistent.models->mem.general;
if (view->file_data.line_wrap_y){
general_memory_free(general, view->file_data.line_wrap_y);
}
view->file_data = file_viewing_data_zero();
}
@ -1690,15 +1606,9 @@ view_set_file(View *view, Editing_File *file, Models *models){
file_view_nullify_file(view);
view->file_data.file = file;
view->file_data.unwrapped_lines = file->settings.unwrapped_lines;
edit_pos = edit_pos_get_new(file, view->persistent.id);
view->edit_pos = edit_pos;
if (file_is_ready(file)){
view_measure_wraps(models, &models->mem.general, view);
}
update_view_line_height(models, view, file->settings.font_id);
}
@ -1731,8 +1641,8 @@ view_set_relative_scrolling(View *view, Relative_Scrolling scrolling){
inline void
view_cursor_move(View *view, Full_Cursor cursor){
view_set_cursor(view, cursor,
1, view->file_data.unwrapped_lines);
view_set_cursor(view, cursor, 1,
view->file_data.file->settings.unwrapped_lines);
view->file_data.show_temp_highlight = 0;
}
@ -1745,7 +1655,7 @@ view_cursor_move(View *view, i32 pos){
inline void
view_cursor_move(View *view, f32 x, f32 y, b32 round_down = 0){
Full_Cursor cursor;
if (view->file_data.unwrapped_lines){
if (view->file_data.file->settings.unwrapped_lines){
cursor = view_compute_cursor_from_unwrapped_xy(view, x, y, round_down);
}
else{
@ -1968,7 +1878,6 @@ file_edit_cursor_fix(System_Functions *system, Models *models,
Cursor_Fix_Descriptor desc, i32 *shift_out){
Partition *part = &models->mem.part;
General_Memory *general = &models->mem.general;
Temp_Memory cursor_temp = begin_temp_memory(part);
i32 cursor_max = layout->panel_max_count * 2;
@ -1981,8 +1890,6 @@ file_edit_cursor_fix(System_Functions *system, Models *models,
for (dll_items(panel, used_panels)){
view = panel->view;
if (view->file_data.file == file){
// TODO(allen): Is this a good place for this ????
view_measure_wraps(models, general, view);
Assert(view->edit_pos);
write_cursor_with_index(cursors, &cursor_count, view->edit_pos->cursor.pos);
write_cursor_with_index(cursors, &cursor_count, view->edit_pos->mark);
@ -2032,7 +1939,7 @@ file_edit_cursor_fix(System_Functions *system, Models *models,
f32 y_offset = MOD(view->edit_pos->scroll.scroll_y, view->line_height);
f32 y_position = temp_cursor.wrapped_y;
if (view->file_data.unwrapped_lines){
if (view->file_data.file->settings.unwrapped_lines){
y_position = temp_cursor.unwrapped_y;
}
y_position += y_offset;
@ -2043,7 +1950,7 @@ file_edit_cursor_fix(System_Functions *system, Models *models,
}
view_set_cursor_and_scroll(view, new_cursor,
1, view->file_data.unwrapped_lines,
1, view->file_data.file->settings.unwrapped_lines,
scroll);
}
}
@ -2100,16 +2007,8 @@ file_do_single_edit(System_Functions *system,
file_grow_starts_as_needed(general, buffer, line_shift);
buffer_remeasure_starts(buffer, line_start, line_end, line_shift, shift_amount);
// NOTE(allen): update the views looking at this file
Panel *panel, *used_panels;
used_panels = &layout->used_sentinel;
for (dll_items(panel, used_panels)){
View *view = panel->view;
if (view->file_data.file == file){
view_measure_wraps(models, general, view);
}
}
Render_Font *font = get_font_info(models->font_set, file->settings.font_id)->font;
file_measure_wraps(general, file, (f32)font->height, font->advance_data);
// NOTE(allen): cursor fixing
Cursor_Fix_Descriptor desc = {};
@ -2583,34 +2482,17 @@ style_get_color(Style *style, Cpp_Token token){
return result;
}
// TODO(allen): What's the deal with this function? Can we
// just pass models in... by the way is this even being called?
internal void
remeasure_file_view(System_Functions *system, View *view){
if (file_is_ready(view->file_data.file)){
Assert(view->edit_pos);
Relative_Scrolling relative = view_get_relative_scrolling(view);
Models *models = view->persistent.models;
view_measure_wraps(models, &models->mem.general, view);
if (view->file_data.show_temp_highlight == 0){
view_cursor_move(view, view->edit_pos->cursor.pos);
}
view_set_relative_scrolling(view, relative);
}
}
internal void
file_set_font(System_Functions *system, Models *models, Editing_File *file, i16 font_id){
file->settings.font_id = font_id;
Render_Font *font = get_font_info(models->font_set, file->settings.font_id)->font;
file_measure_wraps(&models->mem.general, file, (f32)font->height, font->advance_data);
Editing_Layout *layout = &models->layout;
for (View_Iter iter = file_view_iter_init(layout, file, 0);
file_view_iter_good(iter);
iter = file_view_iter_next(iter)){
update_view_line_height(models, iter.view, font_id);
remeasure_file_view(system, iter.view);
}
}
@ -2701,12 +2583,6 @@ init_normal_file(System_Functions *system, Models *models, Editing_File *file,
if (file->settings.tokens_exist && file->state.token_array.tokens == 0){
file_first_lex_parallel(system, general, file);
}
for (View_Iter iter = file_view_iter_init(&models->layout, file, 0);
file_view_iter_good(iter);
iter = file_view_iter_next(iter)){
view_measure_wraps(models, general, iter.view);
}
}
internal void
@ -2719,12 +2595,6 @@ init_read_only_file(System_Functions *system, Models *models, Editing_File *file
if (file->settings.tokens_exist && file->state.token_array.tokens == 0){
file_first_lex_parallel(system, general, file);
}
for (View_Iter iter = file_view_iter_init(&models->layout, file, 0);
file_view_iter_good(iter);
iter = file_view_iter_next(iter)){
view_measure_wraps(models, general, iter.view);
}
}
@ -4465,12 +4335,8 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
SHOW_GUI_BOOL(2, h_align, "show temp highlight", view_ptr->file_data.show_temp_highlight);
SHOW_GUI_INT (2, h_align, "start temp highlight", view_ptr->file_data.temp_highlight.pos);
SHOW_GUI_INT (2, h_align, "end temp highlight", view_ptr->file_data.temp_highlight_end_pos);
SHOW_GUI_BOOL(2, h_align, "unwrapped lines", view_ptr->file_data.unwrapped_lines);
SHOW_GUI_BOOL(2, h_align, "show whitespace", view_ptr->file_data.show_whitespace);
SHOW_GUI_BOOL(2, h_align, "locked", view_ptr->file_data.file_locked);
SHOW_GUI_INT_INT(2, h_align, "line count",
view_ptr->file_data.line_count,
view_ptr->file_data.line_max);
SHOW_GUI_BLANK(0);
SHOW_GUI_REGION(1, h_align, "scroll region", view_ptr->scroll_region);
@ -4886,7 +4752,6 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target
i32 count = 0;
Full_Cursor render_cursor = {0};
f32 *wraps = view->file_data.line_wrap_y;
f32 scroll_x = view->edit_pos->scroll.scroll_x;
f32 scroll_y = view->edit_pos->scroll.scroll_y;
@ -4896,8 +4761,8 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target
scroll_y += view->widget_height;
{
render_cursor = buffer_get_start_cursor(&file->state.buffer, wraps, scroll_y,
!view->file_data.unwrapped_lines,
render_cursor = buffer_get_start_cursor(&file->state.buffer, scroll_y,
!file->settings.unwrapped_lines,
max_x, advance_data, (f32)line_height);
view->edit_pos->scroll_i = render_cursor.pos;
@ -4905,7 +4770,7 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target
buffer_get_render_data(&file->state.buffer, items, max, &count,
(f32)rect.x0, (f32)rect.y0, clip_w,
scroll_x, scroll_y, max_x, (f32)max_y,
render_cursor, !view->file_data.unwrapped_lines,
render_cursor, !file->settings.unwrapped_lines,
advance_data, (f32)line_height);
}
@ -5548,10 +5413,6 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol
inline void
file_view_free_buffers(View *view){
General_Memory *general = &view->persistent.models->mem.general;
if (view->file_data.line_wrap_y){
general_memory_free(general, view->file_data.line_wrap_y);
view->file_data.line_wrap_y = 0;
}
general_memory_free(general, view->gui_mem);
view->gui_mem = 0;
}
@ -5584,7 +5445,6 @@ live_set_alloc_view(Live_Views *live_set, Panel *panel, Models *models){
result.view->gui_mem = gui_mem;
gui_mem = advance_to_alignment(gui_mem);
result.view->gui_target.push = make_part(gui_mem, gui_mem_size);
result.view->display_width = models->default_display_width;
}
return(result);

View File

@ -178,73 +178,9 @@ buffer_remeasure_starts(Buffer_Type *buffer, i32 line_start, i32 line_end, i32 l
buffer->line_count = line_count;
}
#if 0
internal_4tech void
buffer_remeasure_widths(Buffer_Type *buffer, f32 *advance_data,
i32 line_start, i32 line_end, i32 line_shift){
Buffer_Stringify_Type loop;
i32 *starts = buffer->line_starts;
i32 line_count = buffer->line_count;
i32 widths_count = buffer->widths_count;
char *data = 0;
i32 size = 0, end = 0;
i32 i = 0, j = 0;
f32 width = 0;
char ch = 0;
assert_4tech(0 <= line_start);
assert_4tech(line_start <= line_end);
assert_4tech(line_count <= buffer->widths_max);
++line_end;
if (line_shift != 0){
memmove_4tech(widths + line_end + line_shift, widths + line_end,
sizeof(f32)*(widths_count - line_end));
}
buffer->widths_count = line_count;
line_end += line_shift;
i = line_start;
j = starts[i];
if (line_end == line_count){
size = buffer_size(buffer);
}
else{
size = starts[line_end];
}
width = 0;
for (loop = buffer_stringify_loop(buffer, j, size);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; j < end; ++j){
ch = data[j];
if (ch == '\n'){
widths[i] = width;
++i;
assert_4tech(j + 1 == starts[i]);
width = 0;
}
else{
width += measure_character(advance_data, ch);
}
}
}
if (j == buffer_size(buffer)){
widths[i] = width;
assert_4tech(i+1 == line_count);
}
}
#endif
internal_4tech void
buffer_measure_wrap_y(Buffer_Type *buffer, f32 *wraps,
f32 font_height, f32 *adv, f32 max_width){
buffer_measure_wrap_y(Buffer_Type *buffer, f32 font_height, f32 *adv, f32 max_width){
f32 *wraps = buffer->wraps;
Buffer_Stringify_Type loop = {0};
i32 size = buffer_size(buffer);
char *data = 0;
@ -287,8 +223,9 @@ buffer_measure_wrap_y(Buffer_Type *buffer, f32 *wraps,
}
wraps[wrap_index++] = last_wrap;
wraps[wrap_index++] = current_wrap;
assert_4tech(wrap_index == buffer->line_count);
assert_4tech(wrap_index-1 == buffer->line_count);
}
internal_4tech i32
@ -537,12 +474,13 @@ buffer_partial_from_pos(Buffer_Type *buffer, i32 pos){
}
internal_4tech Full_Cursor
buffer_cursor_from_pos(Buffer_Type *buffer, i32 pos, f32 *wraps,
buffer_cursor_from_pos(Buffer_Type *buffer, i32 pos,
f32 max_width, f32 font_height, f32 *adv){
Full_Cursor result;
i32 line_index;
Full_Cursor result = {0};
i32 line_index = 0;
i32 size = buffer_size(buffer);
f32 *wraps = buffer->wraps;
int32_t size = buffer_size(buffer);
if (pos > size){
pos = size;
}
@ -584,11 +522,12 @@ buffer_partial_from_line_character(Buffer_Type *buffer, i32 line, i32 character)
}
internal_4tech Full_Cursor
buffer_cursor_from_line_character(Buffer_Type *buffer, i32 line, i32 character, f32 *wraps,
buffer_cursor_from_line_character(Buffer_Type *buffer, i32 line, i32 character,
f32 max_width, f32 font_height, f32 *adv){
Full_Cursor result = {0};
i32 line_index = line - 1;
f32 *wraps = buffer->wraps;
if (line_index >= buffer->line_count) line_index = buffer->line_count - 1;
if (line_index < 0) line_index = 0;
@ -600,12 +539,12 @@ buffer_cursor_from_line_character(Buffer_Type *buffer, i32 line, i32 character,
}
internal_4tech Full_Cursor
buffer_cursor_from_unwrapped_xy(Buffer_Type *buffer, f32 x, f32 y, i32 round_down, f32 *wraps,
buffer_cursor_from_unwrapped_xy(Buffer_Type *buffer, f32 x, f32 y, i32 round_down,
f32 max_width, f32 font_height, f32 *adv){
Full_Cursor result;
i32 line_index;
Full_Cursor result = {0};
i32 line_index = (i32)(y / font_height);
f32 *wraps = buffer->wraps;
line_index = (i32)(y / font_height);
if (line_index >= buffer->line_count) line_index = buffer->line_count - 1;
if (line_index < 0) line_index = 0;
@ -617,12 +556,12 @@ buffer_cursor_from_unwrapped_xy(Buffer_Type *buffer, f32 x, f32 y, i32 round_dow
}
internal_4tech Full_Cursor
buffer_cursor_from_wrapped_xy(Buffer_Type *buffer, f32 x, f32 y, i32 round_down, f32 *wraps,
buffer_cursor_from_wrapped_xy(Buffer_Type *buffer, f32 x, f32 y, i32 round_down,
f32 max_width, f32 font_height, f32 *adv){
Full_Cursor result;
i32 line_index;
Full_Cursor result = {0};
f32 *wraps = buffer->wraps;
i32 line_index = buffer_get_line_index_from_wrapped_y(wraps, y, font_height, 0, buffer->line_count);
line_index = buffer_get_line_index_from_wrapped_y(wraps, y, font_height, 0, buffer->line_count);
result = make_cursor_hint(line_index, buffer->line_starts, wraps, font_height);
result = buffer_cursor_seek(buffer, seek_wrapped_xy(x, y, round_down),
max_width, font_height, adv, result);
@ -691,16 +630,16 @@ buffer_invert_batch(Buffer_Invert_Batch *state, Buffer_Type *buffer, Buffer_Edit
}
internal_4tech Full_Cursor
buffer_get_start_cursor(Buffer_Type *buffer, f32 *wraps, f32 scroll_y,
buffer_get_start_cursor(Buffer_Type *buffer, f32 scroll_y,
i32 wrapped, f32 width, f32 *adv, f32 font_height){
Full_Cursor result;
if (wrapped){
result = buffer_cursor_from_wrapped_xy(buffer, 0, scroll_y, 0, wraps,
result = buffer_cursor_from_wrapped_xy(buffer, 0, scroll_y, 0,
width, font_height, adv);
}
else{
result = buffer_cursor_from_unwrapped_xy(buffer, 0, scroll_y, 0, wraps,
result = buffer_cursor_from_unwrapped_xy(buffer, 0, scroll_y, 0,
width, font_height, adv);
}

View File

@ -19,6 +19,9 @@ typedef struct Gap_Buffer{
i32 *line_starts;
i32 line_count;
i32 line_max;
f32 *wraps;
i32 wrap_max;
} Gap_Buffer;
inline_4tech i32
@ -91,6 +94,8 @@ buffer_end_init(Gap_Buffer_Init *init, void *scratch, i32 scratch_size){
buffer->gap_size = buffer->max - size1 - size2;
memmove_4tech(buffer->data + size1 + buffer->gap_size, buffer->data + size1, size2);
buffer->wraps = 0;
result = 1;
}
}