diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp
index fedde9d2..a84338ed 100644
--- a/4ed_file_view.cpp
+++ b/4ed_file_view.cpp
@@ -125,6 +125,8 @@ enum View_UI{
     VUI_None,
     VUI_Theme,
     VUI_Interactive,
+    VUI_Menu,
+    VUI_Config,
     VUI_Debug
 };
 
@@ -144,7 +146,7 @@ enum Color_View_Mode{
 struct File_Viewing_Data{
     Editing_File *file;
     
-    i32 temp_highlight_pos;
+    Full_Cursor temp_highlight;
     i32 temp_highlight_end_pos;
     b32 show_temp_highlight;
     
@@ -235,9 +237,17 @@ 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?
     Query_Set query_set;
     f32 widget_height;
+    
     b32 reinit_scrolling;
+    
     Debug_Vars debug_vars;
 };
 
@@ -281,18 +291,11 @@ view_file_height(View *view){
     return (result);
 }
 
-internal Full_Cursor
-view_compute_cursor(View *view, Buffer_Seek seek, b32 return_hint){
-    Full_Cursor result = {0};
-    NotImplemented;
-    return(result);
-}
-
 inline i32
 view_get_cursor_pos(View *view){
     i32 result = 0;
     if (view->file_data.show_temp_highlight){
-        result = view->file_data.temp_highlight_pos;
+        result = view->file_data.temp_highlight.pos;
     }
     else if (view->edit_pos){
         result = view->edit_pos->cursor.pos;
@@ -302,12 +305,21 @@ view_get_cursor_pos(View *view){
 
 inline f32
 view_get_cursor_x(View *view){
-    i32 pos = view_get_cursor_pos(view);
+    f32 result = 0;
     
-    Full_Cursor cursor = view_compute_cursor(view, seek_pos(pos), false);
-    f32 result = cursor.wrapped_x;
-    if (view->file_data.file->settings.unwrapped_lines){
-        result = cursor.unwrapped_x;
+    Full_Cursor *cursor = 0;
+    if (view->file_data.show_temp_highlight){
+        cursor = &view->file_data.temp_highlight;
+    }
+    else if (view->edit_pos){
+        cursor = &view->edit_pos->cursor;
+    }
+    
+    if (cursor){
+        result = cursor->wrapped_x;
+        if (view->file_data.file->settings.unwrapped_lines){
+            result = cursor->unwrapped_x;
+        }
     }
     
     return(result);
@@ -315,29 +327,38 @@ view_get_cursor_x(View *view){
 
 inline f32
 view_get_cursor_y(View *view){
-    i32 pos = view_get_cursor_pos(view);
+    f32 result = 0;
     
-    Full_Cursor cursor = view_compute_cursor(view, seek_pos(pos), false);
-    f32 result = cursor.wrapped_y;
-    if (view->file_data.file->settings.unwrapped_lines){
-        result = cursor.unwrapped_y;
+    Full_Cursor *cursor = 0;
+    if (view->file_data.show_temp_highlight){
+        cursor = &view->file_data.temp_highlight;
+    }
+    else if (view->edit_pos){
+        cursor = &view->edit_pos->cursor;
+    }
+    
+    if (cursor){
+        result = cursor->wrapped_y;
+        if (view->file_data.file->settings.unwrapped_lines){
+            result = cursor->unwrapped_y;
+        }
     }
     
     return(result);
 }
 
 struct Cursor_Limits{
-    f32 min, max, delta;
+    f32 min, max;
+    f32 delta;
 };
 
-internal Cursor_Limits
+inline Cursor_Limits
 view_cursor_limits(View *view){
-    f32 visible_height = view_file_height(view);
-    Editing_File *file = view->file_data.file;
-    Metadata *metadata = &file->state.metadata;
-    f32 line_height = metadata->line_height;
-    
     Cursor_Limits limits = {0};
+    
+    f32 line_height = (f32)view->line_height;
+    f32 visible_height = view_file_height(view);
+    
     limits.max = visible_height - line_height*3.f;
     limits.min = line_height * 2;
     
@@ -352,16 +373,91 @@ view_cursor_limits(View *view){
         }
     }
     
-    limits.max = clamp_bottom(limits.max, 0);
-    limits.min = clamp_bottom(limits.min, 0);
+    limits.max = (limits.max > 0)?(limits.max):(0);
+    limits.min = (limits.min > 0)?(limits.min):(0);
     
     limits.delta = clamp_top(line_height*3.f, (limits.max - limits.min)*.5f);
     
     return(limits);
 }
 
+internal Full_Cursor
+view_compute_cursor(System_Functions *system, View *view, Buffer_Seek seek, b32 return_hint){
+    Editing_File *file = view->file_data.file;
+    
+    Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id);
+    Assert(font != 0);
+    
+    Full_Cursor result = {0};
+    
+    Buffer_Cursor_Seek_Params params;
+    params.buffer           = &file->state.buffer;
+    params.seek             = seek;
+    params.system           = system;
+    params.font             = font;
+    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 = {0};
+    Buffer_Layout_Stop stop = {0};
+    
+    i32 size = buffer_size(params.buffer);
+    
+    f32 line_shift = 0.f;
+    b32 do_wrap = 0;
+    i32 wrap_unit_end = 0;
+    
+    b32 first_wrap_determination = 1;
+    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 = 0;
+                    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 = 1;
+                            wrap_unit_end = file->state.wrap_positions[wrap_array_index];
+                        }
+                        else{
+                            do_wrap = 0;
+                            wrap_unit_end = file->state.wrap_positions[wrap_array_index];
+                        }
+                        first_wrap_determination = 0;
+                    }
+                    else{
+                        assert(stop.pos == wrap_unit_end);
+                        do_wrap = 1;
+                        ++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);
+}
+
 inline Full_Cursor
-view_compute_cursor_from_xy(View *view, f32 seek_x, f32 seek_y){
+view_compute_cursor_from_xy(System_Functions *system, View *view, f32 seek_x, f32 seek_y){
     Buffer_Seek seek;
     if (view->file_data.file->settings.unwrapped_lines){
         seek = seek_unwrapped_xy(seek_x, seek_y, 0);
@@ -369,12 +465,13 @@ view_compute_cursor_from_xy(View *view, f32 seek_x, f32 seek_y){
     else{
         seek = seek_wrapped_xy(seek_x, seek_y, 0);
     }
-    Full_Cursor result = view_compute_cursor(view, seek, false);
+    
+    Full_Cursor result = view_compute_cursor(system, view, seek, 0);
     return(result);
 }
 
 inline i32
-view_compute_max_target_y(i32 lowest_line, f32 line_height, f32 view_height){
+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;
     max_target_y = clamp_bottom(0.f, max_target_y);
     return(ceil32(max_target_y));
@@ -384,13 +481,12 @@ internal i32
 file_compute_lowest_line(Editing_File *file, f32 font_height){
     i32 lowest_line = 0;
     
-    Metadata *metadata = &file->state.metadata;
-    i32 line_count = metadata->line_count;
+    Gap_Buffer *buffer = &file->state.buffer;
     if (file->settings.unwrapped_lines){
-        lowest_line = line_count;
+        lowest_line = buffer->line_count;
     }
     else{
-        lowest_line = metadata->line_wrap_count[line_count];
+        lowest_line = file->state.wrap_line_index[buffer->line_count];
     }
     
     return(lowest_line);
@@ -398,11 +494,9 @@ file_compute_lowest_line(Editing_File *file, f32 font_height){
 
 inline i32
 view_compute_max_target_y(View *view){
-    Editing_File *file = view->file_data.file;
-    f32 line_height = file->state.metadata.line_height;
-    i32 lowest_line = file_compute_lowest_line(view->file_data.file, line_height);
-    f32 file_height = view_file_height(view);
-    f32 view_height = clamp_bottom(line_height, file_height);
+    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);
 }
@@ -458,25 +552,25 @@ view_move_view_to_cursor(View *view, GUI_Scroll_Vars *scroll, b32 center_view){
 }
 
 internal b32
-view_move_cursor_to_view(View *view, GUI_Scroll_Vars scroll, i32 *cursor_pos, f32 preferred_x){
-    b32 result = false;
+view_move_cursor_to_view(System_Functions *system, View *view, GUI_Scroll_Vars scroll, Full_Cursor *cursor, f32 preferred_x){
+    b32 result = 0;
     
     if (view->edit_pos){
-        Editing_File *file = view->file_data.file;
-        f32 line_height = file->state.metadata.line_height;
-        
-        Full_Cursor full_cursor = view_compute_cursor(view, seek_pos(*cursor_pos), false);
-        f32 old_cursor_y = full_cursor.wrapped_y;
+        i32 line_height = view->line_height;
+        f32 old_cursor_y = cursor->wrapped_y;
         if (view->file_data.file->settings.unwrapped_lines){
-            old_cursor_y = full_cursor.unwrapped_y;
+            old_cursor_y = cursor->unwrapped_y;
         }
         f32 cursor_y = old_cursor_y;
         f32 target_y = scroll.target_y + view->widget_height;
         
         Cursor_Limits limits = view_cursor_limits(view);
-        cursor_y = clamp_top(cursor_y, limits.max);
-        if (target_y != 0){
-            cursor_y = clamp_bottom(cursor_y, limits.min);
+        
+        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;
         }
         
         if (cursor_y != old_cursor_y){
@@ -487,9 +581,9 @@ view_move_cursor_to_view(View *view, GUI_Scroll_Vars scroll, i32 *cursor_pos, f3
                 cursor_y -= line_height;
             }
             
-            full_cursor = view_compute_cursor_from_xy(view, preferred_x, cursor_y);
-            *cursor_pos = full_cursor.pos;
-            result = true;
+            *cursor = view_compute_cursor_from_xy(system, view, preferred_x, cursor_y);
+            
+            result = 1;
         }
     }
     
@@ -497,19 +591,9 @@ view_move_cursor_to_view(View *view, GUI_Scroll_Vars scroll, i32 *cursor_pos, f3
 }
 
 internal void
-view_set_cursor(View *view, i32 cursor_pos, b32 set_preferred_x){
-    Editing_File *file = view->file_data.file;
-    if (edit_pos_move_to_front(file, view->edit_pos)){
-        f32 preferred_x = 0.f;
-        if (set_preferred_x){
-            Full_Cursor cursor = view_compute_cursor(view, seek_pos(cursor_pos), false);
-            preferred_x = cursor.wrapped_x;
-            if (file->settings.unwrapped_lines){
-                preferred_x = cursor.unwrapped_x;
-            }
-        }
-        edit_pos_set_cursor(view->edit_pos, cursor_pos, set_preferred_x, preferred_x);
-        
+view_set_cursor(View *view, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapped_lines){
+    if (edit_pos_move_to_front(view->file_data.file, view->edit_pos)){
+        edit_pos_set_cursor(view->edit_pos, cursor, set_preferred_x, unwrapped_lines);
         GUI_Scroll_Vars scroll = view->edit_pos->scroll;
         if (view_move_view_to_cursor(view, &scroll, 0)){
             view->edit_pos->scroll = scroll;
@@ -518,35 +602,33 @@ view_set_cursor(View *view, i32 cursor_pos, b32 set_preferred_x){
 }
 
 internal void
-view_set_scroll(View *view, GUI_Scroll_Vars scroll){
+view_set_scroll(System_Functions *system, View *view, GUI_Scroll_Vars scroll){
     if (edit_pos_move_to_front(view->file_data.file, view->edit_pos)){
         edit_pos_set_scroll(view->edit_pos, scroll);
-        
-        i32 cursor = view->edit_pos->cursor;
-        if (view_move_cursor_to_view(view, view->edit_pos->scroll, &cursor, view->edit_pos->preferred_x)){
+        Full_Cursor cursor = view->edit_pos->cursor;
+        if (view_move_cursor_to_view(system, view, view->edit_pos->scroll, &cursor, view->edit_pos->preferred_x)){
             view->edit_pos->cursor = cursor;
         }
     }
 }
 
 internal void
-view_set_cursor_and_scroll(View *view, i32 cursor_pos, b32 set_preferred_x, f32 preferred_x, GUI_Scroll_Vars scroll){
+view_set_cursor_and_scroll(View *view, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapped_lines, GUI_Scroll_Vars scroll){
     File_Edit_Positions *edit_pos = view->edit_pos;
     if (edit_pos_move_to_front(view->file_data.file, edit_pos)){
-        edit_pos_set_cursor(edit_pos, cursor_pos, set_preferred_x, preferred_x);
+        edit_pos_set_cursor(edit_pos, cursor, set_preferred_x, unwrapped_lines);
         edit_pos_set_scroll(edit_pos, scroll);
         edit_pos->last_set_type = EditPos_None;
     }
 }
 
 inline void
-view_set_temp_highlight(View *view, i32 pos, i32 end_pos){
-    Full_Cursor cursor = view_compute_cursor(view, seek_pos(pos), false);
-    view->file_data.temp_highlight_pos = cursor.pos;
+view_set_temp_highlight(System_Functions *system, View *view, i32 pos, i32 end_pos){
+    view->file_data.temp_highlight = view_compute_cursor(system, view, seek_pos(pos), 0);
     view->file_data.temp_highlight_end_pos = end_pos;
-    view->file_data.show_temp_highlight = true;
+    view->file_data.show_temp_highlight = 1;
     
-    view_set_cursor(view, view->file_data.temp_highlight_pos, false);
+    view_set_cursor(view, view->file_data.temp_highlight, 0, view->file_data.file->settings.unwrapped_lines);
 }
 
 struct View_And_ID{
@@ -560,6 +642,12 @@ struct Live_Views{
     i32 count, max;
 };
 
+enum Lock_Level{
+    LockLevel_Open      = 0,
+    LockLevel_Protected = 1,
+    LockLevel_Hidden    = 2
+};
+
 inline u32
 view_lock_flags(View *view){
     u32 result = AccessOpen;
@@ -574,11 +662,6 @@ view_lock_flags(View *view){
     return(result);
 }
 
-enum Lock_Level{
-    LockLevel_Open      = 0,
-    LockLevel_Protected = 1,
-    LockLevel_Hidden    = 2
-};
 inline i32
 view_lock_level(View *view){
     i32 result = LockLevel_Open;
@@ -594,6 +677,7 @@ view_lock_level(View *view){
 
 struct View_Iter{
     View *view;
+    
     Editing_File *file;
     View *skip;
     Panel *used_panels;
@@ -664,18 +748,16 @@ save_file_to_name(System_Functions *system, Models *models, Editing_File *file,
         i32 max = 0, size = 0;
         b32 dos_write_mode = file->settings.dos_write_mode;
         char *data = 0;
-        
         Gap_Buffer *buffer = &file->state.buffer;
-        Metadata *metadata = &file->state.metadata;
         
         if (dos_write_mode){
-            max = buffer_size(buffer) + metadata->line_count + 1;
+            max = buffer_size(buffer) + buffer->line_count + 1;
         }
         else{
             max = buffer_size(buffer);
         }
         
-        b32 used_general = false;
+        b32 used_general = 0;
         Temp_Memory temp = begin_temp_memory(&mem->part);
         char empty = 0;
         if (max == 0){
@@ -768,23 +850,1153 @@ enum{
     GROW_SUCCESS,
 };
 
+internal i32
+file_grow_starts_as_needed(General_Memory *general, 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 = l_round_up_i32(target_lines + max, KB(1));
+        
+        i32 *new_lines = (i32*)general_memory_reallocate(general, buffer->line_starts, sizeof(i32)*count, sizeof(f32)*max);
+        
+        if (new_lines){
+            result = GROW_SUCCESS;
+            buffer->line_max = max;
+            buffer->line_starts = new_lines;
+        }
+        else{
+            result = GROW_FAILED;
+        }
+    }
+    
+    return(result);
+}
+
 internal void
-file_update_cursor_positions(Models *models, Editing_File *file){
+file_update_cursor_positions(System_Functions *system, Models *models, Editing_File *file){
     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)){
-        
         i32 pos = view_get_cursor_pos(iter.view);
+        
         if (!iter.view->file_data.show_temp_highlight){
-            view_set_cursor(iter.view, pos, true);
+            Full_Cursor cursor = view_compute_cursor(system, iter.view, seek_pos(pos), 0);
+            view_set_cursor(iter.view, cursor, 1, iter.view->file_data.file->settings.unwrapped_lines);
         }
         else{
-            view_set_temp_highlight(iter.view, pos, iter.view->file_data.temp_highlight_end_pos);
+            view_set_temp_highlight(system, iter.view, pos, iter.view->file_data.temp_highlight_end_pos);
         }
     }
 }
 
+//
+// File Metadata Measuring
+//
+
+internal void
+file_measure_starts(General_Memory *general, Gap_Buffer *buffer){
+    PRFL_FUNC_GROUP();
+    
+    if (!buffer->line_starts){
+        i32 max = buffer->line_max = KB(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;
+        }
+    }
+}
+
+// NOTE(allen): These calls assumes that the buffer's line starts are already correct,
+// and that the buffer's line_count is correct.
+internal void
+file_allocate_metadata_as_needed(General_Memory *general, Gap_Buffer *buffer, void **mem, i32 *mem_max_count, i32 count, i32 item_size){
+    if (*mem == 0){
+        i32 max = ((count+1)*2);
+        max = (max+(0x3FF))&(~(0x3FF));
+        *mem = general_memory_allocate(general, max*item_size);
+        *mem_max_count = max;
+    }
+    else if (*mem_max_count < count){
+        i32 old_max = *mem_max_count;
+        i32 max = ((count+1)*2);
+        max = (max+(0x3FF))&(~(0x3FF));
+        
+        void *new_mem = general_memory_reallocate(general, *mem, item_size*old_max, item_size*max);
+        
+        Assert(new_mem);
+        *mem = new_mem;
+        *mem_max_count = max;
+    }
+}
+
+inline void
+file_allocate_character_starts_as_needed(General_Memory *general, Editing_File *file){
+    file_allocate_metadata_as_needed(general, &file->state.buffer, (void**)&file->state.character_starts, &file->state. character_start_max, file->state.buffer.line_count, sizeof(i32));
+}
+
+internal void
+file_measure_character_starts(System_Functions *system, Models *models, Editing_File *file){
+    file_allocate_character_starts_as_needed(&models->mem.general, file);
+    Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id);
+    buffer_measure_character_starts(system, font, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white);
+    file_update_cursor_positions(system, models, file);
+}
+
+internal void
+file_allocate_indents_as_needed(General_Memory *general, Editing_File *file, i32 min_last_index){
+    i32 min_amount = min_last_index + 1;
+    file_allocate_metadata_as_needed(general, &file->state.buffer, (void**)&file->state.line_indents, &file->state.line_indent_max, min_amount, sizeof(f32));
+}
+
+inline void
+file_allocate_wraps_as_needed(General_Memory *general, Editing_File *file){
+    file_allocate_metadata_as_needed(general, &file->state.buffer, (void**)&file->state.wrap_line_index, &file->state.wrap_max, file->state.buffer.line_count, sizeof(f32));
+}
+
+inline void
+file_allocate_wrap_positions_as_needed(General_Memory *general, Editing_File *file, i32 min_last_index){
+    i32 min_amount = min_last_index + 1;
+    file_allocate_metadata_as_needed(general, &file->state.buffer, (void**)&file->state.wrap_positions, &file->state.wrap_position_max, min_amount, sizeof(f32));
+}
+
+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  = {0};
+
+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_index;
+    i32 next_line_start;
+    
+    f32 x;
+    b32 consume_newline;
+    
+    Gap_Buffer_Stream stream;
+    i32 size;
+    i32 i;
+    
+    Render_Font *font;
+    f32 tab_indent_amount;
+    f32 byte_advance;
+    
+    Translation_State tran;
+    Translation_Emits emits;
+    u32 J;
+    Buffer_Model_Step step;
+    Buffer_Model_Behavior behavior;
+};
+
+internal void
+wrap_state_init(System_Functions *system, Code_Wrap_State *state, Editing_File *file, Render_Font *font){
+    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->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->font = font;
+    
+    state->tab_indent_amount = font_get_glyph_advance(system, font, '\t');
+    state->byte_advance = font_get_byte_advance(font);
+    
+    state->tran = null_buffer_translating_state;
+}
+
+internal void
+wrap_state_set_x(Code_Wrap_State *state, f32 line_shift){
+    state->x = line_shift;
+}
+
+internal void
+wrap_state_set_i(Code_Wrap_State *state, i32 i){
+    state->i = i;
+}
+
+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;
+    }
+}
+
+struct Code_Wrap_Step{
+    i32 position_start;
+    i32 position_end;
+    
+    f32 start_x;
+    f32 final_x;
+    
+    Cpp_Token *this_token;
+};
+
+internal Code_Wrap_Step
+wrap_state_consume_token(System_Functions *system, Render_Font *font, Code_Wrap_State *state, i32 fixed_end_point){
+    Code_Wrap_Step result = {0};
+    i32 i = state->i;
+    
+    result.position_start = i;
+    
+    if (state->consume_newline){
+        ++i;
+        state->x = 0;
+        state->consume_newline = 0;
+    }
+    
+    if (state->in_pp_body){
+        if (!(state->token_ptr->flags & CPP_TFLAG_PP_BODY)){
+            state->in_pp_body = 0;
+            state->wrap_x = state->plane_wrap_x;
+        }
+    }
+    
+    if (!state->in_pp_body){
+        if (state->token_ptr->flags & CPP_TFLAG_PP_DIRECTIVE){
+            state->in_pp_body = 1;
+            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!
+    while (i >= state->next_line_start){
+        ++state->line_index;
+        state->next_line_start = state->line_starts[state->line_index + 1];
+    }
+    
+    i32 line_start = state->line_starts[state->line_index];
+    b32 still_looping = 0;
+    i32 end = state->token_ptr->start + state->token_ptr->size;
+    
+    if (fixed_end_point >= 0 && end > fixed_end_point){
+        end = fixed_end_point;
+    }
+    
+    i = clamp_bottom(i, line_start);
+    
+    if (i == line_start){
+        skipping_whitespace = true;
+    }
+    
+    b32 recorded_start_x = false;
+    do{
+        for (; i < state->stream.end; ++i){
+            if (!(i < end)){
+                Assert(state->tran.fill_expected == 0);
+                goto doublebreak;
+            }
+            
+            u8 ch = (u8)state->stream.data[i];
+            translating_fully_process_byte(system, font, &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(system, state->font, 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 = 1;
+                        }
+                        state->x += adv;
+                    }
+                }
+            }
+        }
+        still_looping = buffer_stringify_next(&state->stream);
+    }while(still_looping);
+    doublebreak:;
+    
+    state->i = i;
+    
+    b32 consume_token = 0;
+    if (i >= state->token_ptr->start + state->token_ptr->size){
+        consume_token = 1;
+    }
+    
+    result.this_token = state->token_ptr;
+    if (consume_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;
+    }
+    
+    result.position_end = state->i;
+    result.final_x = state->x;
+    
+    if (!recorded_start_x){
+        result.start_x = state->x;
+        recorded_start_x = 1;
+    }
+    
+    return(result);
+}
+
+struct Wrap_Indent_Pair{
+    i32 wrap_position;
+    f32 line_shift;
+};
+
+struct Potential_Wrap_Indent_Pair{
+    i32 wrap_position;
+    f32 line_shift;
+    
+    f32 wrap_x;
+    i32 wrappable_score;
+    
+    b32 adjust_top_to_this;
+};
+
+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 = 0, other_is_words = 0;
+    if (type == CPP_TOKEN_IDENTIFIER || (type >= CPP_TOKEN_KEY_TYPE && type <= CPP_TOKEN_KEY_OTHER)){
+        is_words = 1;
+    }
+    if (other_type == CPP_TOKEN_IDENTIFIER || (other_type >= CPP_TOKEN_KEY_TYPE && other_type <= CPP_TOKEN_KEY_OTHER)){
+        other_is_words = 1;
+    }
+    
+    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);
+}
+
+struct Wrap_Current_Shift{
+    f32 shift;
+    b32 adjust_top_to_this;
+};
+
+internal Wrap_Current_Shift
+get_current_shift(Code_Wrap_State *wrap_state, i32 next_line_start){
+    Wrap_Current_Shift result = {0};
+    
+    result.shift = wrap_state->wrap_x.paren_nesting[wrap_state->wrap_x.paren_safe_top];
+    
+    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 (wrap_state->token_ptr->type){
+            case CPP_TOKEN_BRACE_CLOSE: case CPP_TOKEN_BRACE_OPEN: break;
+            default: result.shift += statement_continuation_indent; break;
+        }
+    }
+    
+    if (wrap_state->token_ptr->start < next_line_start){
+        if (wrap_state->token_ptr->flags & CPP_TFLAG_PP_DIRECTIVE){
+            result.shift = 0;
+        }
+        else{
+            switch (wrap_state->token_ptr->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_bottom(0.f, result.shift);
+    return(result);
+}
+
+internal void
+file_measure_wraps(System_Functions *system, Models *models, Editing_File *file, Render_Font *font){
+    PRFL_FUNC_GROUP();
+    
+    General_Memory *general = &models->mem.general;
+    Partition *part = &models->mem.part;
+    
+    Temp_Memory temp = begin_temp_memory(part);
+    
+    file_allocate_wraps_as_needed(general, file);
+    file_allocate_indents_as_needed(general, file, file->state.buffer.line_count);
+    file_allocate_wrap_positions_as_needed(general, 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.font            = font;
+    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 = {0};
+    Buffer_Layout_Stop stop = {0};
+    
+    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 = {0};
+    
+    b32 use_tokens = false;
+    
+    Wrap_Indent_Pair *wrap_indent_marks = 0;
+    Potential_Wrap_Indent_Pair *potential_marks = 0;
+    i32 max_wrap_indent_mark = 0;
+    
+    if (params.virtual_white && file->state.tokens_complete && !file->state.still_lexing){
+        wrap_state_init(system, &wrap_state, file, font);
+        use_tokens = true;
+        
+        potential_marks = push_array(part, Potential_Wrap_Indent_Pair, floor32(width));
+        
+        max_wrap_indent_mark = partition_remaining(part)/sizeof(Wrap_Indent_Pair);
+        wrap_indent_marks = push_array(part, Wrap_Indent_Pair, max_wrap_indent_mark);
+    }
+    
+    i32 real_count = 0;
+    i32 potential_count = 0;
+    i32 stage = 0;
+    
+    PRFL_BEGIN_RESUMABLE(buffer_measure_wrap_y);
+    PRFL_BEGIN_RESUMABLE(NeedWrapDetermination);
+    PRFL_BEGIN_RESUMABLE(NeedLineShift);
+    PRFL_BEGIN_RESUMABLE(LongTokenParsing);
+    
+    do{
+        PRFL_START_RESUMABLE(buffer_measure_wrap_y);
+        stop = buffer_measure_wrap_y(&state, params, current_line_shift, do_wrap, wrap_unit_end);
+        PRFL_STOP_RESUMABLE(buffer_measure_wrap_y);
+        
+        switch (stop.status){
+            case BLStatus_NeedWrapDetermination:
+            {
+                PRFL_START_RESUMABLE(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(general, file, wrap_position_index);
+                        file->state.wrap_positions[wrap_position_index++] = stop.pos;
+                    }
+                }
+                else{
+                    Translation_State tran = {0};
+                    Translation_Emits emits = {0};
+                    Gap_Buffer_Stream stream = {0};
+                    
+                    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(system, font, &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.system, params.font, 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(general, file, wrap_position_index);
+                        file->state.wrap_positions[wrap_position_index++] = stop.pos;
+                    }
+                    else{
+                        do_wrap = 0;
+                    }
+                }
+                PRFL_STOP_RESUMABLE(NeedWrapDetermination);
+            }break;
+            
+            case BLStatus_NeedWrapLineShift:
+            case BLStatus_NeedLineShift:
+            {
+                PRFL_START_RESUMABLE(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 = {0};
+                            b32 emit_comment_position = 0;
+                            b32 first_word = 1;
+                            
+                            if (wrap_state.token_ptr->type == CPP_TOKEN_COMMENT || wrap_state.token_ptr->type == CPP_TOKEN_STRING_CONSTANT){
+                                PRFL_START_RESUMABLE(LongTokenParsing);
+                                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 = {0};
+                                Translation_State tran = {0};
+                                Translation_Emits emits = {0};
+                                
+                                Potential_Wrap_Indent_Pair potential_wrap = {0};
+                                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(system, font, &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(system, font, &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.system, params.font, 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(system, font, &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.system, params.font, 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;
+                                }
+                                
+                                PRFL_STOP_RESUMABLE(LongTokenParsing);
+                            }
+                            
+                            if (!emit_comment_position){
+                                step = wrap_state_consume_token(system, font, &wrap_state, next_line_start-1);
+                            }
+                            
+                            b32 need_to_choose_a_wrap = 0;
+                            if (step.final_x > current_width){
+                                need_to_choose_a_wrap = 1;
+                            }
+                            
+                            current_shift = get_current_shift(&wrap_state, next_line_start);
+                            
+                            b32 next_token_is_on_line = 0;
+                            if (wrap_state.token_ptr->start < next_line_start){
+                                next_token_is_on_line = 1;
+                            }
+                            
+                            i32 next_wrap_position = step.position_end;
+                            f32 wrap_x = step.final_x;
+                            if (wrap_state.token_ptr->start > step.position_start && next_wrap_position < wrap_state.token_ptr->start && next_token_is_on_line){
+                                next_wrap_position = wrap_state.token_ptr->start;
+                            }
+                            
+                            if (!need_to_choose_a_wrap){
+                                i32 wrappable_score = 1;
+                                
+                                Cpp_Token *this_token = step.this_token;
+                                Cpp_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 general_stickieness = this_stickieness;
+                                if (general_stickieness < next_stickieness){
+                                    general_stickieness = next_stickieness;
+                                }
+                                
+                                if (wrap_state.wrap_x.paren_top != 0 && this_type == CPP_TOKEN_COMMA){
+                                    general_stickieness = 0;
+                                }
+                                
+                                wrappable_score = 64*50;
+                                wrappable_score += 101 - general_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, font, &wrap_state, wrap_position);
+                                        if (step.position_end >= wrap_position){
+                                            break;
+                                        }
+                                    }
+                                    
+                                    wrap_state_set_x(&wrap_state, line_shift);
+                                    wrap_state_set_i(&wrap_state, 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, font, &wrap_state, next_line_start);
+                        }
+                    }
+                    
+                    current_line_shift = wrap_indent_marks[stage].line_shift;
+                    
+                    if (stage > 0){
+                        ++stage;
+                    }
+                    
+                    current_line_shift = clamp_bottom(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(general, 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;
+                
+                PRFL_STOP_RESUMABLE(NeedLineShift);
+            }break;
+        }
+    }while(stop.status != BLStatus_Finished);
+    
+    PRFL_END_RESUMABLE(buffer_measure_wrap_y);
+    PRFL_END_RESUMABLE(NeedWrapDetermination);
+    PRFL_END_RESUMABLE(NeedLineShift);
+    PRFL_END_RESUMABLE(LongTokenParsing);
+    
+    ++file->state.wrap_line_count;
+    
+    file_allocate_wrap_positions_as_needed(general, file, wrap_position_index);
+    file->state.wrap_positions[wrap_position_index++] = size;
+    file->state.wrap_position_count = wrap_position_index;
+    
+    end_temp_memory(temp);
+    
+    if (file->state.hacks.needs_wraps_and_fix_cursor){
+        file->state.hacks.needs_wraps_and_fix_cursor = false;
+        file_update_cursor_positions(system, models, file);
+    }
+}
+
+internal void
+file_measure_wraps_and_fix_cursor(System_Functions *system, Models *models, Editing_File *file, Render_Font *font){
+    if (file->state.hacks.suppression_mode){
+        file->state.hacks.needs_wraps_and_fix_cursor = true;
+    }
+    else{
+        file->state.hacks.needs_wraps_and_fix_cursor = false;
+        file_measure_wraps(system, models, file, font);
+        file_update_cursor_positions(system, models, file);
+    }
+}
+
+internal void
+file_set_width(System_Functions *system, Models *models, Editing_File *file, i32 display_width, Render_Font *font){
+    file->settings.display_width = display_width;
+    file_measure_wraps_and_fix_cursor(system, models, file, font);
+}
+
+internal void
+file_set_min_base_width(System_Functions *system, Models *models, Editing_File *file, i32 minimum_base_display_width, Render_Font *font){
+    file->settings.minimum_base_display_width = minimum_base_display_width;
+    file_measure_wraps_and_fix_cursor(system, models, file, font);
+}
+
+//
+//
+//
+
 internal void
 file_create_from_string(System_Functions *system, Models *models, Editing_File *file, String val, b8 read_only = 0){
     PRFL_FUNC_GROUP();
@@ -794,10 +2006,8 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File *
     Open_File_Hook_Function *hook_open_file = models->hook_open_file;
     Application_Links *app_links = &models->app_links;
     
-    Gap_Buffer *buffer = &file->state.buffer;
-    
     file->state = null_editing_file_state;
-    Gap_Buffer_Init init = buffer_begin_init(buffer, val.str, val.size);
+    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 = l_round_up_i32(page_size, KB(4));
@@ -813,16 +2023,24 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File *
     b32 init_success = buffer_end_init(&init, part->base + part->pos, scratch_size);
     AllowLocal(init_success); Assert(init_success);
     
-    if (buffer_size(buffer) < val.size){
-        file->settings.dos_write_mode = true;
+    if (buffer_size(&file->state.buffer) < val.size){
+        file->settings.dos_write_mode = 1;
     }
     file_synchronize_times(system, file);
     
     Font_ID font_id = models->global_font_id;
     file->settings.font_id = font_id;
-    Font *font = system->font.get_render_data_by_id(font_id);
+    Render_Font *font = system->font.get_render_data_by_id(font_id);
     
-    buffer_metadata_initialize(system, part, general, buffer, &file->state.metadata, font);
+    {
+        PRFL_SCOPE_GROUP(measurements);
+        file_measure_starts(general, &file->state.buffer);
+        
+        file_allocate_character_starts_as_needed(general, file);
+        buffer_measure_character_starts(system, font, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white);
+        
+        file_measure_wraps(system, models, file, font);
+    }
     
     file->settings.read_only = read_only;
     if (!read_only){
@@ -855,7 +2073,12 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File *
     
     if (hook_open_file){
         PRFL_SCOPE_GROUP(open_hook);
+        file->state.hacks.suppression_mode = true;
         hook_open_file(app_links, file->id.id);
+        file->state.hacks.suppression_mode = false;
+        if (file->state.hacks.needs_wraps_and_fix_cursor){
+            file_measure_wraps_and_fix_cursor(system, models, file, font);
+        }
     }
     file->settings.is_initialized = true;
 }
@@ -876,9 +2099,12 @@ file_close(System_Functions *system, General_Memory *general, Editing_File *file
     Gap_Buffer *buffer = &file->state.buffer;
     if (buffer->data){
         general_memory_free(general, buffer->data);
+        general_memory_free(general, buffer->line_starts);
     }
     
-    buffer_metadata_cleanup(general, &file->state.metadata);
+    general_memory_free(general, file->state.wrap_line_index);
+    general_memory_free(general, file->state.character_starts);
+    general_memory_free(general, file->state.line_indents);
     
     if (file->state.undo.undo.edits){
         general_memory_free(general, file->state.undo.undo.strings);
@@ -1176,7 +2402,6 @@ file_relex_parallel(System_Functions *system, Mem_Options *mem, Editing_File *fi
         
         Cpp_Relex_Data state = cpp_relex_init(array, start_i, end_i, shift_amount, file->settings.tokens_without_strings);
         
-        // TODO(allen): Gap_Buffer now has a chunk API so this can be cleaned up and deduplicated whenever.
         char *chunks[3];
         i32 chunk_sizes[3];
         
@@ -1636,15 +2861,26 @@ file_view_nullify_file(View *view){
     view->file_data = null_file_viewing_data;
 }
 
-// TODO(allen): Time to get rid of view_cursor_move
-inline void
-view_cursor_move(View *view, i32 pos){
-    view_set_cursor(view, pos, true);
-    view->file_data.show_temp_highlight = false;
+internal void
+update_view_line_height(System_Functions *system, Models *models, View *view, Font_ID font_id){
+    Render_Font *font = system->font.get_render_data_by_id(font_id);
+    view->line_height = font_get_height(font);
 }
 
 inline void
-view_cursor_move(View *view, f32 x, f32 y, b32 round_down = false){
+view_cursor_move(View *view, Full_Cursor cursor){
+    view_set_cursor(view, cursor, 1, view->file_data.file->settings.unwrapped_lines);
+    view->file_data.show_temp_highlight = 0;
+}
+
+inline void
+view_cursor_move(System_Functions *system, View *view, i32 pos){
+    Full_Cursor cursor = view_compute_cursor(system, view, seek_pos(pos), 0);
+    view_cursor_move(view, cursor);
+}
+
+inline void
+view_cursor_move(System_Functions *system, View *view, f32 x, f32 y, b32 round_down = 0){
     Buffer_Seek seek;
     if (view->file_data.file->settings.unwrapped_lines){
         seek = seek_unwrapped_xy(x, y, round_down);
@@ -1652,14 +2888,15 @@ view_cursor_move(View *view, f32 x, f32 y, b32 round_down = false){
     else{
         seek = seek_wrapped_xy(x, y, round_down);
     }
-    Full_Cursor cursor = view_compute_cursor(view, seek, false);
-    view_cursor_move(view, cursor.pos);
+    
+    Full_Cursor cursor = view_compute_cursor(system, view, seek, 0);
+    view_cursor_move(view, cursor);
 }
 
 inline void
-view_cursor_move(View *view, i32 line, i32 character){
-    Full_Cursor cursor = view_compute_cursor(view, seek_line_char(line, character), false);
-    view_cursor_move(view, cursor.pos);
+view_cursor_move(System_Functions *system, View *view, i32 line, i32 character){
+    Full_Cursor cursor = view_compute_cursor(system, view, seek_line_char(line, character), 0);
+    view_cursor_move(view, cursor);
 }
 
 inline void
@@ -1699,6 +2936,12 @@ view_set_file(System_Functions *system, View *view, Editing_File *file, Models *
     edit_pos = edit_pos_get_new(file, view->persistent.id);
     view->edit_pos = edit_pos;
     
+    update_view_line_height(system, models, view, file->settings.font_id);
+    
+    if (edit_pos->cursor.line == 0){
+        view_cursor_move(system, view, 0);
+    }
+    
     if (view->showing_ui == VUI_None){
         view_show_file(view);
     }
@@ -1962,7 +3205,7 @@ file_edit_cursor_fix(System_Functions *system, Models *models, Editing_File *fil
         view = panel->view;
         if (view->file_data.file == file){
             Assert(view->edit_pos);
-            write_cursor_with_index(cursors, &cursor_count, view->edit_pos->cursor);
+            write_cursor_with_index(cursors, &cursor_count, view->edit_pos->cursor.pos);
             write_cursor_with_index(cursors, &cursor_count, view->edit_pos->mark);
             write_cursor_with_index(cursors, &cursor_count, view->edit_pos->scroll_i);
         }
@@ -1983,6 +3226,8 @@ file_edit_cursor_fix(System_Functions *system, Models *models, Editing_File *fil
         }
     }
     
+    // TODO(NAME): dump all the markers in the file and then read them back out.
+    // Make a plan for "right leaning" markers.
     if (cursor_count > 0){
         buffer_sort_cursors(cursors, cursor_count);
         if (desc.is_batch){
@@ -1995,9 +3240,6 @@ file_edit_cursor_fix(System_Functions *system, Models *models, Editing_File *fil
         }
         buffer_unsort_cursors(cursors, cursor_count);
         
-        f32 line_height = file->state.metadata.line_height;
-        b32 unwrapped_lines = file->settings.unwrapped_lines;
-        
         cursor_count = 0;
         r_cursor_count = 0;
         for (dll_items(panel, used_panels)){
@@ -2005,33 +3247,30 @@ file_edit_cursor_fix(System_Functions *system, Models *models, Editing_File *fil
             if (view->file_data.file == file){
                 Assert(view->edit_pos);
                 
-                GUI_Scroll_Vars scroll = view->edit_pos->scroll;
                 i32 cursor_pos = cursors[cursor_count++].pos;
+                Full_Cursor new_cursor = view_compute_cursor(system, view, seek_pos(cursor_pos), 0);
+                
+                GUI_Scroll_Vars scroll = view->edit_pos->scroll;
                 
                 view->edit_pos->mark = cursors[cursor_count++].pos;
                 i32 new_scroll_i = cursors[cursor_count++].pos;
                 if (view->edit_pos->scroll_i != new_scroll_i){
                     view->edit_pos->scroll_i = new_scroll_i;
                     
-                    Full_Cursor temp_cursor = view_compute_cursor(view, seek_pos(view->edit_pos->scroll_i), false);
+                    Full_Cursor temp_cursor = view_compute_cursor(system, view, seek_pos(view->edit_pos->scroll_i), 0);
+                    
+                    f32 y_offset = MOD(view->edit_pos->scroll.scroll_y, view->line_height);
                     f32 y_position = temp_cursor.wrapped_y;
-                    if (unwrapped_lines){
+                    if (view->file_data.file->settings.unwrapped_lines){
                         y_position = temp_cursor.unwrapped_y;
                     }
-                    
-                    f32 y_offset = MOD(scroll.scroll_y, (i32)line_height);
                     y_position += y_offset;
                     
                     scroll.target_y += round32(y_position - scroll.scroll_y);
                     scroll.scroll_y = y_position;
                 }
                 
-                Full_Cursor new_cursor = view_compute_cursor(view, seek_pos(cursor_pos), false);
-                f32 preferred_x = new_cursor.wrapped_x;
-                if (unwrapped_lines){
-                    preferred_x = new_cursor.unwrapped_x;
-                }
-                view_set_cursor_and_scroll(view, cursor_pos, true, preferred_x, scroll);
+                view_set_cursor_and_scroll(view, new_cursor, 1, view->file_data.file->settings.unwrapped_lines, scroll);
             }
         }
         
@@ -2074,17 +3313,15 @@ file_do_single_edit(System_Functions *system, Models *models, Editing_File *file
     
     i32 scratch_size = partition_remaining(part);
     
-    Gap_Buffer *buffer = &file->state.buffer;
-    
     Assert(scratch_size > 0);
     i32 request_amount = 0;
-    Assert(end <= buffer_size(buffer));
-    while (buffer_replace_range(buffer, start, end, str, str_len, &shift_amount, part->base + part->pos, scratch_size, &request_amount)){
+    Assert(end <= buffer_size(&file->state.buffer));
+    while (buffer_replace_range(&file->state.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);
         }
-        void *old_data = buffer_edit_provide_memory(buffer, new_data, request_amount);
+        void *old_data = buffer_edit_provide_memory(&file->state.buffer, new_data, request_amount);
         if (old_data){
             general_memory_free(general, old_data);
         }
@@ -2101,11 +3338,27 @@ file_do_single_edit(System_Functions *system, Models *models, Editing_File *file
     }
     
     // NOTE(allen): meta data
-    Metadata *metadata = &file->state.metadata;
-    Font *font = system->font.get_render_data_by_id(file->settings.font_id);
-    i32 pre_end = end;
-    i32 post_end = str_len + start;
-    buffer_metadata_update(system, general, buffer, metadata, font, start, pre_end, post_end);
+    Gap_Buffer *buffer = &file->state.buffer;
+    i32 line_start = buffer_get_line_index(&file->state.buffer, start);
+    i32 line_end = buffer_get_line_index(&file->state.buffer, end);
+    i32 replaced_line_count = line_end - line_start;
+    i32 new_line_count = buffer_count_newlines(&file->state.buffer, start, start+str_len);
+    i32 line_shift =  new_line_count - replaced_line_count;
+    
+    Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id);
+    file_grow_starts_as_needed(general, buffer, line_shift);
+    buffer_remeasure_starts(buffer, line_start, line_end, line_shift, shift_amount);
+    
+    file_allocate_character_starts_as_needed(general, file);
+    buffer_remeasure_character_starts(system, font, buffer, line_start, line_end, line_shift, file->state.character_starts, 0, file->settings.virtual_white);
+    
+    // TODO(allen): Redo this as some sort of dialogical API
+#if 0
+    file_allocate_wraps_as_needed(general, file);
+    buffer_remeasure_wrap_y(buffer, line_start, line_end, line_shift, file->state.wraps, (f32)font->height, font->advance_data, (f32)file->settings.display_width);
+#endif
+    
+    file_measure_wraps(system, models, file, font);
     
     // NOTE(allen): cursor fixing
     Cursor_Fix_Descriptor desc = {0};
@@ -2137,16 +3390,16 @@ file_do_batch_edit(System_Functions *system, Models *models, Editing_File *file,
     Assert(batch_size >= 0);
     
     i32 scratch_size = partition_remaining(part);
-    Gap_Buffer *buffer = &file->state.buffer;
-    
-    Buffer_Batch_State state = {0};
+    Buffer_Batch_State state = {};
     i32 request_amount = 0;
-    while (buffer_batch_edit_step(&state, buffer, batch, (char*)str_base, batch_size, part->base + part->pos, scratch_size, &request_amount)){
+    while (buffer_batch_edit_step(&state, &file->state.buffer, batch,
+                                  (char*)str_base, batch_size, part->base + part->pos,
+                                  scratch_size, &request_amount)){
         void *new_data = 0;
         if (request_amount > 0){
             new_data = general_memory_allocate(general, request_amount);
         }
-        void *old_data = buffer_edit_provide_memory(buffer, new_data, request_amount);
+        void *old_data = buffer_edit_provide_memory(&file->state.buffer, new_data, request_amount);
         if (old_data){
             general_memory_free(general, old_data);
         }
@@ -2159,6 +3412,7 @@ file_do_batch_edit(System_Functions *system, Models *models, Editing_File *file,
         case BatchEdit_Normal:
         {
             if (file->settings.tokens_exist){
+                // TODO(allen): Write a smart fast one here someday.
                 Buffer_Edit *first_edit = batch;
                 Buffer_Edit *last_edit = batch + batch_size - 1;
                 
@@ -2203,17 +3457,26 @@ file_do_batch_edit(System_Functions *system, Models *models, Editing_File *file,
         }break;
     }
     
+    // TODO(allen): Let's try to switch to remeasuring here moron!
+    // We'll need to get the total shift from the actual batch edit state
+    // instead of from the cursor fixing.  The only reason we're getting
+    // it from cursor fixing is because you're a lazy asshole.
+    
     // NOTE(allen): meta data
-    Metadata *metadata = &file->state.metadata;
-    Font *font = system->font.get_render_data_by_id(file->settings.font_id);
-    i32 start = batch[0].start;
-    i32 pre_end = batch[batch_size-1].end;
-    i32 post_end = pre_end + shift_total;
-    buffer_metadata_update(system, general, buffer, metadata, font, start, pre_end, post_end);
+    Buffer_Measure_Starts measure_state = {};
+    buffer_measure_starts(&measure_state, &file->state.buffer);
+    
+    Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id);
+    
+    // TODO(allen): write the remeasurement version
+    file_allocate_character_starts_as_needed(&models->mem.general, file);
+    buffer_measure_character_starts(system, font, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white);
+    
+    file_measure_wraps(system, models, file, font);
     
     // NOTE(allen): cursor fixing
     Cursor_Fix_Descriptor desc = {0};
-    desc.is_batch = true;
+    desc.is_batch = 1;
     desc.batch = batch;
     desc.batch_size = batch_size;
     file_edit_cursor_fix(system, models, file, layout, desc);
@@ -2271,8 +3534,8 @@ apply_history_edit(System_Functions *system, Models *models, Editing_File *file,
         file_do_single_edit(system, models, file, spec, history_mode);
         
         if (view){
-            view_cursor_move(view, step.edit.start + step.edit.len);
-            view->edit_pos->mark = view->edit_pos->cursor;
+            view_cursor_move(system, view, step.edit.start + step.edit.len);
+            view->edit_pos->mark = view->edit_pos->cursor.pos;
             
             Style *style = main_style(models);
             view_post_paste_effect(view, 0.333f, step.edit.start, step.edit.len, style->main.undo_color);
@@ -2484,13 +3747,15 @@ style_get_color(Style *style, Cpp_Token token){
 internal void
 file_set_font(System_Functions *system, Models *models, Editing_File *file, Font_ID font_id){
     file->settings.font_id = font_id;
+    Render_Font *font = system->font.get_render_data_by_id(font_id);
+    file_measure_wraps_and_fix_cursor(system, models, file, font);
     
-    General_Memory *general = &models->mem.general;
-    Partition *part = &models->mem.part;
-    Gap_Buffer *buffer = &file->state.buffer;
-    Metadata *metadata = &file->state.metadata;
-    Font *font = system->font.get_render_data_by_id(font_id);
-    buffer_metadata_change_font(system, part, general, buffer, metadata, font);
+    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(system, models, iter.view, font_id);
+    }
 }
 
 internal void
@@ -2931,15 +4196,22 @@ file_step(View *view, i32_Rect region, Input_Summary *user_input, b32 is_active,
 
 internal void
 do_widget(View *view, GUI_Target *target){
+    Query_Slot *slot;
+    Query_Bar *bar;
+    
+    // NOTE(allen): A temporary measure... although in
+    // general we maybe want the user to be able to ask
+    // how large a particular section of the GUI turns
+    // out to be after layout?
     f32 height = 0.f;
-    Query_Slot *slot = 0;
-    Editing_File *file = view->file_data.file;
-    i32 bar_height = ceil32(file->state.metadata.line_height) + 2;
+    
     for (slot = view->query_set.used_slot; slot != 0; slot = slot->next){
-        Query_Bar *bar = slot->query_bar;
+        bar = slot->query_bar;
         gui_do_text_field(target, bar->prompt, bar->string);
-        height += bar_height;
+        
+        height += view->line_height + 2;
     }
+    
     view->widget_height = height;
 }
 
@@ -3200,7 +4472,8 @@ show_gui_line(GUI_Target *target, String *string, i32 indent_level, i32 h_align,
 }
 
 internal void
-show_gui_int(GUI_Target *target, String *string, i32 indent_level, i32 h_align, char *message, i32 x){
+show_gui_int(GUI_Target *target, String *string,
+             i32 indent_level, i32 h_align, char *message, i32 x){
     string->size = 0;
     append_label(string, indent_level, message);
     append_padding(string, '-', h_align);
@@ -3210,7 +4483,8 @@ show_gui_int(GUI_Target *target, String *string, i32 indent_level, i32 h_align,
 }
 
 internal void
-show_gui_u64(GUI_Target *target, String *string, i32 indent_level, i32 h_align, char *message, u64 x){
+show_gui_u64(GUI_Target *target, String *string,
+             i32 indent_level, i32 h_align, char *message, u64 x){
     string->size = 0;
     append_label(string, indent_level, message);
     append_padding(string, '-', h_align);
@@ -3220,7 +4494,8 @@ show_gui_u64(GUI_Target *target, String *string, i32 indent_level, i32 h_align,
 }
 
 internal void
-show_gui_int_int(GUI_Target *target, String *string, i32 indent_level, i32 h_align, char *message, i32 x, i32 m){
+show_gui_int_int(GUI_Target *target, String *string,
+                 i32 indent_level, i32 h_align, char *message, i32 x, i32 m){
     string->size = 0;
     append_label(string, indent_level, message);
     append_padding(string, '-', h_align);
@@ -3232,7 +4507,8 @@ show_gui_int_int(GUI_Target *target, String *string, i32 indent_level, i32 h_ali
 }
 
 internal void
-show_gui_id(GUI_Target *target, String *string, i32 indent_level, i32 h_align, char *message, GUI_id id){
+show_gui_id(GUI_Target *target, String *string,
+            i32 indent_level, i32 h_align, char *message, GUI_id id){
     string->size = 0;
     append_label(string, indent_level, message);
     append_padding(string, '-', h_align);
@@ -3245,7 +4521,8 @@ show_gui_id(GUI_Target *target, String *string, i32 indent_level, i32 h_align, c
 }
 
 internal void
-show_gui_float(GUI_Target *target, String *string, i32 indent_level, i32 h_align, char *message, float x){
+show_gui_float(GUI_Target *target, String *string,
+               i32 indent_level, i32 h_align, char *message, float x){
     string->size = 0;
     append_label(string, indent_level, message);
     append_padding(string, '-', h_align);
@@ -3255,7 +4532,9 @@ show_gui_float(GUI_Target *target, String *string, i32 indent_level, i32 h_align
 }
 
 internal void
-show_gui_scroll(GUI_Target *target, String *string, i32 indent_level, i32 h_align, char *message, GUI_Scroll_Vars scroll){
+show_gui_scroll(GUI_Target *target, String *string,
+                i32 indent_level, i32 h_align, char *message,
+                GUI_Scroll_Vars scroll){
     show_gui_line (target, string, indent_level, 0, message, 0);
     show_gui_float(target, string, indent_level+1, h_align, " scroll_y ", scroll.scroll_y);
     show_gui_int  (target, string, indent_level+1, h_align, " target_y ", scroll.target_y);
@@ -3266,7 +4545,23 @@ show_gui_scroll(GUI_Target *target, String *string, i32 indent_level, i32 h_alig
 }
 
 internal void
-show_gui_region(GUI_Target *target, String *string, i32 indent_level, i32 h_align, char *message, i32_Rect region){
+show_gui_cursor(GUI_Target *target, String *string,
+                i32 indent_level, i32 h_align, char *message,
+                Full_Cursor cursor){
+    show_gui_line (target, string, indent_level, 0, message, 0);
+    show_gui_int  (target, string, indent_level+1, h_align, " pos ", cursor.pos);
+    show_gui_int  (target, string, indent_level+1, h_align, " line ", cursor.line);
+    show_gui_int  (target, string, indent_level+1, h_align, " column ", cursor.character);
+    show_gui_float(target, string, indent_level+1, h_align, " unwrapped_x ", cursor.unwrapped_x);
+    show_gui_float(target, string, indent_level+1, h_align, " unwrapped_y ", cursor.unwrapped_y);
+    show_gui_float(target, string, indent_level+1, h_align, " wrapped_x ", cursor.wrapped_x);
+    show_gui_float(target, string, indent_level+1, h_align, " wrapped_y ", cursor.wrapped_y);
+}
+
+internal void
+show_gui_region(GUI_Target *target, String *string,
+                i32 indent_level, i32 h_align, char *message,
+                i32_Rect region){
     show_gui_line(target, string, indent_level, 0, message, 0);
     show_gui_int (target, string, indent_level+1, h_align, " x0 ", region.x0);
     show_gui_int (target, string, indent_level+1, h_align, " y0 ", region.y0);
@@ -3302,11 +4597,14 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
     b32 show_scrollbar = !view->hide_scrollbar;
     
     if (view->showing_ui != VUI_None){
-        b32 did_esc = false;
-        for (i32 i = 0; i < keys.count; ++i){
-            Key_Event_Data key = get_single_key(&keys, i);
+        b32 did_esc = 0;
+        Key_Event_Data key;
+        i32 i;
+        
+        for (i = 0; i < keys.count; ++i){
+            key = get_single_key(&keys, i);
             if (key.keycode == key_esc){
-                did_esc = true;
+                did_esc = 1;
                 break;
             }
         }
@@ -3317,12 +4615,6 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
         }
     }
     
-    Editing_File *this_file = view->file_data.file;
-    Assert(this_file != 0);
-    
-    i32 line_height = ceil32(this_file->state.metadata.line_height);
-    i32 delta = line_height*9;
-    
     gui_begin_top_level(target, input);
     {
         if (view->showing_ui != VUI_Debug && !view->hide_file_bar){
@@ -3334,6 +4626,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
             
             gui_begin_serial_section(target);
             {
+                i32 delta = 9 * view->line_height;
                 GUI_id scroll_context = {0};
                 scroll_context.id[1] = view->showing_ui;
                 scroll_context.id[0] = (u64)(view->file_data.file);
@@ -3440,14 +4733,17 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
                             message = make_lit_string("Theme Library - Click to Select");
                             gui_do_text_field(target, message, empty_string);
                             
-                            gui_begin_scrollable(target, scroll_context, view->gui_scroll, delta, show_scrollbar);
+                            gui_begin_scrollable(target, scroll_context, view->gui_scroll,
+                                                 9 * view->line_height, show_scrollbar);
                             
-                            i32 count = models->styles.count;
-                            for (i32 i = 1; i < count; ++i){
-                                Style *style = get_style(models, i);
-                                id.id[0] = (u64)(style);
-                                if (gui_do_style_preview(target, id, i)){
-                                    style_copy(main_style(models), style);
+                            {
+                                i32 count = models->styles.count;
+                                for (i32 i = 1; i < count; ++i){
+                                    Style *style = get_style(models, i);
+                                    id.id[0] = (u64)(style);
+                                    if (gui_do_style_preview(target, id, i)){
+                                        style_copy(main_style(models), style);
+                                    }
                                 }
                             }
                             
@@ -3458,6 +4754,9 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
                         case CV_Mode_Global_Font:
                         case CV_Mode_Font:
                         {
+                            Editing_File *file = view->file_data.file;
+                            Assert(file != 0);
+                            
                             message = make_lit_string("Back");
                             
                             id.id[0] = 0;
@@ -3467,7 +4766,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
                             
                             Font_ID font_id = models->global_font_id;
                             if (view->color_mode == CV_Mode_Font){
-                                font_id = this_file->settings.font_id;
+                                font_id = file->settings.font_id;
                             }
                             
                             // TODO(allen): paginate the display
@@ -3500,7 +4799,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
                             
                             if (font_id != new_font_id){
                                 if (view->color_mode == CV_Mode_Font){
-                                    file_set_font(system, models, this_file, new_font_id);
+                                    file_set_font(system, models, file, new_font_id);
                                 }
                                 else{
                                     global_set_font(system, models, new_font_id);
@@ -3522,7 +4821,8 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
                                 view->color_mode = CV_Mode_Library;
                             }
                             
-                            gui_begin_scrollable(target, scroll_context, view->gui_scroll, delta, show_scrollbar);
+                            gui_begin_scrollable(target, scroll_context, view->gui_scroll,
+                                                 9 * view->line_height, show_scrollbar);
                             
                             i32 next_color_editing = view->current_color_editing;
                             
@@ -3669,7 +4969,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
                             if (gui_scroll_was_activated(target, scroll_context)){
                                 snap_into_view = true;
                             }
-                            gui_begin_scrollable(target, scroll_context, view->gui_scroll, delta, show_scrollbar);
+                            gui_begin_scrollable(target, scroll_context, view->gui_scroll, 9 * view->line_height, show_scrollbar);
                             
                             id.id[0] = (u64)(hdir) + 1;
                             
@@ -3768,7 +5068,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
                             if (gui_scroll_was_activated(target, scroll_context)){
                                 snap_into_view = 1;
                             }
-                            gui_begin_scrollable(target, scroll_context, view->gui_scroll, delta, show_scrollbar);
+                            gui_begin_scrollable(target, scroll_context, view->gui_scroll, 9 * view->line_height, show_scrollbar);
                             
                             id.id[0] = (u64)(working_set) + 1;
                             if (gui_begin_list(target, id, view->list_i, 0, snap_into_view, &update)){
@@ -3971,7 +5271,8 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
                         }
                     }
                     
-                    gui_begin_scrollable(target, scroll_context, view->gui_scroll, delta, show_scrollbar);
+                    gui_begin_scrollable(target, scroll_context, view->gui_scroll,
+                                         9 * view->line_height, show_scrollbar);
                     
                     switch (view->debug_vars.mode)
                     {
@@ -4179,6 +5480,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
                                         else { show_gui_line(target, &string, n, h, " " str " ", "false"); } } while(0)
                                     
 #define SHOW_GUI_SCROLL(n, h, str, v) show_gui_scroll(target, &string, n, h, " " str, v)
+#define SHOW_GUI_CURSOR(n, h, str, v) show_gui_cursor(target, &string, n, h, " " str, v)
 #define SHOW_GUI_REGION(n, h, str, v) show_gui_region(target, &string, n, h, " " str, v)
                                     
                                     i32 h_align = 31;
@@ -4211,7 +5513,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
                                     SHOW_GUI_LINE(1, "file data:");
                                     SHOW_GUI_BOOL(2, h_align, "has file", view_ptr->file_data.file);
                                     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, "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, "show whitespace", view_ptr->file_data.show_whitespace);
@@ -4228,7 +5530,8 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
                                         if (edit_pos){
                                             SHOW_GUI_SCROLL(2, h_align, "scroll:", edit_pos->scroll);
                                             SHOW_GUI_BLANK (2);
-                                            SHOW_GUI_INT   (2, h_align, "cursor:", edit_pos->cursor);
+                                            SHOW_GUI_CURSOR(2, h_align, "cursor:", edit_pos->cursor);
+                                            SHOW_GUI_BLANK (2);
                                             SHOW_GUI_INT   (2, h_align, "mark", edit_pos->mark);
                                             SHOW_GUI_FLOAT (2, h_align, "preferred_x", edit_pos->preferred_x);
                                             SHOW_GUI_INT   (2, h_align, "scroll_i", edit_pos->scroll_i);
@@ -4364,9 +5667,9 @@ to_writable_character(Key_Code long_character, u8 *character){
 }
 
 internal Input_Process_Result
-do_step_view(System_Functions *system, View *view, i32_Rect rect, b32 is_active, Input_Summary *user_input, GUI_Scroll_Vars vars, i32_Rect region, i32 max_y){
+do_step_file_view(System_Functions *system, View *view, i32_Rect rect, b32 is_active, Input_Summary *user_input, GUI_Scroll_Vars vars, i32_Rect region, i32 max_y){
     Input_Process_Result result = {0};
-    b32 is_file_scroll = false;
+    b32 is_file_scroll = 0;
     
     GUI_Session gui_session = {0};
     GUI_Header *h = 0;
@@ -4381,14 +5684,13 @@ do_step_view(System_Functions *system, View *view, i32_Rect rect, b32 is_active,
     target->active = gui_id_zero();
     
     if (target->push.pos > 0){
-        Editing_File *file = view->file_data.file;
-        i32 line_height = (i32)file->state.metadata.line_height;
-        gui_session_init(&gui_session, target, rect, line_height);
+        gui_session_init(&gui_session, target, rect, view->line_height);
         
         for (h = (GUI_Header*)target->push.base;
              h->type;
              h = NextHeader(h)){
-            interpret_result = gui_interpret(target, &gui_session, h, result.vars, result.region, max_y);
+            interpret_result = gui_interpret(target, &gui_session, h,
+                                             result.vars, result.region, max_y);
             
             if (interpret_result.has_region){
                 result.region = interpret_result.region;
@@ -4597,39 +5899,38 @@ do_step_view(System_Functions *system, View *view, i32_Rect rect, b32 is_active,
     return(result);
 }
 
-internal void
+internal i32
 draw_file_loaded(System_Functions *system, View *view, i32_Rect rect, b32 is_active, Render_Target *target){
-    
-#if 0
     Models *models = view->persistent.models;
-    Style *style = main_style(models);
     Editing_File *file = view->file_data.file;
-    i32 line_height = (i32)file->state.metadata.line_height;
-    
-    Partition *part = &models->mem.part;
-    Temp_Memory temp = begin_temp_memory(part);
-    partition_align(part, 4);
+    Style *style = main_style(models);
+    i32 line_height = view->line_height;
     
     f32 max_x = view_file_display_width(view);
     i32 max_y = rect.y1 - rect.y0 + line_height;
     
-    Assert(file != 0 && !file->is_dummy && buffer_good(&file->state.buffer));
-    Assert(view->edit_pos != 0);
+    Assert(file && !file->is_dummy && buffer_good(&file->state.buffer));
+    Assert(view->edit_pos);
     
-    b32 tokens_use = false;
-    Cpp_Token_Array token_array = {0};
-    if (file != 0){
-        tokens_use = (file->state.tokens_complete && file->state.token_array.count > 0);
+    b32 tokens_use = 0;
+    Cpp_Token_Array token_array = {};
+    if (file){
+        tokens_use = file->state.tokens_complete && (file->state.token_array.count > 0);
         token_array = file->state.token_array;
     }
     
+    Partition *part = &models->mem.part;
+    Temp_Memory temp = begin_temp_memory(part);
+    
+    partition_align(part, 4);
+    
     f32 left_side_space = 0;
     
     i32 max = partition_remaining(part) / sizeof(Buffer_Render_Item);
     Buffer_Render_Item *items = push_array(part, Buffer_Render_Item, max);
     
     Font_ID font_id = file->settings.font_id;
-    Font *font = system->font.get_render_data_by_id(font_id);
+    Render_Font *font = system->font.get_render_data_by_id(font_id);
     
     f32 scroll_x = view->edit_pos->scroll.scroll_x;
     f32 scroll_y = view->edit_pos->scroll.scroll_y;
@@ -4701,7 +6002,7 @@ draw_file_loaded(System_Functions *system, View *view, i32_Rect rect, b32 is_act
                         first_wrap_determination = 0;
                     }
                     else{
-                        Assert(stop.pos == wrap_unit_end);
+                        assert(stop.pos == wrap_unit_end);
                         do_wrap = 1;
                         ++wrap_array_index;
                         wrap_unit_end = file->state.wrap_positions[wrap_array_index];
@@ -4830,7 +6131,8 @@ draw_file_loaded(System_Functions *system, View *view, i32_Rect rect, b32 is_act
     }
     
     end_temp_memory(temp);
-#endif
+    
+    return(0);
 }
 
 internal void
@@ -4869,7 +6171,7 @@ draw_text_with_cursor(System_Functions *system, Render_Target *target, View *vie
         draw_rectangle(target, rect, back_color);
         
         if (pos >= 0 && pos <  s.size){
-            Font *font = system->font.get_render_data_by_id(font_id);
+            Render_Font *font = system->font.get_render_data_by_id(font_id);
             
             String part1 = substr(s, 0, pos);
             String part2 = substr(s, pos, 1);
@@ -4877,15 +6179,12 @@ draw_text_with_cursor(System_Functions *system, Render_Target *target, View *vie
             
             x = draw_string(system, target, font_id, part1, floor32(x), y, text_color);
             
-            Editing_File *file = view->file_data.file;
-            i32 line_height = ceil32(file->state.metadata.line_height);
-            
-            f32 adv = font_touch_and_get_glyph_advance(system, font, s.str[pos]);
+            f32 adv = font_get_glyph_advance(system, font, s.str[pos]);
             i32_Rect cursor_rect;
             cursor_rect.x0 = floor32(x);
             cursor_rect.x1 = floor32(x) + ceil32(adv);
             cursor_rect.y0 = y;
-            cursor_rect.y1 = y + line_height;
+            cursor_rect.y1 = y + view->line_height;
             draw_rectangle(target, cursor_rect, cursor_color);
             x = draw_string(system, target, font_id, part2, floor32(x), y, at_cursor_color);
             
@@ -4899,6 +6198,7 @@ draw_text_with_cursor(System_Functions *system, Render_Target *target, View *vie
 
 internal void
 draw_file_bar(System_Functions *system, Render_Target *target, View *view, Editing_File *file, i32_Rect rect){
+    File_Bar bar;
     Models *models = view->persistent.models;
     Style *style = main_style(models);
     Interactive_Style bar_style = style->main.file_info_style;
@@ -4908,7 +6208,6 @@ draw_file_bar(System_Functions *system, Render_Target *target, View *view, Editi
     u32 pop1_color = bar_style.pop1_color;
     u32 pop2_color = bar_style.pop2_color;
     
-    File_Bar bar = {0};
     bar.rect = rect;
     
     if (target){
@@ -4920,7 +6219,7 @@ draw_file_bar(System_Functions *system, Render_Target *target, View *view, Editi
         
         draw_rectangle(target, bar.rect, back_color);
         
-        Assert(file != 0);
+        Assert(file);
         
         intbar_draw_string(system, target, &bar, file->name.live_name, base_color);
         intbar_draw_string(system, target, &bar, make_lit_string(" -"), base_color);
@@ -4929,14 +6228,12 @@ draw_file_bar(System_Functions *system, Render_Target *target, View *view, Editi
             intbar_draw_string(system, target, &bar, make_lit_string(" loading"), base_color);
         }
         else{
-            Full_Cursor cursor = view_compute_cursor(view, seek_pos(view->edit_pos->cursor), false);
-            
             char bar_space[526];
             String bar_text = make_fixed_width_string(bar_space);
             append_ss        (&bar_text, make_lit_string(" L#"));
-            append_int_to_str(&bar_text, cursor.line);
+            append_int_to_str(&bar_text, view->edit_pos->cursor.line);
             append_ss        (&bar_text, make_lit_string(" C#"));
-            append_int_to_str(&bar_text, cursor.character);
+            append_int_to_str(&bar_text, view->edit_pos->cursor.character);
             
             append_ss(&bar_text, make_lit_string(" -"));
             
@@ -5036,10 +6333,7 @@ draw_fat_option_block(System_Functions *system, GUI_Target *gui_target, Render_T
     u32 text_color = style->main.default_color;
     u32 pop_color = style->main.file_info_style.pop2_color;
     
-    Editing_File *file = view->file_data.file;
-    i32 line_height = ceil32(file->state.metadata.line_height);
-    
-    i32 h = line_height;
+    i32 h = view->line_height;
     i32 x = inner.x0 + 3;
     i32 y = inner.y0 + h/2 - 1;
     
@@ -5078,10 +6372,7 @@ draw_button(System_Functions *system, GUI_Target *gui_target, Render_Target *tar
     u32 back = get_margin_color(active_level, style);
     u32 text_color = style->main.default_color;
     
-    Editing_File *file = view->file_data.file;
-    i32 line_height = ceil32(file->state.metadata.line_height);
-    
-    i32 h = line_height;
+    i32 h = view->line_height;
     i32 y = inner.y0 + h/2 - 1;
     
     i32 w = (i32)font_string_width(system, target, font_id, text);
@@ -5101,7 +6392,7 @@ draw_style_preview(System_Functions *system, GUI_Target *gui_target, Render_Targ
     char font_name_space[256];
     String font_name = make_fixed_width_string(font_name_space);
     font_name.size = system->font.get_name_by_id(font_id, font_name.str, font_name.memory_size);
-    Font *font = system->font.get_render_data_by_id(font_id);
+    Render_Font *font = system->font.get_render_data_by_id(font_id);
     
     i32_Rect inner = get_inner_rect(rect, 3);
     
@@ -5139,9 +6430,11 @@ draw_style_preview(System_Functions *system, GUI_Target *gui_target, Render_Targ
     draw_string(system, target, font_id, "[] () {}; * -> +-/ <>= ! && || % ^", x, y, text_color);
 }
 
-internal void
+internal i32
 do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scroll, View *active, i32_Rect rect, b32 is_active, Render_Target *target, Input_Summary *user_input){
+    
     Editing_File *file = view->file_data.file;
+    i32 result = 0;
     
     GUI_Session gui_session = {0};
     GUI_Header *h = 0;
@@ -5155,9 +6448,7 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol
     
     Font_ID font_id = file->settings.font_id;
     if (gui_target->push.pos > 0){
-        i32 line_height = ceil32(file->state.metadata.line_height);
-        
-        gui_session_init(&gui_session, gui_target, rect, line_height);
+        gui_session_init(&gui_session, gui_target, rect, view->line_height);
         
         v = view_get_scroll_y(view);
         
@@ -5185,7 +6476,7 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol
                     case guicom_file:
                     {
                         if (file_is_ready(file)){
-                            draw_file_loaded(system, view, gui_session.rect, is_active, target);
+                            result = draw_file_loaded(system, view, gui_session.rect, is_active, target);
                         }
                     }break;
                     
@@ -5351,6 +6642,8 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol
         
         draw_pop_clip(target);
     }
+    
+    return(result);
 }
 
 inline void