From c395f8a7356a02bc30c0bbffb72849f1a97049bc Mon Sep 17 00:00:00 2001
From: Allen Webster <yoyo4thdimention@gmail.com>
Date: Thu, 21 Jan 2016 12:48:09 -0500
Subject: [PATCH] adding cl parameters

---
 4coder_custom.cpp                 |  15 ++---
 4coder_helper.h                   |   8 +++
 4ed.cpp                           |  53 ++++++++++-------
 4ed_color_view.cpp                |   1 +
 4ed_command.cpp                   |   4 +-
 4ed_file_view.cpp                 |  30 +++++++---
 4ed_rendering.cpp                 |  60 +++++++++++++------
 4ed_rendering.h                   |   7 ++-
 4ed_rendering_helper.cpp          |  12 +++-
 4ed_system.h                      |   1 +
 buffer/4coder_buffer_abstract.cpp |  68 +++++++++++++++++-----
 buffer/4coder_shared.cpp          |   9 ++-
 vc120.pdb                         | Bin 94208 -> 94208 bytes
 win32_4ed.cpp                     |  92 +++++++++++++++++++-----------
 14 files changed, 247 insertions(+), 113 deletions(-)

diff --git a/4coder_custom.cpp b/4coder_custom.cpp
index 2be30003..262ba8d7 100644
--- a/4coder_custom.cpp
+++ b/4coder_custom.cpp
@@ -8,15 +8,6 @@
 #include "4coder_custom.h"
 #include "4coder_helper.h"
 
-#define exec_command_keep_stack app->exec_command_keep_stack
-#define clear_parameters app->clear_parameters
-#define get_active_buffer app->get_active_buffer
-
-#define exec_command(cmd_context, id)           \
-    exec_command_keep_stack(cmd_context, id);   \
-    clear_parameters(cmd_context)
-#define push_memory(cmd_context, len) app->push_memory(cmd_context, len)
-
 #ifndef literal
 #define literal(s) s, (sizeof(s)-1)
 #endif
@@ -219,7 +210,7 @@ extern "C" GET_BINDING_DATA(get_bindings){
     //
     // If this is not set, it defaults to mapid_global.
     inherit_map(context, mapid_file);
-    
+
     // NOTE(allen|a3.1): Children can override parent's bindings.
     bind(context, codes->right, MDFR_CTRL, cmdid_seek_alphanumeric_or_camel_right);
     bind(context, codes->left, MDFR_CTRL, cmdid_seek_alphanumeric_or_camel_left);
@@ -232,10 +223,12 @@ extern "C" GET_BINDING_DATA(get_bindings){
     bind_me(context, ')', MDFR_NONE, write_and_auto_tab);
     bind_me(context, ']', MDFR_NONE, write_and_auto_tab);
     bind_me(context, ';', MDFR_NONE, write_and_auto_tab);
-    
+
+#if 0
     bind(context, '\t', MDFR_NONE, cmdid_auto_tab_line_at_cursor);
     bind(context, '\t', MDFR_CTRL, cmdid_auto_tab_range);
     bind(context, '\t', MDFR_CTRL | MDFR_SHIFT, cmdid_write_character);
+#endif
     
     end_map(context);
     
diff --git a/4coder_helper.h b/4coder_helper.h
index 85623ceb..42e2ed69 100644
--- a/4coder_helper.h
+++ b/4coder_helper.h
@@ -242,3 +242,11 @@ push_directory(Application_Links *app, void *cmd_context){
 
 #define dir_string(d) ((d).str), ((d).size)
 
+#define exec_command_keep_stack app->exec_command_keep_stack
+#define clear_parameters app->clear_parameters
+#define get_active_buffer app->get_active_buffer
+
+#define exec_command(cmd_context, id)               \
+    exec_command_keep_stack(cmd_context, id);  \
+    clear_parameters(cmd_context)
+
diff --git a/4ed.cpp b/4ed.cpp
index a0335209..9fd1273a 100644
--- a/4ed.cpp
+++ b/4ed.cpp
@@ -393,8 +393,7 @@ COMMAND_DECL(seek_alphanumeric_or_camel_right){
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
 
-    i32 an_pos = buffer_seek_alphanumeric_right(&file->state.buffer, view->cursor.pos);
-    i32 pos = buffer_seek_alphanumeric_or_camel_right(&file->state.buffer, view->cursor.pos, an_pos);
+    i32 pos = buffer_seek_alphanumeric_or_camel_right(&file->state.buffer, view->cursor.pos);
     view_cursor_move(view, pos);
 #endif
 }
@@ -405,8 +404,7 @@ COMMAND_DECL(seek_alphanumeric_or_camel_left){
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
     
-    i32 an_pos = buffer_seek_alphanumeric_left(&file->state.buffer, view->cursor.pos);
-    i32 pos = buffer_seek_alphanumeric_or_camel_left(&file->state.buffer, view->cursor.pos, an_pos);
+    i32 pos = buffer_seek_alphanumeric_or_camel_left(&file->state.buffer, view->cursor.pos);
     view_cursor_move(view, pos);
 #endif
 }
@@ -794,9 +792,9 @@ app_open_file(System_Functions *system, App_Vars *vars, Exchange *exchange,
                 created_file = 1;
                 target_file = file.file;
                 file_get_loading(target_file);
-                table_add(&working_set->table, filename_str, file.index);
                 file_init_strings(target_file);
                 file_set_name(target_file, filename);
+                table_add(&working_set->table, target_file->state.source_path, file.index);
                 
                 app_push_file_binding(vars, file_id, file.index);
             }
@@ -1722,8 +1720,9 @@ build(System_Functions *system, Mem_Options *mem,
         
         if (file){
             file_create_super_locked(system, mem, file, buffer_name, font_set, style->font_id);
+            file->settings.unimportant = 1;
             table_add(&working_set->table, file->state.live_name, index);
-
+            
             if (bind_to_new_view){
                 View *new_view = live_set_alloc_view(live_set, mem);
                 view_replace_major(system, exchange, new_view, panel, live_set);
@@ -2930,6 +2929,24 @@ App_Step_Sig(app_step){
                 if (system->cli_end_update(&proc->cli)){
                     *proc = vars->cli_processes.procs[--count];
                     --i;
+
+                    char str_space[256];
+                    String str = make_fixed_width_string(str_space);
+                    append(&str, "exited with code ");
+                    append_int_to_str(proc->cli.exit, &str);
+                    
+                    Edit_Spec spec = {};
+                    spec.step.type = ED_NORMAL;
+                    spec.step.edit.start = buffer_size(&out_file->state.buffer);
+                    spec.step.edit.end = spec.step.edit.start;
+                    spec.step.edit.len = str.size;
+                    spec.step.pre_pos = new_cursor;
+                    spec.step.post_pos = spec.step.edit.start + str.size;
+                    spec.str = (u8*)str.str;
+                    file_do_single_edit(system, &vars->mem, out_file,
+                                        &vars->layout, spec, hist_normal);
+                    app_result.redraw = 1;
+                    new_cursor = spec.step.post_pos;
                 }
             
                 Panel *panel = vars->layout.panels;
@@ -2938,7 +2955,7 @@ App_Step_Sig(app_step){
                     View *view = panel->view;
                     if (view && view->is_minor) view = view->major;
                     File_View *fview = view_to_file_view(view);
-                    if (fview){
+                    if (fview && fview->file == out_file){
                         view_cursor_move(fview, new_cursor);
                     }
                 }
@@ -3419,20 +3436,10 @@ App_Step_Sig(app_step){
             {
                 Editing_File *file = working_set_lookup_file(working_set, *string);
                 if (file){
-                    switch (buffer_get_sync(file)){
-                    case SYNC_BEHIND_OS:
-                    case SYNC_GOOD:
-                    {
-                        table_remove(&working_set->table, file->state.source_path);
-                        kill_file(system, exchange, general, file, live_set, &vars->layout);
-                        view_remove_minor(system, exchange, panel, live_set);
-                    }break;
-                    
-                    case SYNC_UNSAVED:
-                    {
+                    if (buffer_needs_save(file)){
                         View *new_view = live_set_alloc_view(live_set, mem);
                         view_replace_minor(system, exchange, new_view, panel, live_set);
-                        
+                            
                         new_view->map = &vars->map_ui;
                         Interactive_View *int_view = 
                             interactive_view_init(system, new_view, &vars->hot_directory, style,
@@ -3441,9 +3448,11 @@ App_Step_Sig(app_step){
                         int_view->action = INTV_SURE_TO_KILL;
                         copy(&int_view->query, "Are you sure?");
                         copy(&int_view->dest, file->state.live_name);
-                    }break;
-                    
-                    default: Assert(!"invalid path");
+                    }
+                    else{
+                        table_remove(&working_set->table, file->state.source_path);
+                        kill_file(system, exchange, general, file, live_set, &vars->layout);
+                        view_remove_minor(system, exchange, panel, live_set);
                     }
                 }
             }break;
diff --git a/4ed_color_view.cpp b/4ed_color_view.cpp
index e2c95427..56194c62 100644
--- a/4ed_color_view.cpp
+++ b/4ed_color_view.cpp
@@ -1458,6 +1458,7 @@ do_file_list_box(System_Functions *system, UI_State *state,
             
             append(&full_path, filename);
             terminate_with_null(&full_path);
+            
             Editing_File *file = working_set_contains(state->working_set, full_path);
             full_path.size = restore_size;
             
diff --git a/4ed_command.cpp b/4ed_command.cpp
index 8a378312..6b519872 100644
--- a/4ed_command.cpp
+++ b/4ed_command.cpp
@@ -102,8 +102,8 @@ map_drop(Command_Map *map, u16 event_code, u8 modifiers){
 }
 
 internal void
-map_init(Command_Map *commands, Partition *part, i32 max,
-         Command_Map *parent){
+map_init(Command_Map *commands, Partition *part, i32 max, Command_Map *parent){
+    max = ((max < 6)?(6):(max));
     commands->parent = parent;
     commands->commands = push_array(part, Command_Binding, max);
     memset(commands->commands, 0, max*sizeof(*commands->commands));
diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp
index 9c40a8e2..3499f05c 100644
--- a/4ed_file_view.cpp
+++ b/4ed_file_view.cpp
@@ -93,9 +93,10 @@ struct Editing_File_Settings{
     Font_Set *set;
     i32 base_map_id;
     i32 dos_write_mode;
-    b32 tokens_exist;
-    b32 super_locked;
-    b32 is_initialized;
+    b8 tokens_exist;
+    b8 super_locked;
+    b8 is_initialized;
+    b8 unimportant;
 };
 
 // NOTE(allen): This part of the Editing_File is cleared whenever
@@ -4017,6 +4018,15 @@ buffer_get_sync(Editing_File *file){
     return result;
 }
 
+inline b32
+buffer_needs_save(Editing_File *file){
+    b32 result = 0;
+    if (file->settings.unimportant == 0)
+        if (buffer_get_sync(file) == SYNC_UNSAVED)
+            result = 1;
+    return(result);
+}
+
 internal i32
 draw_file_loaded(View *view_, i32_Rect rect, b32 is_active, Render_Target *target){
     File_View *view = (File_View*)view_;
@@ -4072,11 +4082,12 @@ draw_file_loaded(View *view_, i32_Rect rect, b32 is_active, Render_Target *targe
     Render_Font *font = get_font_info(view->font_set, font_id)->font;
     float *advance_data = 0;
     if (font) advance_data = font->advance_data;
-    
+
     i32 count;
+    Buffer_Render_Options opts = {};
     buffer_get_render_data(&file->state.buffer, view->line_wrap_y, items, max, &count,
                            (f32)rect.x0, (f32)rect.y0, view->scroll_x, view->scroll_y, !view->unwrapped_lines,
-                           (f32)max_x, (f32)max_y, advance_data, (f32)line_height);
+                           (f32)max_x, (f32)max_y, advance_data, (f32)line_height, opts);
     
     Assert(count > 0);
     
@@ -4098,6 +4109,7 @@ draw_file_loaded(View *view_, i32_Rect rect, b32 is_active, Render_Target *targe
     i32 token_i = 0;
     i32 link_i = 0;
     u32 main_color = style->main.default_color;
+    u32 special_color = style->main.special_character_color;
     u32 link_color = 0;
     if (tokens_use){
         Cpp_Get_Token_Result result = cpp_get_token(&token_stack, items->index);
@@ -4141,10 +4153,14 @@ draw_file_loaded(View *view_, i32_Rect rect, b32 is_active, Render_Target *targe
         }
         u32 char_color = main_color;
         
+        if (item->flags & BRFlag_Special_Character) char_color = special_color;
+        
         if (cursor_begin <= ind && ind < cursor_end && (ind != prev_ind || cursor_begin < ind)){
-            if (is_active) draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), cursor_color);
+            if (is_active){
+                draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), cursor_color);
+                char_color = at_cursor_color;
+            }
             else draw_rectangle_outline(target, f32R(item->x0, item->y0, item->x1, item->y1), cursor_color);
-            char_color = at_cursor_color;
         }
         else if (highlight_color){
             draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), highlight_color);
diff --git a/4ed_rendering.cpp b/4ed_rendering.cpp
index 601dd66d..8d1367cd 100644
--- a/4ed_rendering.cpp
+++ b/4ed_rendering.cpp
@@ -34,22 +34,6 @@ draw_set_color(Render_Target *target, u32 color){
     }
 }
 
-internal void
-draw_push_clip(Render_Target *target, i32_Rect clip_box){
-    Assert(target->clip_top == -1 ||
-           fits_inside(clip_box, target->clip_boxes[target->clip_top]));
-    Assert(target->clip_top+1 < ArrayCount(target->clip_boxes));
-    target->clip_boxes[++target->clip_top] = clip_box;
-    draw_set_clip(target, clip_box);
-}
-
-internal void
-draw_pop_clip(Render_Target *target){
-    Assert(target->clip_top > 0);
-    --target->clip_top;
-    draw_set_clip(target, target->clip_boxes[target->clip_top]);
-}
-
 #define PutStruct(s,x) *(s*)(target->push_buffer + target->size) = x; target->size += sizeof(s)
 
 internal void
@@ -79,6 +63,39 @@ draw_push_piece(Render_Target *target, Render_Piece_Combined piece){
     Assert(target->size <= target->max);
 }
 
+internal void
+draw_push_piece_clip(Render_Target *target, i32_Rect clip_box){
+    // TODO(allen): optimize out if there are two clip box changes in a row
+    Render_Piece_Change_Clip clip;
+    Render_Piece_Header header;
+    
+    header.type = piece_type_change_clip;
+    clip.box = clip_box;
+    
+    PutStruct(Render_Piece_Header, header);
+    PutStruct(Render_Piece_Change_Clip, clip);
+}
+
+internal void
+draw_push_clip(Render_Target *target, i32_Rect clip_box){
+    Assert(target->clip_top == -1 ||
+           fits_inside(clip_box, target->clip_boxes[target->clip_top]));
+    Assert(target->clip_top+1 < ArrayCount(target->clip_boxes));
+    target->clip_boxes[++target->clip_top] = clip_box;
+
+    draw_push_piece_clip(target, clip_box);
+}
+
+internal void
+draw_pop_clip(Render_Target *target){
+    i32_Rect clip_box;
+    Assert(target->clip_top > 0);
+    --target->clip_top;
+    clip_box = target->clip_boxes[target->clip_top];
+    
+    draw_push_piece_clip(target, clip_box);
+}
+
 #define ExtractStruct(s) ((s*)cursor); cursor += sizeof(s)
 
 inline void
@@ -148,7 +165,7 @@ private_draw_glyph(Render_Target *target, Render_Font *font,
     
     stbtt_aligned_quad q;
     stbtt_GetPackedQuad(font->chardata, font->tex_width, font->tex_height,
-                        character, &x, &y, &q, 1);
+                        character, &x, &y, &q, 0);
     
     draw_set_color(target, color);
     draw_bind_texture(target, font->tex);
@@ -177,7 +194,7 @@ private_draw_glyph_mono(Render_Target *target, Render_Font *font, u8 character,
     
     stbtt_aligned_quad q;
     stbtt_GetPackedQuad(font->chardata, font->tex_width, font->tex_height,
-                        character, &x, &y, &q, 1);
+                        character, &x, &y, &q, 0);
     
     draw_set_color(target, color);
     draw_bind_texture(target, font->tex);
@@ -263,6 +280,13 @@ launch_rendering(Render_Target *target){
                                         glyph->pos.x, glyph->pos.y,
                                         glyph->advance, glyph->color);
         }break;
+
+        case piece_type_change_clip:
+        {
+            Render_Piece_Change_Clip *clip =
+                ExtractStruct(Render_Piece_Change_Clip);
+            draw_set_clip(target, clip->box);
+        }break;
         }
     }
 }
diff --git a/4ed_rendering.h b/4ed_rendering.h
index cd2b52bb..fefc7488 100644
--- a/4ed_rendering.h
+++ b/4ed_rendering.h
@@ -61,7 +61,8 @@ enum Render_Piece_Type{
     piece_type_gradient,
     piece_type_glyph,
     piece_type_mono_glyph,
-    piece_type_mono_glyph_advance
+    piece_type_mono_glyph_advance,
+    piece_type_change_clip
 };
 
 struct Render_Piece_Header{
@@ -93,6 +94,10 @@ struct Render_Piece_Glyph_Advance{
     u8 character;
 };
 
+struct Render_Piece_Change_Clip{
+    i32_Rect box;
+};
+
 struct Render_Piece_Combined{
     Render_Piece_Header header;
     union{
diff --git a/4ed_rendering_helper.cpp b/4ed_rendering_helper.cpp
index b09dfa29..7858fc44 100644
--- a/4ed_rendering_helper.cpp
+++ b/4ed_rendering_helper.cpp
@@ -22,15 +22,23 @@ draw_pop_clip(Render_Target *target){
 internal void
 begin_render_section(Render_Target *target, System_Functions *system){
     Font_Set *font_set = &target->font_set;
+    system->acquire_lock(RENDER_LOCK);
     font_set->used_this_frame = 0;
     memset(font_set->font_used_flags, 0, font_set->max);
     target->size = 0;
-    system->acquire_lock(RENDER_LOCK);
+    target->clip_top = -1;
+
+    i32_Rect clip;
+    clip.x0 = 0;
+    clip.y0 = 0;
+    clip.x1 = target->width;
+    clip.y1 = target->height;
+    draw_push_clip(target, clip);
 }
 
 internal void
 end_render_section(Render_Target *target, System_Functions *system){
-    //Font_Set *font_set = &target->font_set;
+    Assert(target->clip_top == 0);
     system->release_lock(RENDER_LOCK);
 }
 
diff --git a/4ed_system.h b/4ed_system.h
index 6c0dd5cb..7d63a6ea 100644
--- a/4ed_system.h
+++ b/4ed_system.h
@@ -42,6 +42,7 @@ struct CLI_Handles{
     Plat_Handle out_read;
     Plat_Handle out_write;
     u32 scratch_space[4];
+    i32 exit;
 };
 
 #define Sys_CLI_Call_Sig(name) b32 name(char *path, char *script_name, CLI_Handles *cli_out)
diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp
index cb6ee55f..529f8280 100644
--- a/buffer/4coder_buffer_abstract.cpp
+++ b/buffer/4coder_buffer_abstract.cpp
@@ -253,7 +253,7 @@ buffer_seek_alphanumeric_right(Buffer_Type *buffer, int pos){
         end = loop.size + loop.absolute_pos;
         data = loop.data - loop.absolute_pos;
         for (; pos < end; ++pos){
-            if (!is_alphanumeric_true(data[pos])) goto buffer_seek_alphanumeric_right_mid;
+            if (is_alphanumeric_true(data[pos])) goto buffer_seek_alphanumeric_right_mid;
         }
     }
     
@@ -263,7 +263,7 @@ buffer_seek_alphanumeric_right_mid:
         end = loop.size + loop.absolute_pos;
         data = loop.data - loop.absolute_pos;
         for (; pos < end; ++pos){
-            if (is_alphanumeric_true(data[pos])) goto buffer_seek_alphanumeric_right_end;
+            if (!is_alphanumeric_true(data[pos])) goto buffer_seek_alphanumeric_right_end;
         }
     }
     
@@ -298,11 +298,12 @@ buffer_seek_alphanumeric_left_mid:
             end = loop.absolute_pos;
             data = loop.data - end;
             for (; pos >= end; --pos){
-                if (!is_alphanumeric_true(data[pos])) goto buffer_seek_alphanumeric_left_end;
+                if (!is_alphanumeric_true(data[pos])){
+                    ++pos;
+                    goto buffer_seek_alphanumeric_left_end;
+                }
             }
         }
-        
-        ++pos;
     }
     else{
         pos = 0;
@@ -313,7 +314,7 @@ buffer_seek_alphanumeric_left_end:
 }
 
 internal_4tech int
-buffer_seek_alphanumeric_or_camel_right(Buffer_Type *buffer, int pos, int an_pos){
+buffer_seek_range_camel_right(Buffer_Type *buffer, int pos, int an_pos){
     Buffer_Stringify_Type loop;
     char *data;
     int end, size;
@@ -351,7 +352,7 @@ buffer_seek_alphanumeric_or_camel_right_end:
 }
 
 internal_4tech int
-buffer_seek_alphanumeric_or_camel_left(Buffer_Type *buffer, int pos, int an_pos){
+buffer_seek_range_camel_left(Buffer_Type *buffer, int pos, int an_pos){
     Buffer_Backify_Type loop;
     char *data;
     int end, size;
@@ -382,6 +383,22 @@ buffer_seek_alphanumeric_or_camel_left_end:
     return(pos);
 }
 
+internal_4tech int
+buffer_seek_alphanumeric_or_camel_right(Buffer_Type *buffer, int pos){
+    int an_pos, result;
+    an_pos = buffer_seek_alphanumeric_right(buffer, pos);
+    result = buffer_seek_range_camel_right(buffer, pos, an_pos);
+    return(result);
+}
+
+internal_4tech int
+buffer_seek_alphanumeric_or_camel_left(Buffer_Type *buffer, int pos){
+    int an_pos, result;
+    an_pos = buffer_seek_alphanumeric_left(buffer, pos);
+    result = buffer_seek_range_camel_left(buffer, pos, an_pos);
+    return(result);
+}
+
 internal_4tech int
 buffer_find_hard_start(Buffer_Type *buffer, int line_start, int *all_whitespace,
                        int *all_space, int *preferred_indent, int tab_width){
@@ -1124,10 +1141,15 @@ buffer_invert_batch(Buffer_Invert_Batch *state, Buffer_Type *buffer, Buffer_Edit
     return(result);
 }
 
+struct Buffer_Render_Options{
+    b8 show_slash_t;
+};
+
 internal_4tech void
 buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *items, int max, int *count,
                        float port_x, float port_y, float scroll_x, float scroll_y, int wrapped,
-                       float width, float height, float *advance_data, float font_height){
+                       float width, float height, float *advance_data, float font_height,
+                       Buffer_Render_Options opts){
     Buffer_Stringify_Type loop;
     Full_Cursor start_cursor;
     Buffer_Render_Item *item;
@@ -1180,6 +1202,7 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
                 switch (ch){
                 case '\n':
                     write_render_item_inline(item, i, ' ', x, y, advance_data, font_height);
+                    item->flags = 0;
                     ++item_i;
                     ++item;
                 
@@ -1189,11 +1212,13 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
 
                 case 0:
                     ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, font_height);
+                    item->flags = BRFlag_Special_Character;
                     ++item_i;
                     ++item;
                     x += ch_width;
 
                     ch_width = write_render_item_inline(item, i, '0', x, y, advance_data, font_height);
+                    item->flags = BRFlag_Special_Character;
                     ++item_i;
                     ++item;
                     x += ch_width;
@@ -1201,29 +1226,42 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
 
                 case '\r':
                     ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, font_height);
+                    item->flags = BRFlag_Special_Character;
                     ++item_i;
                     ++item;
                     x += ch_width;
 
                     ch_width = write_render_item_inline(item, i, 'r', x, y, advance_data, font_height);
+                    item->flags = BRFlag_Special_Character;
                     ++item_i;
                     ++item;
                     x += ch_width;
                     break;
 
                 case '\t':
-                    ch_width_sub = write_render_item_inline(item, i, '\\', x, y, advance_data, font_height);
-                    ++item_i;
-                    ++item;
-
-                    write_render_item_inline(item, i, 't', x + ch_width_sub, y, advance_data, font_height);
-                    ++item_i;
-                    ++item;
+                    if (opts.show_slash_t){
+                        ch_width_sub = write_render_item_inline(item, i, '\\', x, y, advance_data, font_height);
+                        item->flags = BRFlag_Special_Character;
+                        ++item_i;
+                        ++item;
+                        
+                        write_render_item_inline(item, i, 't', x + ch_width_sub, y, advance_data, font_height);
+                        item->flags = BRFlag_Special_Character;
+                        ++item_i;
+                        ++item;
+                    }
+                    else{
+                        write_render_item_inline(item, i, ' ', x, y, advance_data, font_height);
+                        item->flags = 0;
+                        ++item_i;
+                        ++item;
+                    }
                     x += ch_width;
                     break;
 
                 default:
                     write_render_item(item, i, ch, x, y, ch_width, font_height);
+                    item->flags = 0;
                     ++item_i;
                     ++item;
                     x += ch_width;
diff --git a/buffer/4coder_shared.cpp b/buffer/4coder_shared.cpp
index 69e688c4..c99e3676 100644
--- a/buffer/4coder_shared.cpp
+++ b/buffer/4coder_shared.cpp
@@ -146,15 +146,18 @@ typedef struct Full_Cursor{
     float wrapped_x, wrapped_y;
 } Full_Cursor;
 
+#define BRFlag_Special_Character (1 << 0)
+
 typedef struct Buffer_Render_Item{
     int index;
-    int glyphid;
+    unsigned short glyphid;
+    unsigned short flags;
     float x0, y0;
     float x1, y1;
 } Buffer_Render_Item;
 
 inline_4tech void
-write_render_item(Buffer_Render_Item *item, int index, int glyphid,
+write_render_item(Buffer_Render_Item *item, int index, unsigned short glyphid,
                   float x, float y, float w, float h){
     item->index = index;
     item->glyphid = glyphid;
@@ -165,7 +168,7 @@ write_render_item(Buffer_Render_Item *item, int index, int glyphid,
 }
 
 inline_4tech float
-write_render_item_inline(Buffer_Render_Item *item, int index, int glyphid,
+write_render_item_inline(Buffer_Render_Item *item, int index, unsigned short glyphid,
                          float x, float y, float *advance_data, float h){
     float ch_width;
     ch_width = measure_character(advance_data, (char)glyphid);
diff --git a/vc120.pdb b/vc120.pdb
index cc1f5af16337abc3de783129a0d9ccbaa898873e..e32ca26cc30e1addb3bf203386c93ab5a3170f81 100644
GIT binary patch
delta 418
zcmZp8z}oPDb%P1FhAT4z!w-gUj0`{kqZ6Qf7|o#Yjd61f_fi%ni<ZrT0`K`JD+us0
zGdTQ)b2b@pC@_gKZRQHFV%_Yrbr0911QA;sIR*wvps^{e3=A$T3=E<`Hjv4{1H>Fa
z%n8I?Kn#>(5CUR;AO^aIfg6Z<HwPxT3s0U<BrtsiGvfrd5Luw0z~+s`hqxCt1Z-in
zU_lYuAh79!4xa!Y1DlwqAOk~{00RS%Vwilu!e??p3&-XOb_I-!4hW#@n{<Fjl^>{(
z1?W<ChX4OTF8Ti-<OT)?8z2XSK`wRKZYaQbp5KuBlp&)9ND^p1k@^f6uk!;#W;>Sy
hBbR_AdXTUI%@P5bH(fV?QJ$3#$Q0Zj7{It*9suc@Q2_t|

delta 382
zcmZp8z}oPDb%P1FhIj%4!w&{^CI%pY(FssKjAl?!XWAUYy_AJ1p?R~Qz<d753Icr0
z3=)6foJ|HC3QRj0H**D8v2OMW-NH37fMZgEh^>ws1A`>c<P=s01_u@f22mgz$YkIH
zVh$kY1Y#~A21+pq0x>@jGXpU%5DRP$OmG+GyW+;ku;wKbL$Mo3Y<r*sV-(M#hJZyI
z6gGX(;hVg{B4%<y3&-XO=T@*XLFA8dPddP($_F&>i!1{JJH!9~Amji42N}%3U;*TS
zFvxm`?S=}B=lM5XuwWrauL0wAexR?nb2%__2}q**l?`Zt2oUp3*9~BlXXOSmg|-I<
IFs_#e0F8M|RsaA1

diff --git a/win32_4ed.cpp b/win32_4ed.cpp
index cdb3d6b0..8d2928e5 100644
--- a/win32_4ed.cpp
+++ b/win32_4ed.cpp
@@ -40,6 +40,7 @@
 
 #define WM_4coder_LOAD_FONT (WM_USER + 1)
 #define WM_4coder_PAINT (WM_USER + 2)
+#define WM_4coder_SET_CURSOR (WM_USER + 3)
 
 struct Thread_Context{
     u32 job_id;
@@ -154,6 +155,9 @@ struct Win32_Vars{
     Win32_Font_Load_Parameters used_font_param;
     Win32_Font_Load_Parameters free_font_param;
     Partition fnt_part;
+
+    char **argv;
+    i32 argc;
 };
 
 globalvar Win32_Vars win32vars;
@@ -506,11 +510,23 @@ Sys_Post_Clipboard_Sig(system_post_clipboard){
 	}
 }
 
+internal
+Sys_Acquire_Lock_Sig(system_acquire_lock){
+    WaitForSingleObject(win32vars.locks[id], INFINITE);
+}
+
+internal
+Sys_Release_Lock_Sig(system_release_lock){
+    ReleaseSemaphore(win32vars.locks[id], 1, 0);
+}
+
 internal void
 Win32RedrawScreen(HDC hdc){
+    system_acquire_lock(RENDER_LOCK);
     launch_rendering(&win32vars.target);
+    system_release_lock(RENDER_LOCK);
     glFlush();
-    //SwapBuffers(hdc);
+    SwapBuffers(hdc);
 }
 
 internal void
@@ -521,6 +537,14 @@ Win32RedrawFromUpdate(){
         0, 0);
 }
 
+internal void
+Win32SetCursorFromUpdate(Application_Mouse_Cursor cursor){
+    SendMessage(
+        win32vars.window_handle,
+        WM_4coder_SET_CURSOR,
+        cursor, 0);
+}
+
 internal void
 Win32Resize(i32 width, i32 height){
     if (width > 0 && height > 0){
@@ -639,16 +663,6 @@ Sys_Post_Job_Sig(system_post_job){
     return result;
 }
 
-internal
-Sys_Acquire_Lock_Sig(system_acquire_lock){
-    WaitForSingleObject(win32vars.locks[id], INFINITE);
-}
-
-internal
-Sys_Release_Lock_Sig(system_release_lock){
-    ReleaseSemaphore(win32vars.locks[id], 1, 0);
-}
-
 internal
 Sys_Cancel_Job_Sig(system_cancel_job){
     Work_Queue *queue = exchange_vars.thread.queues + group_id;
@@ -826,7 +840,15 @@ Sys_CLI_Update_Step_Sig(system_cli_update_step){
 internal
 Sys_CLI_End_Update_Sig(system_cli_end_update){
     b32 close_me = 0;
-    if (WaitForSingleObject(*(HANDLE*)&cli->proc, 0) == WAIT_OBJECT_0){
+    HANDLE proc = *(HANDLE*)&cli->proc;
+    DWORD result = 0;
+    
+    if (WaitForSingleObject(proc, 0) == WAIT_OBJECT_0){
+        if (GetExitCodeProcess(proc, &result) == 0)
+            cli->exit = -1;
+        else
+            cli->exit = (i32)result;
+        
         close_me = 1;
         CloseHandle(*(HANDLE*)&cli->proc);
         CloseHandle(*(HANDLE*)&cli->out_read);
@@ -1219,9 +1241,7 @@ Win32Callback(HWND hwnd, UINT uMsg,
     {
         PAINTSTRUCT ps;
         HDC hdc = BeginPaint(hwnd, &ps);
-        system_acquire_lock(RENDER_LOCK);
         Win32RedrawScreen(hdc);
-        system_release_lock(RENDER_LOCK);
         EndPaint(hwnd, &ps);
         
     }break;
@@ -1230,12 +1250,27 @@ Win32Callback(HWND hwnd, UINT uMsg,
     {
         PAINTSTRUCT ps;
         HDC hdc = BeginPaint(hwnd, &ps);
-        system_acquire_lock(RENDER_LOCK);
         Win32RedrawScreen(hdc);
-        system_release_lock(RENDER_LOCK);
         EndPaint(hwnd, &ps);
     }break;
     
+    case WM_4coder_SET_CURSOR:
+    {
+        switch (wParam){
+        case APP_MOUSE_CURSOR_ARROW:
+            SetCursor(win32vars.cursor_arrow); break;
+            
+        case APP_MOUSE_CURSOR_IBEAM:
+            SetCursor(win32vars.cursor_ibeam); break;
+            
+        case APP_MOUSE_CURSOR_LEFTRIGHT:
+            SetCursor(win32vars.cursor_leftright); break;
+            
+        case APP_MOUSE_CURSOR_UPDOWN:
+            SetCursor(win32vars.cursor_updown); break;
+        }
+    }break;
+    
     case WM_CLOSE: // NOTE(allen): I expect WM_CLOSE not WM_DESTROY
     case WM_DESTROY:
     {
@@ -1363,21 +1398,12 @@ UpdateLoop(LPVOID param){
                                1, win32vars.first, redraw);
     
         ProfileStart(OS_frame_out);
+
+        Win32SetCursorFromUpdate(result.mouse_cursor_type);
+        
+        if (result.redraw) Win32RedrawFromUpdate();
+        
         win32vars.first = 0;
-        switch (result.mouse_cursor_type){
-        case APP_MOUSE_CURSOR_ARROW:
-            SetCursor(win32vars.cursor_arrow); break;
-        case APP_MOUSE_CURSOR_IBEAM:
-            SetCursor(win32vars.cursor_ibeam); break;
-        case APP_MOUSE_CURSOR_LEFTRIGHT:
-            SetCursor(win32vars.cursor_leftright); break;
-        case APP_MOUSE_CURSOR_UPDOWN:
-            SetCursor(win32vars.cursor_updown); break;
-        }
-		
-        if (result.redraw){
-            Win32RedrawFromUpdate();
-        }
         
         ProfileEnd(OS_frame_out);
         
@@ -1457,8 +1483,10 @@ WinMain(HINSTANCE hInstance,
         LPSTR lpCmdLine,
         int nCmdShow){
     win32vars = {};
-    
     exchange_vars = {};
+
+    win32vars.argv = __argv;
+    win32vars.argc = __argc;
     
 #if FRED_INTERNAL
     win32vars.internal_bubble.next = &win32vars.internal_bubble;
@@ -1594,7 +1622,7 @@ WinMain(HINSTANCE hInstance,
     static PIXELFORMATDESCRIPTOR pfd = {
         sizeof(PIXELFORMATDESCRIPTOR),
         1,
-        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
+        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
         PFD_TYPE_RGBA,
         32,
         0, 0, 0, 0, 0, 0,