diff --git a/4ed.cpp b/4ed.cpp
index 89b4e5a3..873e8e29 100644
--- a/4ed.cpp
+++ b/4ed.cpp
@@ -229,7 +229,7 @@ COMMAND_DECL(write_character){
 }
 
 COMMAND_DECL(seek_whitespace_right){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
@@ -240,7 +240,7 @@ COMMAND_DECL(seek_whitespace_right){
 }
 
 COMMAND_DECL(seek_whitespace_left){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
@@ -251,7 +251,7 @@ COMMAND_DECL(seek_whitespace_left){
 }
 
 COMMAND_DECL(seek_whitespace_up){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
@@ -262,7 +262,7 @@ COMMAND_DECL(seek_whitespace_up){
 }
 
 COMMAND_DECL(seek_whitespace_down){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
@@ -356,7 +356,7 @@ COMMAND_DECL(seek_white_or_token_left){
 }
 
 COMMAND_DECL(seek_alphanumeric_right){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
@@ -367,7 +367,7 @@ COMMAND_DECL(seek_alphanumeric_right){
 }
 
 COMMAND_DECL(seek_alphanumeric_left){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
@@ -378,7 +378,7 @@ COMMAND_DECL(seek_alphanumeric_left){
 }
 
 COMMAND_DECL(seek_alphanumeric_or_camel_right){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
@@ -390,7 +390,7 @@ COMMAND_DECL(seek_alphanumeric_or_camel_right){
 }
 
 COMMAND_DECL(seek_alphanumeric_or_camel_left){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp
index f8039c96..dd0eb2cd 100644
--- a/4ed_file_view.cpp
+++ b/4ed_file_view.cpp
@@ -1148,7 +1148,7 @@ file_synchronize_times(Editing_File *file, u8 *filename){
 internal b32
 file_save(Partition *part, Editing_File *file, char *filename){
 	b32 result = 0;
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     Temp_Memory temp = begin_temp_memory(part);
     i32 max = partition_remaining(part);
     if (file->dos_write_mode){
@@ -1199,7 +1199,7 @@ enum File_Bubble_Type{
 internal i32
 file_grow_starts_as_needed(General_Memory *general, Buffer_Type *buffer, i32 additional_lines){
     bool32 result = GROW_NOT_NEEDED;
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     i32 max = buffer->line_max;
     i32 count = buffer->line_count;
     i32 target_lines = count + additional_lines;
@@ -1223,7 +1223,7 @@ file_grow_starts_as_needed(General_Memory *general, Buffer_Type *buffer, i32 add
 
 internal void
 file_measure_starts(General_Memory *general, Buffer_Type *buffer){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     ProfileMomentFunction();
     if (!buffer->line_starts){
         i32 max = buffer->line_max = Kbytes(1);
@@ -1256,7 +1256,7 @@ internal void
 file_remeasure_starts(General_Memory *general, Buffer_Type *buffer,
                       i32 line_start, i32 line_end, i32 line_shift,
                       i32 character_shift){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     ProfileMomentFunction();
     Assert(buffer->line_starts);
     file_grow_starts_as_needed(general, buffer, line_shift);
@@ -1279,7 +1279,7 @@ get_opaque_font_advance(Font *font){
 
 internal void
 file_grow_widths_as_needed(General_Memory *general, Buffer_Type *buffer){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     i32 line_count = buffer->line_count;
     if (line_count > buffer->widths_max || buffer->widths_max == 0){
         i32 new_max = LargeRoundUp(line_count, Kbytes(1));
@@ -1300,7 +1300,7 @@ file_grow_widths_as_needed(General_Memory *general, Buffer_Type *buffer){
 
 internal void
 file_measure_widths(General_Memory *general, Buffer_Type *buffer, Font *font){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     ProfileMomentFunction();
     file_grow_widths_as_needed(general, buffer);
     Opaque_Font_Advance opad = get_opaque_font_advance(font);
@@ -1311,7 +1311,7 @@ file_measure_widths(General_Memory *general, Buffer_Type *buffer, Font *font){
 internal void
 file_remeasure_widths(General_Memory *general, Buffer_Type *buffer, Font *font,
                       i32 line_start, i32 line_end, i32 line_shift){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     ProfileMomentFunction();
     file_grow_widths_as_needed(general, buffer);
     Opaque_Font_Advance opad = get_opaque_font_advance(font);
@@ -1329,7 +1329,7 @@ view_wrapped_line_span(real32 line_width, real32 max_width){
 internal i32
 view_compute_lowest_line(File_View *view){
     i32 lowest_line = 0;
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     i32 last_line = view->line_count - 1;
     if (last_line > 0){
         if (view->unwrapped_lines){
@@ -1355,7 +1355,7 @@ view_compute_lowest_line(File_View *view){
 
 internal void
 view_measure_wraps(General_Memory *general, File_View *view){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     ProfileMomentFunction();
     Buffer_Type *buffer;
 
@@ -2019,7 +2019,7 @@ file_post_history(General_Memory *general, Editing_File *file,
 
 inline Full_Cursor
 view_compute_cursor_from_pos(File_View *view, i32 pos){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     Editing_File *file = view->file;
     Style *style = view->style;
     Font *font = style->font;
@@ -2037,7 +2037,7 @@ view_compute_cursor_from_pos(File_View *view, i32 pos){
 inline Full_Cursor
 view_compute_cursor_from_unwrapped_xy(File_View *view, real32 seek_x, real32 seek_y,
                                       bool32 round_down = 0){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     Editing_File *file = view->file;
     Style *style = view->style;
     Font *font = style->font;
@@ -2055,7 +2055,7 @@ view_compute_cursor_from_unwrapped_xy(File_View *view, real32 seek_x, real32 see
 inline Full_Cursor
 view_compute_cursor_from_wrapped_xy(File_View *view, real32 seek_x, real32 seek_y,
                                     bool32 round_down = 0){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     Editing_File *file = view->file;
     Style *style = view->style;
     Font *font = style->font;
@@ -2491,17 +2491,21 @@ file_do_single_edit(Mem_Options *mem, Editing_File *file,
     file_pre_edit_maintenance(file);
 
     // NOTE(allen): actual text replacement
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     i32 shift_amount = 0;
     General_Memory *general = &mem->general;
+    Partition *part = &mem->part;
 
     char *str = (char*)spec.str;
     i32 start = spec.step.edit.start;
     i32 end = spec.step.edit.end;
     i32 str_len = spec.step.edit.len;
 
+    i32 scratch_size = partition_remaining(part);
+    Assert(scratch_size > 0);
     i32 request_amount = 0;
-    while (buffer_replace_range(&file->buffer, start, end, str, str_len, &shift_amount, &request_amount)){
+    while (buffer_replace_range(&file->buffer, start, end, str, str_len, &shift_amount,
+                                part->base + part->pos, scratch_size, &request_amount)){
         void *new_data = 0;
         if (request_amount > 0){
             new_data = general_memory_allocate(general, request_amount, BUBBLE_BUFFER);
@@ -2539,7 +2543,7 @@ file_do_single_edit(Mem_Options *mem, Editing_File *file,
         file_relex_parallel(mem, file, start, end, shift_amount);
 #endif
 
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     Temp_Memory cursor_temp = begin_temp_memory(&mem->part);
     i32 cursor_max = layout->panel_max_count * 2;
     Cursor_With_Index *cursors = push_array(&mem->part, Cursor_With_Index, cursor_max);
@@ -2946,7 +2950,7 @@ working_set_lookup_file(Working_Set *working_set, String string){
 
 internal void
 clipboard_copy(General_Memory *general, Working_Set *working, Range range, Editing_File *file){
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     i32 size = range.end - range.start;
     String *dest = working_set_next_clipboard_string(general, working, size);
     buffer_stringify(&file->buffer, range.start, range.end, dest->str);
@@ -3820,7 +3824,7 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
     bar.rect.y1 = bar.rect.y0 + font->height + 2;
     rect.y0 += font->height + 2;
 
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
     i32 max_x = rect.x1 - rect.x0;
     i32 max_y = rect.y1 - rect.y0 + font->height;
     
@@ -3895,17 +3899,6 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
     i32 prev_ind = -1;
     u32 highlight_color = 0;
     
-    u32 chunk_highlights[] = {
-        0x22FF0000,
-        0x22FFFF00,
-        0x2200FF00,
-        0x2200FFFF,
-        0x220000FF,
-        0x22FF00FF
-    };
-
-    i32 current_chunk = item->chunk_i;
-    u32 chunk_highlight = chunk_highlights[current_chunk % ArrayCount(chunk_highlights)];
     for (i32 i = 0; i < count; ++i, ++item){
         i32 ind = item->index;
         if (tokens_use && ind != prev_ind){
@@ -3930,11 +3923,6 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
         }
         u32 char_color = main_color;
         
-        if (item->chunk_i > current_chunk){
-            current_chunk = item->chunk_i;
-            chunk_highlight = chunk_highlights[current_chunk % ArrayCount(chunk_highlights)];
-        }
-        
         if (cursor_begin <= ind && ind < cursor_end && (ind != prev_ind || cursor_begin < ind)){
             if (is_active) draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), cursor_color);
             else draw_rectangle_outline(target, f32R(item->x0, item->y0, item->x1, item->y1), cursor_color);
@@ -3943,9 +3931,6 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
         else if (highlight_color){
             draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), highlight_color);
         }
-        else if  (chunk_highlight){
-            draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), chunk_highlight);
-        }
         
         u32 fade_color = 0xFFFF00FF;
         f32 fade_amount = 0.f;
@@ -4126,7 +4111,7 @@ HANDLE_COMMAND_SIG(handle_command_file_view){
     
     case FWIDG_SEARCH:
     {
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
         String *string = &file_view->isearch.str;
         Single_Line_Input_Step result =
             app_single_line_input_step(codes, key, string);
diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp
index 2e92ea39..ad987637 100644
--- a/buffer/4coder_buffer_abstract.cpp
+++ b/buffer/4coder_buffer_abstract.cpp
@@ -17,7 +17,7 @@
 #define Buffer_Stringify_Type cat_4tech(Buffer_Type, _Stringify_Loop)
 #define Buffer_Backify_Type cat_4tech(Buffer_Type, _Backify_Loop)
 
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
 inline_4tech void
 buffer_stringify(Buffer_Type *buffer, int start, int end, char *out){
     for (Buffer_Stringify_Type loop = buffer_stringify_loop(buffer, start, end);
@@ -72,7 +72,7 @@ buffer_count_newlines(Buffer_Type *buffer, int start, int end){
 }
 #endif
 
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
 internal_4tech int
 buffer_seek_whitespace_down(Buffer_Type *buffer, int pos){
     Buffer_Stringify_Type loop;
@@ -479,8 +479,8 @@ buffer_rfind_string_end:
 }
 #endif
 
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
-typedef struct{
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
+typedef struct Buffer_Measure_Starts{
     int i;
     int count;
     int start;
@@ -742,8 +742,9 @@ buffer_get_line_index_from_wrapped_y(float *wraps, float y, float font_height, i
 #endif
 
 #ifndef NON_ABSTRACT_4TECH
-typedef struct{
-    Full_Cursor cursor, prev_cursor;
+typedef struct Seek_State{
+    Full_Cursor cursor;
+    Full_Cursor prev_cursor;
 } Seek_State;
 
 internal_4tech int
@@ -854,7 +855,7 @@ cursor_seek_step_end:
 
 #endif
 
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
 internal_4tech Full_Cursor
 buffer_cursor_seek(Buffer_Type *buffer, Buffer_Seek seek, float max_width, float font_height,
                    void *advance_data, int stride, Full_Cursor cursor){
@@ -940,7 +941,7 @@ buffer_cursor_from_wrapped_xy(Buffer_Type *buffer, float x, float y, int round_d
 }
 #endif
 
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
 internal_4tech void
 buffer_invert_edit_shift(Buffer_Type *buffer, Buffer_Edit edit, Buffer_Edit *inverse, char *strings,
                          int *str_pos, int max, int shift_amount){
@@ -965,7 +966,7 @@ buffer_invert_edit(Buffer_Type *buffer, Buffer_Edit edit, Buffer_Edit *inverse,
     buffer_invert_edit_shift(buffer, edit, inverse, strings, str_pos, max, 0);
 }
 
-typedef struct{
+typedef struct Buffer_Invert_Batch{
     int i;
     int shift_amount;
     int len;
@@ -1004,7 +1005,7 @@ buffer_invert_batch(Buffer_Invert_Batch *state, Buffer_Type *buffer, Buffer_Edit
 }
 #endif
 
-#if BUFFER_EXPERIMENT_SCALPEL <= 1
+#if BUFFER_EXPERIMENT_SCALPEL <= 2
 internal_4tech void
 buffer_batch_edit(Buffer_Type *buffer, Buffer_Edit *sorted_edits, char *strings, int edit_count){
     Buffer_Batch_State state;
@@ -1021,7 +1022,7 @@ buffer_batch_edit(Buffer_Type *buffer, Buffer_Edit *sorted_edits, char *strings,
 }
 #endif
 
-#if BUFFER_EXPERIMENT_SCALPEL <= 2
+#if BUFFER_EXPERIMENT_SCALPEL <= 3
 internal_4tech void
 buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *items, int max, int *count,
                        float port_x, float port_y, float scroll_x, float scroll_y, int wrapped,
@@ -1077,9 +1078,6 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
             switch (ch){
             case '\n':
                 write_render_item_inline(item, i, ' ', x, y, advance_data, stride, font_height);
-#if BUFFER_EXPERIMENT_SCALPEL == 2
-                item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
-#endif
                 ++item_i;
                 ++item;
                 
@@ -1089,17 +1087,11 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
 
             case 0:
                 ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
-#if BUFFER_EXPERIMENT_SCALPEL == 2
-                item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
-#endif
                 ++item_i;
                 ++item;
                 x += ch_width;
 
                 ch_width = write_render_item_inline(item, i, '0', x, y, advance_data, stride, font_height);
-#if BUFFER_EXPERIMENT_SCALPEL == 2
-                item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
-#endif
                 ++item_i;
                 ++item;
                 x += ch_width;
@@ -1107,17 +1099,11 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
 
             case '\r':
                 ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
-#if BUFFER_EXPERIMENT_SCALPEL == 2
-                item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
-#endif
                 ++item_i;
                 ++item;
                 x += ch_width;
 
                 ch_width = write_render_item_inline(item, i, 'r', x, y, advance_data, stride, font_height);
-#if BUFFER_EXPERIMENT_SCALPEL == 2
-                item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
-#endif
                 ++item_i;
                 ++item;
                 x += ch_width;
@@ -1125,16 +1111,10 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
 
             case '\t':
                 ch_width_sub = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
-#if BUFFER_EXPERIMENT_SCALPEL == 2
-                item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
-#endif
                 ++item_i;
                 ++item;
 
                 write_render_item_inline(item, i, 't', x + ch_width_sub, y, advance_data, stride, font_height);
-#if BUFFER_EXPERIMENT_SCALPEL == 2
-                item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
-#endif
                 ++item_i;
                 ++item;
                 x += ch_width;
@@ -1142,9 +1122,6 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
 
             default:
                 write_render_item(item, i, ch, x, y, ch_width, font_height);
-#if BUFFER_EXPERIMENT_SCALPEL == 2
-                item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
-#endif
                 ++item_i;
                 ++item;
                 x += ch_width;
@@ -1160,9 +1137,6 @@ buffer_get_render_data_end:
         ch = 0;
         ch_width = measure_character(advance_data, stride, ' ');
         write_render_item(item, size, ch, x, y, ch_width, font_height);
-#if BUFFER_EXPERIMENT_SCALPEL == 2
-        item->chunk_i = -1;
-#endif
         ++item_i;
         ++item;
         x += ch_width;
diff --git a/buffer/4coder_gap_buffer.cpp b/buffer/4coder_gap_buffer.cpp
index 2c2da69f..be68b191 100644
--- a/buffer/4coder_gap_buffer.cpp
+++ b/buffer/4coder_gap_buffer.cpp
@@ -13,7 +13,7 @@
 
 // TOP
 
-typedef struct{
+typedef struct Gap_Buffer{
     char *data;
     int size1, gap_size, size2, max;
     
@@ -39,7 +39,7 @@ buffer_size(Gap_Buffer *buffer){
     return(size);
 }
 
-typedef struct{
+typedef struct Gap_Buffer_Init{
     Gap_Buffer *buffer;
     char *data;
     int size;
@@ -110,7 +110,7 @@ buffer_end_init(Gap_Buffer_Init *init, void *scratch, int scratch_size){
     return(result);
 }
 
-typedef struct{
+typedef struct Gap_Buffer_Stringify_Loop{
     Gap_Buffer *buffer;
     char *data, *base;
     int absolute_pos;
@@ -172,7 +172,7 @@ buffer_stringify_next(Gap_Buffer_Stringify_Loop *loop){
     loop->data = loop->base + loop->pos;
 }
 
-typedef struct{
+typedef struct Gap_Buffer_Backify_Loop{
     Gap_Buffer *buffer;
     char *data, *base;
     int pos, end;
diff --git a/buffer/4coder_golden_array.cpp b/buffer/4coder_golden_array.cpp
index 645a4a5b..a656a498 100644
--- a/buffer/4coder_golden_array.cpp
+++ b/buffer/4coder_golden_array.cpp
@@ -13,7 +13,7 @@
 
 // TOP
 
-typedef struct{
+typedef struct Buffer{
     char *data;
     int size, max;
     
@@ -37,7 +37,7 @@ buffer_size(Buffer *buffer){
     return buffer->size;
 }
 
-typedef struct{
+typedef struct Buffer_Init{
     Buffer *buffer;
     char *data;
     int size;
@@ -92,7 +92,7 @@ buffer_end_init(Buffer_Init *init, void *scratch, int scratch_size){
     return(result);
 }
 
-typedef struct{
+typedef struct Buffer_Stringify_Loop{
     Buffer *buffer;
     char *data, *end;
     int absolute_pos;
@@ -125,7 +125,7 @@ buffer_stringify_next(Buffer_Stringify_Loop *loop){
     loop->buffer = 0;
 }
 
-typedef struct{
+typedef struct Buffer_Backify_Loop{
     Buffer *buffer;
     char *data, *end;
     int absolute_pos;
diff --git a/buffer/4coder_multi_gap_buffer.cpp b/buffer/4coder_multi_gap_buffer.cpp
index 225f2c61..de35dbc2 100644
--- a/buffer/4coder_multi_gap_buffer.cpp
+++ b/buffer/4coder_multi_gap_buffer.cpp
@@ -16,7 +16,7 @@
 
 // TOP
 
-typedef struct{
+typedef struct Fixed_Width_Gap_Buffer{
     char *data;
     int size1, gap_size, size2;
     int start_pos;
@@ -25,7 +25,7 @@ typedef struct{
 #define fixed_width_buffer_size Kbytes(8)
 #define fixed_width_buffer_half_size Kbytes(4)
 
-typedef struct{
+typedef struct Multi_Gap_Buffer{
     Fixed_Width_Gap_Buffer *gaps;
     int chunk_count;
     int chunk_alloced;
@@ -57,7 +57,7 @@ buffer_size(Multi_Gap_Buffer *buffer){
     return(size);
 }
 
-typedef struct{
+typedef struct Multi_Gap_Buffer_Init{
     Multi_Gap_Buffer *buffer;
     char *data;
     int size;
@@ -202,7 +202,7 @@ buffer_find_chunk(Multi_Gap_Buffer *buffer, int pos){
     return(m);
 }
 
-typedef struct{
+typedef struct Multi_Gap_Buffer_Stringify_Loop{
     Multi_Gap_Buffer *buffer;
     Fixed_Width_Gap_Buffer *gaps;
     char *data;
@@ -290,7 +290,7 @@ buffer_stringify_next(Multi_Gap_Buffer_Stringify_Loop *loop){
     }
 }
 
-typedef struct{
+typedef struct Multi_Gap_Buffer_Backify_Loop{
     Multi_Gap_Buffer *buffer;
     Fixed_Width_Gap_Buffer *gaps;
     char *data;
diff --git a/buffer/4coder_rope_buffer.cpp b/buffer/4coder_rope_buffer.cpp
index 2729c8a3..2ae09aa6 100644
--- a/buffer/4coder_rope_buffer.cpp
+++ b/buffer/4coder_rope_buffer.cpp
@@ -15,7 +15,7 @@
 
 typedef struct Rope_Node{
     int left, right, parent;
-    int left_total, total;
+    int left_weight, weight;
     int str_start;
 } Rope_Node;
 
@@ -26,6 +26,10 @@ typedef struct Rope_String{
 #define rope_string_full_size 256
 #define rope_string_width (rope_string_full_size-sizeof(Rope_String))
 
+typedef struct Rope_Buffer_Edit_State{
+    int left, right, throw_away, middle;
+} Rope_Buffer_Edit_State;
+
 typedef struct Rope_Buffer{
     void *data;
     int free_rope_string;
@@ -41,6 +45,10 @@ typedef struct Rope_Buffer{
     int widths_count;
     int line_max;
     int widths_max;
+    
+    int grow_string_memory;
+    int edit_stage;
+    Rope_Buffer_Edit_State edit_state;
 } Rope_Buffer;
 
 inline_4tech int
@@ -53,7 +61,7 @@ buffer_good(Rope_Buffer *buffer){
 inline_4tech int
 buffer_size(Rope_Buffer *buffer){
     int size;
-    size = buffer->nodes->left_total;
+    size = buffer->nodes->left_weight;
     return(size);
 }
 
@@ -195,26 +203,106 @@ buffer_construct_stage(int parent, int right, int weight){
 }
 
 internal_4tech int
-buffer_end_init(Rope_Buffer_Init *init, void *scratch, int scratch_size){
+buffer_build_tree(Rope_Buffer *buffer, char *str, int len, int root,
+                  void *scratch, int scratch_size, int *request_amount){
     Rope_Construct_Stage *stack, *stage;
+    Rope_Node *node, *nodes;
+    char *dest;
+    int stack_max, top;
+    int result;
+    int node_index;
+    int is_right_side;
+    int read_pos;
+
+    nodes = buffer->nodes;
+    stack = (Rope_Construct_Stage*)scratch;
+    stack_max = scratch_size / sizeof(Rope_Construct_Stage);
+    top = 0;
+    result = 1;
+    read_pos = 0;
+    
+    stack[top++] = buffer_construct_stage(root, 0, len);
+    for (;top > 0;){
+        stage = stack + (--top);
+        
+        if (buffer_alloc_rope_node(buffer, &node_index)){
+            node = nodes + node_index;
+            node->parent = stage->parent_index;
+            node->weight = stage->weight;
+            node->left = 0;
+            node->right = 0;
+            is_right_side = stage->is_right_side;
+            
+            if (stage->weight > rope_string_width){
+                node->str_start = 0;
+                node->left_weight = stage->weight / 2;
+                assert_4tech(top < stack_max);
+                stack[top++] = buffer_construct_stage(node_index, 1, node->weight - node->left_weight);
+                assert_4tech(top < stack_max);
+                stack[top++] = buffer_construct_stage(node_index, 0, node->left_weight);
+            }
+            else{
+                node->left_weight = 0;
+                if (buffer_alloc_rope_string(buffer, &node->str_start)){
+                    dest = (char*)buffer->data + node->str_start;
+                    assert_4tech(read_pos < len);
+                    memcpy_4tech(dest, str + read_pos, node->weight);
+                    read_pos += node->weight;
+                }
+                else{
+                    result = 0;
+                    if (request_amount){
+                        buffer->grow_string_memory = 1;
+                        *request_amount = buffer->string_count*rope_string_full_size*2;
+                    }
+                    break;
+                }
+            }
+            
+            node = nodes + node->parent;
+            if (is_right_side) node->right = node_index;
+            else node->left = node_index;
+        }
+        else{
+            result = 0;
+            if (request_amount){
+                buffer->grow_string_memory = 0;
+                *request_amount = buffer->node_count*sizeof(Rope_Node)*2;
+            }
+            break;
+        }
+    }
+    
+    if (!result && request_amount){
+        top = 0;
+        stack[top++] = buffer_construct_stage(nodes[root].left, 0, 0);
+        
+        for (;top > 0;){
+            stage = stack + (--top);
+            node_index = stage->parent_index;
+            node = nodes + node_index;
+            if (node->left) stack[top++] = buffer_construct_stage(node->left, 0, 0);
+            if (node->right) stack[top++] = buffer_construct_stage(node->right, 0, 0);
+            if (node->str_start) buffer_free_rope_string(buffer, node->str_start);
+            buffer_free_rope_node(buffer, node_index);
+        }
+    }
+    
+    return(result);
+}
+
+internal_4tech int
+buffer_end_init(Rope_Buffer_Init *init, void *scratch, int scratch_size){
     Rope_Buffer *buffer;
     Rope_String *rope_string;
     Rope_Node *node;
-    char *src, *dest;
-    int node_index;
-    int i, top, stack_max, is_right_side;
-    int read_pos, read_end;
+    int i;
     int result;
     int count;
     
-    src = init->data;
-    read_pos = 0;
-    read_end = init->size;
-    
     result = 0;
     buffer = init->buffer;
     if (buffer->nodes && buffer->data){
-        // NOTE(allen): initialize free lists
         buffer->string_count = init->rope_string_count;
         buffer->free_rope_string = 0;
         
@@ -231,66 +319,550 @@ buffer_end_init(Rope_Buffer_Init *init, void *scratch, int scratch_size){
         
         node = buffer->nodes + 1;
         count = init->node_count;
-        for (i = 1; i < count; ++i, ++node){
+        for (i = 1; i < count-1; ++i, ++node){
             node->parent = i+1;
         }
         node->parent = 0;
         
         result = 1;
         
-        // NOTE(allen): initialize tree
         node = buffer->nodes;
         node->parent = 0;
-        node->total = init->size;
-        node->left_total = init->size;
+        node->weight = init->size;
+        node->left_weight = init->size;
+
+        result = buffer_build_tree(buffer, init->data, init->size, 0, scratch, scratch_size, 0);
+    }
+    
+    return(result);
+}
+
+internal_4tech int
+buffer_find_node(Rope_Buffer *buffer, int pos, int *node_start){
+    Rope_Node *nodes, *node;
+    *node_start = 0;
+    nodes = buffer->nodes;
+    node = nodes + nodes->left;
+    for (;node->str_start == 0;){
+        if (pos < node->left_weight){
+            node = nodes + node->left;
+        }
+        else{
+            *node_start += node->left_weight;
+            pos -= node->left_weight;
+            node = nodes + node->right;
+        }
+    }
+    return (int)(node - nodes);
+}
+
+typedef struct Rope_Buffer_Stringify_Loop{
+    Rope_Buffer *buffer;
+    char *data;
+    int absolute_pos;
+    int size;
+    int pos, end_pos;
+    int node, node_end;
+} Rope_Buffer_Stringify_Loop;
+
+internal_4tech Rope_Buffer_Stringify_Loop
+buffer_stringify_loop(Rope_Buffer *buffer, int start, int end){
+    Rope_Buffer_Stringify_Loop result;
+    Rope_Node *node;
+    int size, node_start_pos, temp_end;
+
+    size = buffer_size(buffer);
+    if (0 <= start && start < end && end <= size){
+        result.buffer = buffer;
+        result.absolute_pos = start;
         
-        stack = (Rope_Construct_Stage*)scratch;
-        stack_max = scratch_size / sizeof(Rope_Construct_Stage);
-        top = 0;
+        result.node = buffer_find_node(buffer, start, &node_start_pos);
+        result.pos = start - node_start_pos;
         
-        stack[top++] = buffer_construct_stage(0, 0, init->size);
-        for (;top > 0;){
-            stage = stack + (--top);
-            
-            if (buffer_alloc_rope_node(buffer, &node_index)){
-                node = buffer->nodes + node_index;
-                node->parent = stage->parent_index;
-                node->total = stage->weight;
-                is_right_side = stage->is_right_side;
-                if (stage->weight > rope_string_width){
-                    node->left_total = stage->weight / 2;
-                    assert_4tech(top < stack_max);
-                    stack[top++] = buffer_construct_stage(node_index, 1, node->total - node->left_total);
-                    assert_4tech(top < stack_max);
-                    stack[top++] = buffer_construct_stage(node_index, 0, node->left_total);
-                }
-                else{
-                    node->left_total = 0;
-                    node->left = 0;
-                    node->right = 0;
-                    if (buffer_alloc_rope_string(buffer, &node->str_start)){
-                        dest = (char*)buffer->data + node->str_start;
-                        assert_4tech(read_pos < read_end);
-                        memcpy_4tech(dest, src + read_pos, node->total);
-                        read_pos += node->total;
-                    }
-                    else{
-                        result = 0;
-                        break;
-                    }
-                }
-                node = buffer->nodes + node->parent;
-                if (is_right_side) node->right = node_index;
-                else node->left = node_index;
-            }
-            else{
-                result = 0;
+        result.node_end = buffer_find_node(buffer, end, &node_start_pos);
+        result.end_pos = end - node_start_pos;
+
+        node = buffer->nodes + result.node;
+        temp_end = node->weight;
+        if (result.node == result.node_end) temp_end = result.end_pos;
+        
+        result.data = (char*)buffer->data + node->str_start + result.pos;
+        result.size = temp_end - result.pos;
+    }
+    else result.buffer = 0;
+    return(result);
+}
+
+inline_4tech int
+buffer_stringify_good(Rope_Buffer_Stringify_Loop *loop){
+    int result;
+    result = (loop->buffer != 0);
+    return(result);
+}
+
+internal_4tech void
+buffer_stringify_next(Rope_Buffer_Stringify_Loop *loop){
+    Rope_Node *node, *child, *nodes;
+    int temp_end;
+    
+    if (loop->node == loop->node_end && loop->pos + loop->size == loop->end_pos){
+        loop->buffer = 0;
+    }
+    else{
+        nodes = loop->buffer->nodes;
+        node = nodes + loop->node;
+        
+        for (;;){
+            assert_4tech(node->parent != 0);
+            child = node;
+            node = nodes + node->parent;
+            if (nodes + node->left == child){
                 break;
             }
+            else{
+                assert_4tech(nodes + node->right == child);
+            }
+        }
+        
+        node = nodes + node->right;
+        
+        for (;node->left;){
+            node = nodes + node->left;
+        }
+
+        loop->pos = 0;
+        loop->node = (int)(node - nodes);
+        loop->absolute_pos += loop->size;
+        temp_end = node->weight;
+        if (loop->node == loop->node_end) temp_end = loop->end_pos;
+        loop->size = temp_end;
+        loop->data = (char*)loop->buffer->data + node->str_start;
+    }
+}
+
+typedef struct Rope_Buffer_Backify_Loop{
+    Rope_Buffer *buffer;
+    char *data;
+    int absolute_pos;
+    int size;
+    int pos, end_pos;
+    int node, node_end;
+} Rope_Buffer_Backify_Loop;
+
+internal_4tech Rope_Buffer_Backify_Loop
+buffer_backify_loop(Rope_Buffer *buffer, int start, int end){
+    Rope_Buffer_Backify_Loop result;
+    int size, node_start_pos, temp_end;
+
+    size = buffer_size(buffer);
+    ++start;
+    if (0 <= end && end < start && start <= size){
+        result.buffer = buffer;
+        
+        result.node_end = buffer_find_node(buffer, end, &node_start_pos);
+        result.end_pos = end - node_start_pos;
+        
+        result.node = buffer_find_node(buffer, start, &node_start_pos);
+        temp_end = start - node_start_pos;
+        
+        if (result.node_end == result.node){
+            result.pos = result.end_pos;
+            result.absolute_pos = end;
+        }
+        else{
+            result.pos = 0;
+            result.absolute_pos = node_start_pos;
+        }
+        
+        result.size = temp_end - result.pos;
+        result.data = (char*)buffer->data + buffer->nodes[result.node].str_start + result.pos;
+    }
+    else result.buffer = 0;
+    return(result);
+}
+
+inline_4tech int
+buffer_backify_good(Rope_Buffer_Backify_Loop *loop){
+    int result;
+    result = (loop->buffer != 0);
+    return(result);
+}
+
+internal_4tech void
+buffer_backify_next(Rope_Buffer_Backify_Loop *loop){
+    Rope_Node *node, *child, *nodes;
+    int temp_start;
+    
+    if (loop->node == loop->node_end && loop->pos == loop->end_pos){
+        loop->buffer = 0;
+    }
+    else{
+        nodes = loop->buffer->nodes;
+        node = nodes + loop->node;
+        
+        for (;;){
+            assert_4tech(node->parent != 0);
+            child = node;
+            node = nodes + node->parent;
+            if (nodes + node->right == child){
+                break;
+            }
+            else{
+                assert_4tech(nodes + node->left == child);
+            }
+        }
+        
+        node = nodes + node->left;
+        
+        for (;node->right;){
+            node = nodes + node->right;
+        }
+
+        loop->pos = 0;
+        loop->node = (int)(node - nodes);
+        loop->absolute_pos -= node->weight;
+        temp_start = 0;
+        if (loop->node == loop->node_end) temp_start = loop->end_pos;
+        loop->size = node->weight - temp_start;
+        loop->data = (char*)loop->buffer->data + node->str_start;
+    }
+}
+
+internal_4tech int
+buffer_concat(Rope_Buffer *buffer, int node_a, int node_b, int *root, int *request_amount){
+    Rope_Node *r, *a, *b, *nodes;
+    int result;
+    
+    result = 0;
+    if (buffer_alloc_rope_node(buffer, root)){
+        nodes = buffer->nodes;
+        
+        r = nodes + *root;
+        a = nodes + node_a;
+        b = nodes + node_b;
+        
+        r->left = node_a;
+        r->right = node_b;
+        r->weight = a->weight + b->weight;
+        r->left_weight = a->weight;
+        r->str_start = 0;
+        r->parent = 0;
+        
+        a->parent = *root;
+        b->parent = *root;
+    }
+    else{
+        result = 1;
+        buffer->grow_string_memory = 0;
+        *request_amount = buffer->node_count*sizeof(Rope_Node)*2;
+    }
+    
+    return(result);
+}
+
+internal_4tech int
+buffer_string_split(Rope_Buffer *buffer, int *node_index, int pos, int *request_amount){
+    Rope_Node *node, *a, *b;
+    int node_a, node_b;
+    int new_string_start, string_start;
+    int result;
+    result = 0;
+
+    if (pos > 0){
+        if (buffer_alloc_rope_string(buffer, &new_string_start)){
+            if (buffer_alloc_rope_node(buffer, &node_a)){
+                if (buffer_alloc_rope_node(buffer, &node_b)){
+                    node = buffer->nodes + *node_index;
+                    string_start = node->str_start;
+                    memcpy_4tech((char*)buffer->data + new_string_start, (char*)buffer->data + string_start + pos, node->weight - pos);
+                    node->str_start = 0;
+                    node->left_weight = pos;
+                    node->left = node_a;
+                    node->right = node_b;
+                    
+                    a = buffer->nodes + node_a;
+                    b = buffer->nodes + node_b;
+                    
+                    a->parent = *node_index;
+                    a->left = 0;
+                    a->right = 0;
+                    a->left_weight = 0;
+                    a->weight = pos;
+                    a->str_start = string_start;
+                    
+                    b->parent = *node_index;;
+                    b->left = 0;
+                    b->right = 0;
+                    b->left_weight = 0;
+                    b->weight = node->weight - pos;
+                    b->str_start = new_string_start;
+                    
+                    *node_index = node_b;
+                }
+                else{
+                    buffer_free_rope_string(buffer, new_string_start);
+                    buffer_free_rope_node(buffer, node_a);
+                    result = 1;
+                    buffer->grow_string_memory = 0;
+                    *request_amount = buffer->node_count*sizeof(Rope_Node)*2;                    
+                }
+            }
+            else{
+                buffer_free_rope_string(buffer, new_string_start);
+                result = 1;
+                buffer->grow_string_memory = 0;
+                *request_amount = buffer->node_count*sizeof(Rope_Node)*2;                
+            }
+        }
+        else{
+            result = 1;
+            buffer->grow_string_memory = 1;
+            *request_amount = buffer->string_count*rope_string_full_size*2;
         }
     }
     
-    assert_4tech(!result || read_pos == read_end);
+    return(result);
+}
+
+internal_4tech void
+buffer_reduce_node(Rope_Buffer *buffer, int node_index){
+    Rope_Node *parent, *child, *node, *nodes;
+    int child_index;
+    
+    nodes = buffer->nodes;
+    node = nodes + node_index;
+    parent = nodes + node->parent;
+    child_index = node->left;
+    if (child_index == 0) child_index = node->right;
+    assert_4tech(child_index != 0);
+    child = nodes + child_index;
+    
+    if (parent->left == node_index) parent->left = child_index;
+    else parent->right = child_index;
+    child->parent = node->parent;
+    
+    for (;parent != nodes;){
+        parent->weight = nodes[parent->left].weight + nodes[parent->right].weight;
+        parent->left_weight = nodes[parent->left].weight;
+        parent = nodes + parent->parent;
+    }
+    
+    parent->weight = parent->left_weight = nodes[parent->left].weight;
+    
+    buffer_free_rope_node(buffer, node_index);
+}
+
+internal_4tech int
+buffer_split(Rope_Buffer *buffer, int pos, int *node_a, int *node_b, int *request_amount){
+    Rope_Node *node, *nodes, *child;
+    int node_index, node_start_pos, split_root;
+    int result;
+    debug_4tech(int dbg_check);
+
+    result = 0;
+    node_index = buffer_find_node(buffer, pos, &node_start_pos);
+    
+    if (node_start_pos < pos){
+        if (buffer_string_split(buffer, &node_index, pos - node_start_pos, request_amount)){
+            result = 1;
+            goto buffer_split_end;
+        }
+    }
+    
+    split_root = 0;
+    nodes = buffer->nodes;
+    node = nodes + node_index;
+    for (;;){
+        child = node;
+        node = nodes + node->parent;
+        if (child == nodes + node->right){
+            break;
+        }
+        else{
+            assert_4tech(child == nodes + node->left);
+        }
+    }
+    
+    for (;;){
+        if (split_root == 0){
+            split_root = node->right;
+        }
+        else{
+            debug_4tech(dbg_check =)
+                buffer_concat(buffer, split_root, node->right, &split_root, request_amount);
+            assert_4tech(!dbg_check);
+        }
+        
+        node_index = (int)(node - nodes);
+        node->right = 0;
+        node = nodes + node->left;
+        buffer_reduce_node(buffer, node_index);
+
+        for (;;){
+            child = node;
+            node = nodes + child->parent;
+            if (nodes + node->left == child){
+                break;
+            }
+            else{
+                assert_4tech(nodes + node->right == child);
+            }
+        }
+        
+        if (node == nodes) break;
+    }
+    
+    *node_a = nodes->left;
+    *node_b = split_root;
+    
+buffer_split_end:
+    return(result);
+}
+
+internal_4tech int
+buffer_build_tree_floating(Rope_Buffer *buffer, char *str, int len, int *out,
+                           void *scratch, int scratch_size, int *request_amount){
+    int result;
+    int super_root;
+
+    result = 0;
+    if (buffer_alloc_rope_node(buffer, &super_root)){
+        if (buffer_build_tree(buffer, str, len, super_root, scratch, scratch_size, request_amount)){
+            *out = buffer->nodes[super_root].left;
+            buffer_free_rope_node(buffer, super_root);
+        }
+        else{
+            result = 1;
+            buffer_free_rope_node(buffer, super_root);
+        }
+    }
+    else{
+        result = 1;
+        buffer->grow_string_memory = 0;
+        *request_amount = buffer->node_count*sizeof(Rope_Node)*2;
+    }
+    
+    return(result);
+}
+
+internal_4tech int
+buffer_replace_range(Rope_Buffer *buffer, int start, int end, char *str, int len, int *shift_amount,
+                     void *scratch, int scratch_size, int *request_amount){
+    Rope_Node *nodes;
+    Rope_Buffer_Edit_State state;
+    int result;
+
+    state = buffer->edit_state;
+    
+    *shift_amount = (len - (end - start));
+    result = 0;
+    
+    for (; buffer->edit_stage < 6; ++buffer->edit_stage){
+        switch (buffer->edit_stage){
+        case 0:
+            if (buffer_split(buffer, end, &state.throw_away, &state.right, request_amount)){
+                result = 1;
+                goto rope_buffer_replace_range_end;
+            } break;
+            
+        case 1:
+            if (start == end){
+                state.left = state.throw_away;
+            }
+            else{
+                if (buffer_split(buffer, start, &state.left, &state.throw_away, request_amount)){
+                    result = 1;
+                    goto rope_buffer_replace_range_end;
+                }
+            }
+            if (len == 0){
+                buffer->edit_stage = 5 - 1;
+            }
+            break;
+            
+        case 2:
+            if (buffer_build_tree_floating(buffer, str, len, &state.middle, scratch, scratch_size, request_amount)){
+                result = 1;
+                goto rope_buffer_replace_range_end;
+            } break;
+            
+        case 3:
+            if (buffer_concat(buffer, state.left, state.middle, &state.throw_away, request_amount)){
+                result = 1;
+                goto rope_buffer_replace_range_end;
+            } break;
+            
+        case 4:
+            if (buffer_concat(buffer, state.throw_away, state.right, &state.middle, request_amount)){
+                result = 1;
+                goto rope_buffer_replace_range_end;
+            }
+            buffer->edit_stage = 6;
+            break;
+            
+        case 5:                
+            if (buffer_concat(buffer, state.left, state.right, &state.middle, request_amount)){
+                result = 1;
+                goto rope_buffer_replace_range_end;
+            } break;
+        }
+    }
+
+    buffer->edit_stage = 0;
+    nodes = buffer->nodes;
+    nodes->left = state.middle;
+    nodes->weight = nodes->left_weight = nodes[state.middle].weight;
+    
+    state = {};
+    
+rope_buffer_replace_range_end:
+    buffer->edit_state = state;
+    
+    return(result);
+}
+
+internal_4tech void*
+buffer_edit_provide_memory(Rope_Buffer *buffer, void *new_data, int size){
+    void *result;
+    Rope_String *rope_string;
+    Rope_Node *node;
+    int start, end, i;
+    
+    if (buffer->grow_string_memory){
+        assert_4tech(size >= buffer->string_count * rope_string_full_size);
+        result = buffer->data;
+        memcpy_4tech(new_data, buffer->data, buffer->string_count * rope_string_full_size);
+
+        buffer->data = new_data;
+        start = buffer->string_count*rope_string_full_size;
+        end = size/rope_string_full_size;
+        buffer->string_count = end;
+        end = (end-1)*rope_string_full_size;
+        for (i = start; i < end; i += rope_string_full_size){
+            rope_string = (Rope_String*)((char*)new_data + i);
+            rope_string->next_free = i + rope_string_full_size;
+        }
+        rope_string = (Rope_String*)((char*)new_data + i);
+        rope_string->next_free = buffer->free_rope_string;
+        buffer->free_rope_string = start;
+    }
+    else{
+        assert_4tech(size >= buffer->node_count * sizeof(Rope_Node));
+        result = buffer->nodes;
+        memcpy_4tech(new_data, buffer->nodes, buffer->node_count * sizeof(Rope_Node));
+        
+        buffer->nodes = (Rope_Node*)new_data;
+        start = buffer->node_count;
+        end = size/sizeof(Rope_Node);
+        buffer->node_count = end;
+        end -= 1;
+        node = buffer->nodes + start;
+        for (i = start; i < end; ++i, ++node){
+            node->parent = i+1;
+        }
+        node->parent = buffer->free_rope_node;
+        buffer->free_rope_node = start;
+    }
     
     return(result);
 }
diff --git a/buffer/4coder_shared.cpp b/buffer/4coder_shared.cpp
index 8605b17a..e4fca991 100644
--- a/buffer/4coder_shared.cpp
+++ b/buffer/4coder_shared.cpp
@@ -86,12 +86,12 @@ measure_character(void *advance_data, int stride, char character){
     return(width);
 }
 
-typedef struct{
+typedef struct Buffer_Edit{
     int str_start, len;
     int start, end;
 } Buffer_Edit;
 
-typedef struct{
+typedef struct Buffer_Batch_State{
     int i;
     int shift_total;
 } Buffer_Batch_State;
@@ -103,7 +103,7 @@ typedef enum{
     buffer_seek_line_char
 } Buffer_Seek_Type;
 
-typedef struct{
+typedef struct Buffer_Seek{
     Buffer_Seek_Type type;
     union{
         struct { int pos; };
@@ -149,20 +149,18 @@ seek_line_char(int line, int character){
     return(result);
 }
 
-typedef struct{
+typedef struct Full_Cursor{
     int pos;
     int line, character;
     float unwrapped_x, unwrapped_y;
     float wrapped_x, wrapped_y;
 } Full_Cursor;
 
-typedef struct{
+typedef struct Buffer_Render_Item{
     int index;
     int glyphid;
     float x0, y0;
     float x1, y1;
-    
-    int chunk_i;
 } Buffer_Render_Item;
 
 inline_4tech void
@@ -198,7 +196,7 @@ make_cursor_hint(int line_index, int *starts, float *wrap_ys, float font_height)
     return(hint);
 }
 
-typedef struct{
+typedef struct Cursor_With_Index{
     int pos, index;
 } Cursor_With_Index;
 
diff --git a/temp.cpp b/temp.cpp
new file mode 100644
index 00000000..5b8ab654
--- /dev/null
+++ b/temp.cpp
@@ -0,0 +1,22 @@
+/*
+ * YOUR INFO HERE!
+ */
+
+// a b c d e f g
+
+#define swap(a,b) {auto t=a; a=b; b=t;}
+
+struct Thing{
+    int x, y, z;
+};
+
+struct Stuff{
+    Thing x;
+    int a, b, c;
+};
+
+void insert_sort(int *items, int size){
+    
+}
+
+