diff --git a/.gitignore b/.gitignore
index 28b4d0f0..29bd3f0b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
 vc120.pdb
+custom_casey.cpp
diff --git a/4coder_buffer_types.h b/4coder_buffer_types.h
index 1bfa8ba0..ace28eab 100644
--- a/4coder_buffer_types.h
+++ b/4coder_buffer_types.h
@@ -201,6 +201,25 @@ dynamic_to_bool(Dynamic *dynamic){
     return result;
 }
 
+
+typedef struct File_Info{
+    String filename;
+    int folder;
+} File_Info;
+
+typedef struct File_List{
+    // Ignore this, it's for internal stuff.
+    void *block;
+    
+    // The list of files and folders.
+    File_Info *infos;
+    int count;
+    
+    // Ignore this, it's for internal stuff.
+    int block_size;
+} File_List;
+
+
 #endif
 
 // BOTTOM
diff --git a/4coder_custom.cpp b/4coder_custom.cpp
index 52339fa6..b999bdda 100644
--- a/4coder_custom.cpp
+++ b/4coder_custom.cpp
@@ -34,26 +34,6 @@ HOOK_SIG(my_start){
     exec_command(app, cmdid_change_active_panel);
 }
 
-char *get_extension(const char *filename, int len, int *extension_len){
-    char *c = (char*)(filename + len - 1);
-    char *end = c;
-    while (*c != '.' && c > filename) --c;
-    *extension_len = (int)(end - c);
-    return c+1;
-}
-
-bool str_match(const char *a, int len_a, const char *b, int len_b){
-    bool result = 0;
-    if (len_a == len_b){
-        char *end = (char*)(a + len_a);
-        while (a < end && *a == *b){
-            ++a; ++b;
-        }
-        if (a == end) result = 1;
-    }
-    return result;
-}
-
 HOOK_SIG(my_file_settings){
      Buffer_Summary buffer = app->get_active_buffer(app);
      
@@ -64,16 +44,15 @@ HOOK_SIG(my_file_settings){
      //   -The name provided to get_buffer_by_name did not match any of the existing buffers
      if (buffer.exists){
          int treat_as_code = 0;
-
+         
          if (buffer.file_name && buffer.size < (16 << 20)){
-             int extension_len;
-             char *extension = get_extension(buffer.file_name, buffer.file_name_len, &extension_len);
-             if (str_match(extension, extension_len, literal("cpp"))) treat_as_code = 1;
-             else if (str_match(extension, extension_len, literal("h"))) treat_as_code = 1;
-             else if (str_match(extension, extension_len, literal("c"))) treat_as_code = 1;
-             else if (str_match(extension, extension_len, literal("hpp"))) treat_as_code = 1;
+             String ext = file_extension(make_string(buffer.file_name, buffer.file_name_len));
+             if (match(ext, make_lit_string("cpp"))) treat_as_code = 1;
+             else if (match(ext, make_lit_string("h"))) treat_as_code = 1;
+             else if (match(ext, make_lit_string("c"))) treat_as_code = 1;
+             else if (match(ext, make_lit_string("hpp"))) treat_as_code = 1;
          }
-
+         
          push_parameter(app, par_lex_as_cpp_file, treat_as_code);
          push_parameter(app, par_wrap_lines, !treat_as_code);
          push_parameter(app, par_key_mapid, (treat_as_code)?((int)my_code_map):((int)mapid_file));
@@ -290,7 +269,7 @@ CUSTOM_COMMAND_SIG(switch_to_file_in_quotes){
                 app->buffer_read_range(app, &buffer, start, end, short_file_name);
                 
                 copy(&file_name, make_string(buffer.file_name, buffer.file_name_len));
-                truncate_to_path_of_directory(&file_name);
+                remove_last_folder(&file_name);
                 append(&file_name, make_string(short_file_name, size));
 
                 exec_command(app, cmdid_change_active_panel);
@@ -467,8 +446,9 @@ CUSTOM_COMMAND_SIG(replace_in_range){
     pos = range.min;
     app->buffer_seek_string(app, &buffer, pos, r.str, r.size, 1, &new_pos);
     
-    while (new_pos < range.end){
+    while (new_pos + r.size < range.end){
         app->buffer_replace_range(app, &buffer, new_pos, new_pos + r.size, w.str, w.size);
+        range = get_range(&view);
         pos = new_pos + w.size;
         app->buffer_seek_string(app, &buffer, pos, r.str, r.size, 1, &new_pos);
     }
@@ -533,6 +513,26 @@ CUSTOM_COMMAND_SIG(query_replace){
     app->view_set_cursor(app, &view, seek_pos(pos), 1);
 }
 
+CUSTOM_COMMAND_SIG(open_all_cpp_and_h){
+    String dir = push_directory(app);
+    File_List list = app->get_file_list(app, dir.str, dir.size);
+    for (int i = 0; i < list.count; ++i){
+        File_Info *info = list.infos + i;
+        if (!info->folder){
+            String extension = file_extension(info->filename);
+            if (match(extension, make_lit_string("cpp")) ||
+                    match(extension, make_lit_string("hpp")) ||
+                    match(extension, make_lit_string("c")) ||
+                    match(extension, make_lit_string("h"))){
+                push_parameter(app, par_name, info->filename.str, info->filename.size);
+                push_parameter(app, par_do_in_background, 1);
+                exec_command(app, cmdid_interactive_open);
+            }
+        }
+    }
+    app->free_file_list(app, list);
+}
+
 CUSTOM_COMMAND_SIG(open_in_other){
     exec_command(app, cmdid_change_active_panel);
     exec_command(app, cmdid_interactive_open);
@@ -570,7 +570,7 @@ CUSTOM_COMMAND_SIG(build_at_launch_location){
     push_parameter(app, par_name, literal("*compilation*"));
     push_parameter(app, par_cli_path, literal("."));
     push_parameter(app, par_cli_command, literal("build"));
-    exec_command(app, cmdid_build);
+    exec_command(app, cmdid_command_line);
 }
 
 CUSTOM_COMMAND_SIG(build_search){
@@ -602,18 +602,26 @@ CUSTOM_COMMAND_SIG(build_search){
     // Step 3: If the batch file did not exist try to move to the parent directory using
     // app->directory_cd. The cd function can also be used to navigate to subdirectories.
     // It returns true if it can actually move in the specified direction, and false otherwise.
+    // This doesn't actually change the hot directory of 4coder, it's only effect is to
+    // modify the string you passed in to reflect the change in directory.
     
     int keep_going = 1;
+    int old_size;
     String dir = push_directory(app);
     while (keep_going){
-        if (app->directory_has_file(app, dir, "build.bat")){
+        old_size = dir.size;
+        append(&dir, "build.bat");
+        
+        if (app->file_exists(app, dir.str, dir.size)){
+            dir.size = old_size;
+            
             push_parameter(app, par_cli_overlap_with_conflict, 0);
             push_parameter(app, par_name, literal("*compilation*"));
             push_parameter(app, par_cli_path, dir.str, dir.size);
             
             if (append(&dir, "build")){
                 push_parameter(app, par_cli_command, dir.str, dir.size);
-                exec_command(app, cmdid_build);
+                exec_command(app, cmdid_command_line);
             }
             else{
                 app->clear_parameters(app);
@@ -621,8 +629,9 @@ CUSTOM_COMMAND_SIG(build_search){
             
             return;
         }
+        dir.size = old_size;
 
-        if (app->directory_cd(app, &dir, "..") == 0){
+        if (app->directory_cd(app, dir.str, &dir.size, dir.memory_size, literal("..")) == 0){
             keep_going = 0;
         }
     }
@@ -638,7 +647,7 @@ CUSTOM_COMMAND_SIG(write_and_auto_tab){
 extern "C" GET_BINDING_DATA(get_bindings){
     Bind_Helper context_actual = begin_bind_helper(data, size);
     Bind_Helper *context = &context_actual;
-
+    
     // NOTE(allen|a3.1): Right now hooks have no loyalties to maps, all hooks are
     // global and once set they always apply, regardless of what map is active.
     set_hook(context, hook_start, my_start);
@@ -658,11 +667,14 @@ extern "C" GET_BINDING_DATA(get_bindings){
     bind(context, 'x', MDFR_ALT, cmdid_open_menu);
     bind(context, 'o', MDFR_ALT, open_in_other);
     
+    bind(context, 'm', MDFR_ALT, build_search);
+    bind(context, 'a', MDFR_ALT, open_all_cpp_and_h);
+    
     // NOTE(allen): These callbacks may not actually be useful to you, but
     // go look at them and see what they do.
     bind(context, 'M', MDFR_ALT | MDFR_CTRL, open_my_files);
     bind(context, 'M', MDFR_ALT, build_at_launch_location);
-    bind(context, 'm', MDFR_ALT, build_search);
+    
 
     end_map(context);
 
@@ -693,9 +705,6 @@ extern "C" GET_BINDING_DATA(get_bindings){
     bind(context, '\t', MDFR_NONE, cmdid_word_complete);
     bind(context, '\t', MDFR_CTRL, cmdid_auto_tab_range);
     bind(context, '\t', MDFR_SHIFT, cmdid_auto_tab_line_at_cursor);
-
-    bind(context, '\n', MDFR_SHIFT, write_and_auto_tab);
-    bind(context, ' ', MDFR_SHIFT, cmdid_write_character);
     
     bind(context, '=', MDFR_CTRL, write_increment);
     bind(context, '-', MDFR_CTRL, write_decrement);
@@ -773,7 +782,11 @@ extern "C" GET_BINDING_DATA(get_bindings){
     
     bind(context, ',', MDFR_ALT, switch_to_compilation);
     
+    bind(context, '\n', MDFR_SHIFT, write_and_auto_tab);
+    bind(context, ' ', MDFR_SHIFT, cmdid_write_character);
+    
     end_map(context);
+    
     end_bind_helper(context);
     
     return context->write_total;
diff --git a/4coder_custom.h b/4coder_custom.h
index 68283a13..27dc7d90 100644
--- a/4coder_custom.h
+++ b/4coder_custom.h
@@ -22,10 +22,7 @@ enum Command_ID{
     cmdid_seek_alphanumeric_right,
     cmdid_seek_alphanumeric_or_camel_left,
     cmdid_seek_alphanumeric_or_camel_right,
-    //cmdid_search,
-    //cmdid_reverse_search,
     cmdid_word_complete,
-    //cmdid_goto_line,
     cmdid_set_mark,
     cmdid_copy,
     cmdid_cut,
@@ -75,7 +72,7 @@ enum Command_ID{
     cmdid_cursor_mark_swap,
     cmdid_open_menu,
     cmdid_set_settings,
-    cmdid_build,
+    cmdid_command_line,
     //
     cmdid_count
 };
@@ -84,6 +81,8 @@ enum Param_ID{
     par_range_start,
     par_range_end,
     par_name,
+    par_buffer_id,
+    par_do_in_background,
     par_lex_as_cpp_file,
     par_wrap_lines,
     par_key_mapid,
@@ -156,7 +155,6 @@ struct Query_Bar{
 };
 
 #define GET_BINDING_DATA(name) int name(void *data, int size)
-#define SET_EXTRA_FONT_SIG(name) void name(Extra_Font *font_out)
 #define CUSTOM_COMMAND_SIG(name) void name(struct Application_Links *app)
 #define HOOK_SIG(name) void name(struct Application_Links *app)
 
@@ -175,9 +173,11 @@ struct Application_Links;
 #define CLEAR_PARAMETERS_SIG(name) void name(Application_Links *context)
 
 // File system navigation
-#define DIRECTORY_GET_HOT_SIG(name) int name(Application_Links *context, char *buffer, int max)
-#define DIRECTORY_HAS_FILE_SIG(name) int name(Application_Links *context, String dir, char *filename)
-#define DIRECTORY_CD_SIG(name) int name(Application_Links *context, String *dir, char *rel_path)
+#define DIRECTORY_GET_HOT_SIG(name) int name(Application_Links *context, char *out, int capacity)
+#define FILE_EXISTS_SIG(name) int name(Application_Links *context, char *filename, int len)
+#define DIRECTORY_CD_SIG(name) int name(Application_Links *context, char *dir, int *len, int capacity, char *rel_path, int rel_len)
+#define GET_FILE_LIST_SIG(name) File_List name(Application_Links *context, char *dir, int len)
+#define FREE_FILE_LIST_SIG(name) void name(Application_Links *context, File_List list)
 
 // Direct buffer manipulation
 #define GET_BUFFER_MAX_INDEX_SIG(name) int name(Application_Links *context)
@@ -190,7 +190,6 @@ struct Application_Links;
 #define BUFFER_SEEK_STRING_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, char *str, int len, int seek_forward, int *out)
 #define BUFFER_READ_RANGE_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, int end, char *out)
 #define BUFFER_REPLACE_RANGE_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, int end, char *str, int len)
-#define BUFFER_SAVE_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, char *filename, int len)
 
 // File view manipulation
 #define GET_VIEW_MAX_INDEX_SIG(name) int name(Application_Links *context)
@@ -216,9 +215,6 @@ struct Application_Links;
 #define GET_USER_INPUT_SIG(name) User_Input name(Application_Links *context, unsigned int get_type, unsigned int abort_type)
 
 // Queries
-#define QueryEffectImmediate 0x0
-#define QueryEffectSmooth 0x1
-
 #define START_QUERY_BAR_SIG(name) int name(Application_Links *context, Query_Bar *bar, unsigned int flags)
 #define END_QUERY_BAR_SIG(name) void name(Application_Links *context, Query_Bar *bar, unsigned int flags)
 
@@ -230,9 +226,11 @@ extern "C"{
     typedef CLEAR_PARAMETERS_SIG(Clear_Parameters_Function);
     
     // File system navigation
-    typedef DIRECTORY_GET_HOT_SIG(Directory_Get_Hot);
-    typedef DIRECTORY_HAS_FILE_SIG(Directory_Has_File);
-    typedef DIRECTORY_CD_SIG(Directory_CD);
+    typedef DIRECTORY_GET_HOT_SIG(Directory_Get_Hot_Function);
+    typedef FILE_EXISTS_SIG(File_Exists_Function);
+    typedef DIRECTORY_CD_SIG(Directory_CD_Function);
+    typedef GET_FILE_LIST_SIG(Get_File_List_Function);
+    typedef FREE_FILE_LIST_SIG(Free_File_List_Function);
     
     // Buffer manipulation
     typedef GET_BUFFER_MAX_INDEX_SIG(Get_Buffer_Max_Index_Function);
@@ -245,7 +243,6 @@ extern "C"{
     typedef BUFFER_SEEK_STRING_SIG(Buffer_Seek_String_Function);
     typedef BUFFER_READ_RANGE_SIG(Buffer_Read_Range_Function);
     typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function);
-    typedef BUFFER_SAVE_SIG(Buffer_Save_Function);
     
     // View manipulation
     typedef GET_VIEW_MAX_INDEX_SIG(Get_View_Max_Index_Function);
@@ -267,8 +264,9 @@ extern "C"{
 }
 
 struct Application_Links{
-    // Application data ptr
+    // User data
     void *data;
+    int size;
     
     // Command exectuion
     Exec_Command_Function *exec_command_keep_stack;
@@ -277,9 +275,11 @@ struct Application_Links{
     Clear_Parameters_Function *clear_parameters;
     
     // File system navigation
-    Directory_Get_Hot *directory_get_hot;
-    Directory_Has_File *directory_has_file;
-    Directory_CD *directory_cd;
+    Directory_Get_Hot_Function *directory_get_hot;
+    File_Exists_Function *file_exists;
+    Directory_CD_Function *directory_cd;
+    Get_File_List_Function *get_file_list;
+    Free_File_List_Function *free_file_list;
     
     // Buffer manipulation
     Get_Buffer_Max_Index_Function *get_buffer_max_index;
@@ -292,7 +292,6 @@ struct Application_Links{
     Buffer_Seek_String_Function *buffer_seek_string;
     Buffer_Read_Range_Function *buffer_read_range;
     Buffer_Replace_Range_Function *buffer_replace_range;
-    Buffer_Save_Function *buffer_save;
     
     // View manipulation
     Get_View_Max_Index_Function *get_view_max_index;
@@ -311,6 +310,9 @@ struct Application_Links{
     // Queries
     Start_Query_Bar_Function *start_query_bar;
     End_Query_Bar_Function *end_query_bar;
+    
+    // Internal
+    void *cmd_context;
 };
 
 struct Custom_API{
diff --git a/4coder_string.h b/4coder_string.h
index f2724562..3fae8d3d 100644
--- a/4coder_string.h
+++ b/4coder_string.h
@@ -175,12 +175,13 @@ FCPP_LINK int    reverse_seek_slash(String str);
 FCPP_LINK int    reverse_seek_slash(String str, int start_pos);
 inline    bool   get_front_of_directory(String *dest, String dir) { return append_checked(dest, substr(dir, reverse_seek_slash(dir) + 1)); }
 inline    bool   get_path_of_directory(String *dest, String dir) { return append_checked(dest, substr(dir, 0, reverse_seek_slash(dir) + 1)); }
-inline    void   truncate_to_path_of_directory(String *dir) { dir->size = reverse_seek_slash(*dir) + 1; }
 FCPP_LINK bool   set_last_folder(String *dir, char *folder_name, char slash);
 FCPP_LINK bool   set_last_folder(String *dir, String folder_name, char slash);
 FCPP_LINK String file_extension(String str);
 FCPP_LINK String file_extension_slowly(char *str);
+FCPP_LINK char * file_extension_c(String str);
 FCPP_LINK bool   remove_last_folder(String *str);
+FCPP_LINK void   replace_char(String str, char replace, char with);
 
 inline String make_string(char *str, int size, int mem_size){
     String result;
@@ -1043,6 +1044,16 @@ file_extension_slowly(char *str){
     return make_string(str+i, s-i);
 }
 
+FCPP_LINK char*
+file_extension_c(String str){
+    int i;
+    for (i = str.size - 1; i >= 0; --i){
+        if (str.str[i] == '.') break;
+    }
+    ++i;
+    return str.str+i;
+}
+
 FCPP_LINK bool
 remove_last_folder(String *str){
     bool result = 0;
@@ -1054,11 +1065,21 @@ remove_last_folder(String *str){
     return(result);
 }
 
+FCPP_LINK void
+replace_char(String str, char replace, char with){
+    char *s = str.str;
+    int i;
+    
+    for (i = 0; i < str.size; ++i, ++s){
+        if (*s == replace) *s = with;
+    }
+}
+
 // NOTE(allen): experimental section, things below here are
 // not promoted to public API level yet.
 
 #ifndef ArrayCount
-#define ArrayCount(a) ((sizeof(a))/sizeof(a))
+#define ArrayCount(a) ((sizeof(a))/sizeof(*a))
 #endif
 
 struct Absolutes{
diff --git a/4ed.cpp b/4ed.cpp
index 4c651814..95c40043 100644
--- a/4ed.cpp
+++ b/4ed.cpp
@@ -33,9 +33,16 @@ struct CLI_List{
     i32 count, max;
 };
 
+#define SysAppCreateView 0x1
+#define SysAppCreateNewBuffer 0x2
+
 struct Sys_App_Binding{
     i32 sys_id;
     i32 app_id;
+    
+    u32 success;
+    u32 fail;
+    Panel *panel;
 };
 
 struct Complete_State{
@@ -60,10 +67,10 @@ struct Command_Data{
     Exchange *exchange;
     System_Functions *system;
     Coroutine *current_coroutine;
-    
+
     i32 screen_width, screen_height;
     Key_Event_Data key;
-    
+
     Partition part;
 };
 
@@ -71,7 +78,7 @@ struct App_Vars{
     Mem_Options mem;
 
     App_Settings settings;
-    
+
     Command_Map map_top;
     Command_Map map_file;
     Command_Map map_ui;
@@ -82,22 +89,22 @@ struct App_Vars{
     i32 *map_id_table;
     i32 user_map_count;
     Command_Binding prev_command;
-    
+
     Coroutine *command_coroutine;
     u32 command_coroutine_flags[2];
-    
+
     Sys_App_Binding *sys_app_bindings;
     i32 sys_app_count, sys_app_max;
-    
+
     Custom_Command_Function *hooks[hook_type_count];
-    
+
     Font_Set *font_set;
-    
+
     Style style;
     Style_Library styles;
     u32 *palette;
     i32 palette_size;
-    
+
     Editing_Layout layout;
     Live_Views live_set;
     Working_Set working_set;
@@ -106,19 +113,19 @@ struct App_Vars{
     Hot_Directory hot_directory;
 
     CLI_List cli_processes;
-    
-    Delay delay;
+
+    Delay delay1, delay2;
 
     String mini_str;
     u8 mini_buffer[512];
-    
+
     App_State state;
     App_State_Resizing resizing;
     Complete_State complete_state;
     Panel *prev_mouse_panel;
-    
+
     Command_Data command_data;
-    
+
     Custom_API config_api;
 };
 
@@ -168,6 +175,8 @@ globalvar Application_Links app_links;
 #define USE_MEM(n) Mem_Options *n = command->mem
 #define USE_PANEL(n) Panel *n = command->panel
 #define USE_VIEW(n) View *n = command->view
+#define USE_FILE_VIEW(n) File_View *n = view_to_file_view(command->view)
+#define USE_FILE(n,v) Editing_File *n = 0; if (v) { (n) = (v)->file; }
 #define USE_WORKING_SET(n) Working_Set *n = command->working_set
 #define USE_LAYOUT(n) Editing_Layout *n = command->layout
 #define USE_LIVE_SET(n) Live_Views *live_set = command->live_set
@@ -240,7 +249,7 @@ COMMAND_DECL(write_character){
     REQ_FILE(file, view);
     USE_LAYOUT(layout);
     USE_MEM(mem);
-    
+
     char character;
     i32 pos, next_cursor_pos;
 
@@ -258,7 +267,7 @@ COMMAND_DECL(seek_whitespace_right){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     i32 pos = buffer_seek_whitespace_right(&file->state.buffer, view->cursor.pos);
     view_cursor_move(view, pos);
 }
@@ -267,7 +276,7 @@ COMMAND_DECL(seek_whitespace_left){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     i32 pos = buffer_seek_whitespace_left(&file->state.buffer, view->cursor.pos);
     view_cursor_move(view, pos);
 }
@@ -276,7 +285,7 @@ COMMAND_DECL(seek_whitespace_up){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     i32 pos = buffer_seek_whitespace_up(&file->state.buffer, view->cursor.pos);
     view_cursor_move(view, pos);
 }
@@ -285,7 +294,7 @@ COMMAND_DECL(seek_whitespace_down){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-        
+
     i32 pos = buffer_seek_whitespace_down(&file->state.buffer, view->cursor.pos);
     view_cursor_move(view, pos);
 }
@@ -296,12 +305,12 @@ seek_token_left(Cpp_Token_Stack *tokens, i32 pos){
     if (get.token_index == -1){
         get.token_index = 0;
     }
-    
+
     Cpp_Token *token = tokens->tokens + get.token_index;
     if (token->start == pos && get.token_index > 0){
         --token;
     }
-    
+
     return token->start;
 }
 
@@ -314,7 +323,7 @@ seek_token_right(Cpp_Token_Stack *tokens, i32 pos){
     if (get.token_index >= tokens->count){
         get.token_index = tokens->count-1;
     }
-    
+
     Cpp_Token *token = tokens->tokens + get.token_index;
     return token->start + token->size;
 }
@@ -323,7 +332,7 @@ COMMAND_DECL(seek_token_left){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     if (file->state.tokens_complete){
         i32 pos = seek_token_left(&file->state.token_stack, view->cursor.pos);
         view_cursor_move(view, pos);
@@ -334,7 +343,7 @@ COMMAND_DECL(seek_token_right){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     if (file->state.tokens_complete){
         i32 pos = seek_token_right(&file->state.token_stack, view->cursor.pos);
         view_cursor_move(view, pos);
@@ -345,7 +354,7 @@ COMMAND_DECL(seek_white_or_token_right){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     i32 token_pos, white_pos;
     if (file->state.tokens_complete){
         token_pos = seek_token_right(&file->state.token_stack, view->cursor.pos);
@@ -361,7 +370,7 @@ COMMAND_DECL(seek_white_or_token_left){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     i32 token_pos, white_pos;
     if (file->state.tokens_complete){
         token_pos = seek_token_left(&file->state.token_stack, view->cursor.pos);
@@ -377,7 +386,7 @@ COMMAND_DECL(seek_alphanumeric_right){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     i32 pos = buffer_seek_alphanumeric_right(&file->state.buffer, view->cursor.pos);
     view_cursor_move(view, pos);
 }
@@ -386,7 +395,7 @@ COMMAND_DECL(seek_alphanumeric_left){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     i32 pos = buffer_seek_alphanumeric_left(&file->state.buffer, view->cursor.pos);
     view_cursor_move(view, pos);
 }
@@ -404,7 +413,7 @@ COMMAND_DECL(seek_alphanumeric_or_camel_left){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     i32 pos = buffer_seek_alphanumeric_or_camel_left(&file->state.buffer, view->cursor.pos);
     view_cursor_move(view, pos);
 }
@@ -417,39 +426,40 @@ COMMAND_DECL(word_complete){
     USE_MEM(mem);
     USE_VARS(vars);
     USE_WORKING_SET(working_set);
-    
+
     Partition *part = &mem->part;
     General_Memory *general = &mem->general;
     Complete_State *complete_state = &vars->complete_state;
     Search_Range *ranges;
     Search_Match match;
-    
+
     Temp_Memory temp;
-    
+
     Buffer_Type *buffer;
     Buffer_Backify_Type loop;
     char *data;
     i32 end;
     i32 size_of_buffer;
-    
+
     i32 cursor_pos, word_start, word_end;
     char c;
-    
+
     char *spare;
     i32 size;
-    
+
     i32 buffer_count, i, j;
     Editing_File *file_ptr;
-    
+
     i32 match_size;
     b32 do_init = 0;
-    
+
     buffer = &file->state.buffer;
     size_of_buffer = buffer_size(buffer);
     
-    if (vars->prev_command.function != command_word_complete){
+    if (view->mode.rewrite != 2){
         do_init = 1;
     }
+    view->next_mode.rewrite = 2;
     
     if (complete_state->initialized == 0){
         do_init = 1;
@@ -477,30 +487,30 @@ COMMAND_DECL(word_complete){
             }
         }
         double_break:;
-        
+
         size = word_end - word_start;
-        
+
         if (size == 0){
             complete_state->initialized = 0;
             return;
         }
-        
+
         complete_state->initialized = 1;
         search_iter_init(general, &complete_state->iter, size);
         buffer_stringify(buffer, word_start, word_end, complete_state->iter.word.str);
         complete_state->iter.word.size = size;
-        
+
         buffer_count = working_set->file_index_count;
         search_set_init(general, &complete_state->set, buffer_count + 1);
         ranges = complete_state->set.ranges;
         ranges[0].buffer = buffer;
         ranges[0].start = 0;
         ranges[0].size = word_start;
-        
+
         ranges[1].buffer = buffer;
         ranges[1].start = word_end;
         ranges[1].size = size_of_buffer - word_end;
-        
+
         file_ptr = working_set->files;
         for (i = 0, j = 2; i < buffer_count; ++i, ++file_ptr){
             if (file_ptr != file && !file_ptr->state.is_dummy){
@@ -511,11 +521,11 @@ COMMAND_DECL(word_complete){
             }
         }
         complete_state->set.count = j;
-        
+
         search_hits_init(general, &complete_state->hits, &complete_state->str, 100, Kbytes(4));
         search_hit_add(general, &complete_state->hits, &complete_state->str,
             complete_state->iter.word.str, complete_state->iter.word.size);
-        
+
         complete_state->word_start = word_start;
         complete_state->word_end = word_end;
     }
@@ -568,7 +578,7 @@ COMMAND_DECL(set_mark){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     view->mark = (i32)view->cursor.pos;
 }
 
@@ -578,11 +588,11 @@ COMMAND_DECL(copy){
     REQ_FILE(file, view);
     USE_WORKING_SET(working_set);
     USE_MEM(mem);
-    
+
     // TODO(allen): deduplicate
     int r_start = 0, r_end = 0;
     int start_set = 0, end_set = 0;
-    
+
     Command_Parameter *end = param_stack_end(&command->part);
     Command_Parameter *param = param_stack_first(&command->part, end);
     for (; param < end; param = param_next(param, end)){
@@ -592,7 +602,7 @@ COMMAND_DECL(copy){
             start_set = 1;
             r_start = dynamic_to_int(&param->param.value);
             break;
-            
+
             case par_range_end:
             end_set = 1;
             r_end = dynamic_to_int(&param->param.value);
@@ -615,11 +625,11 @@ COMMAND_DECL(cut){
     USE_WORKING_SET(working_set);
     USE_LAYOUT(layout);
     USE_MEM(mem);
-    
+
     // TODO(allen): deduplicate
     int r_start = 0, r_end = 0;
     int start_set = 0, end_set = 0;
-    
+
     Command_Parameter *end = param_stack_end(&command->part);
     Command_Parameter *param = param_stack_first(&command->part, end);
     for (; param < end; param = param_next(param, end)){
@@ -629,7 +639,7 @@ COMMAND_DECL(cut){
             start_set = 1;
             r_start = dynamic_to_int(&param->param.value);
             break;
-            
+
             case par_range_end:
             end_set = 1;
             r_end = dynamic_to_int(&param->param.value);
@@ -645,7 +655,7 @@ COMMAND_DECL(cut){
 
         clipboard_copy(system, &mem->general, working_set, range, file);
         view_replace_range(system, mem, view, layout, range.start, range.end, 0, 0, next_cursor_pos);
-        
+
         view->mark = range.start;
         view_cursor_move(view, next_cursor_pos);
     }
@@ -658,34 +668,34 @@ COMMAND_DECL(paste){
     USE_WORKING_SET(working_set);
     USE_LAYOUT(layout);
     USE_MEM(mem);
-    
+
     Panel *current_panel;
     String *src;
     File_View *current_view;
     i32 pos_left, next_cursor_pos;
     i32 panel_count;
     i32 i;
-    
+
     if (working_set->clipboard_size > 0){
         view->next_mode.rewrite = 1;
-        
+
         src = working_set_clipboard_head(working_set);
         pos_left = view->cursor.pos;
 
         next_cursor_pos = pos_left+src->size;
         view_replace_range(system, mem, view, layout, pos_left, pos_left, src->str, src->size, next_cursor_pos);
-        
+
         view_cursor_move(view, next_cursor_pos);
         view->mark = pos_left;
-        
+
         current_panel = layout->panels;
         panel_count = layout->panel_count;
         for (i = 0; i < panel_count; ++i, ++current_panel){
             current_view = view_to_file_view(current_panel->view);
-            
+
             if (current_view && current_view->file == file){
                 view_post_paste_effect(current_view, 20, pos_left, src->size,
-                                       current_view->style->main.paste_color);
+                    current_view->style->main.paste_color);
             }
         }
     }
@@ -698,30 +708,30 @@ COMMAND_DECL(paste_next){
     USE_WORKING_SET(working_set);
     USE_LAYOUT(layout);
     USE_MEM(mem);
-    
-    if (working_set->clipboard_size > 0 && view->mode.rewrite){
+
+    if (working_set->clipboard_size > 0 && view->mode.rewrite == 1){
         view->next_mode.rewrite = 1;
-        
+
         Range range = make_range(view->mark, view->cursor.pos);
         String *src = working_set_clipboard_roll_down(working_set);
         i32 next_cursor_pos = range.start+src->size;
         view_replace_range(system,
-                           mem, view, layout, range.start, range.end,
-                           src->str, src->size, next_cursor_pos);
-        
+            mem, view, layout, range.start, range.end,
+            src->str, src->size, next_cursor_pos);
+
         view_cursor_move(view, next_cursor_pos);
         view->mark = range.start;
-        
+
         Editing_Layout *layout = command->layout;
         Panel *panels = layout->panels;
         i32 panel_count = layout->panel_count;
         for (i32 i = 0; i < panel_count; ++i){
             Panel *current_panel = panels + i;
             File_View *current_view = view_to_file_view(current_panel->view);
-                
+
             if (current_view && current_view->file == file){
                 view_post_paste_effect(current_view, 20, range.start, src->size,
-                                       current_view->style->main.paste_color);
+                    current_view->style->main.paste_color);
             }
         }
     }
@@ -736,12 +746,12 @@ COMMAND_DECL(delete_range){
     REQ_FILE(file, view);
     USE_LAYOUT(layout);
     USE_MEM(mem);
-    
+
     Range range = make_range(view->cursor.pos, view->mark);
     if (range.start < range.end){
         i32 next_cursor_pos = range.start;
         view_replace_range(system, mem, view, layout, range.start, range.end,
-                           0, 0, next_cursor_pos);
+            0, 0, next_cursor_pos);
         view_cursor_move(view, next_cursor_pos);
         view->mark = range.start;
     }
@@ -751,7 +761,7 @@ COMMAND_DECL(timeline_scrub){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE_HISTORY(file, view);
-    
+
     view_set_widget(view, FWIDG_TIMELINES);
     view->widget.timeline.undo_line = 1;
     view->widget.timeline.history_line = 1;
@@ -763,7 +773,7 @@ COMMAND_DECL(undo){
     REQ_FILE_HISTORY(file, view);
     USE_LAYOUT(layout);
     USE_MEM(mem);
-    
+
     view_undo(system, mem, layout, view);
 }
 
@@ -773,7 +783,7 @@ COMMAND_DECL(redo){
     REQ_FILE_HISTORY(file, view);
     USE_LAYOUT(layout);
     USE_MEM(mem);
-    
+
     view_redo(system, mem, layout, view);
 }
 
@@ -783,7 +793,7 @@ COMMAND_DECL(history_backward){
     REQ_FILE_HISTORY(file, view);
     USE_LAYOUT(layout);
     USE_MEM(mem);
-    
+
     view_history_step(system, mem, layout, view, hist_backward);
 }
 
@@ -793,7 +803,7 @@ COMMAND_DECL(history_forward){
     REQ_FILE_HISTORY(file, view);
     USE_LAYOUT(layout);
     USE_MEM(mem);
-    
+
     view_history_step(system, mem, layout, view, hist_forward);
 }
 
@@ -803,7 +813,7 @@ COMMAND_DECL(save_history){
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
     USE_MEM(mem);
-    
+
     file_dump_history(system, mem, file, "history_data.hst");
 }
 #endif
@@ -819,31 +829,34 @@ COMMAND_DECL(interactive_new){
     USE_DELAY(delay);
     USE_EXCHANGE(exchange);
     USE_FONT_SET(font_set);
-    
+
     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, working_set,
-                              font_set, delay);
+        style, working_set,
+        font_set, delay);
     int_view->interaction = INTV_SYS_FILE_LIST;
     int_view->action = INTV_NEW;
     copy(&int_view->query, "New: ");
 }
 
-internal void
+internal Sys_App_Binding*
 app_push_file_binding(App_Vars *vars, int sys_id, int app_id){
-    Sys_App_Binding binding;
+    Sys_App_Binding *binding;
     Assert(vars->sys_app_count < vars->sys_app_max);
-    binding.sys_id = sys_id;
-    binding.app_id = app_id;
-    vars->sys_app_bindings[vars->sys_app_count++] = binding;
+    binding = vars->sys_app_bindings + vars->sys_app_count++;
+    binding->sys_id = sys_id;
+    binding->app_id = app_id;
+    return(binding);
 }
 
 struct App_Open_File_Result{
     Editing_File *file;
+    i32 sys_id;
+    i32 file_index;
     b32 is_new;
 };
 
@@ -852,68 +865,29 @@ app_open_file_background(App_Vars *vars, Exchange *exchange, Working_Set *workin
     Get_File_Result file;
     i32 file_id;
     App_Open_File_Result result = {};
-    
+
     result.file = working_set_contains(working_set, filename);
     if (result.file == 0){
+        result.is_new = 1;
         file = working_set_get_available_file(working_set);
         if (file.file){
+            result.file = file.file;
             file_id = exchange_request_file(exchange, filename.str, filename.size);
             if (file_id){
-                result.is_new = 1;
-                result.file = file.file;
                 file_init_strings(result.file);
                 file_set_name(working_set, result.file, filename.str);
                 file_set_to_loading(result.file);
                 table_add(&working_set->table, result.file->name.source_path, file.index);
                 
-                app_push_file_binding(vars, file_id, file.index);
+                result.sys_id = file_id;
+                result.file_index = file.index;
             }
             else{
                 file_get_dummy(file.file);
             }
         }
     }
-    
-    return(result);
-}
 
-internal File_View*
-app_open_file(System_Functions *system, App_Vars *vars, Exchange *exchange,
-              Live_Views *live_set, Working_Set *working_set, Panel *panel,
-              Command_Data *command_data, String filename){
-    App_Open_File_Result file;
-    Mem_Options *mem = &vars->mem;
-    File_View *result = 0;
-    
-    file = app_open_file_background(vars, exchange, working_set, filename);
-    
-    if (file.file){
-        Style *style = command_data->style;
-        
-        View *new_view = live_set_alloc_view(live_set, mem);
-        view_replace_major(system, exchange, new_view, panel, live_set);
-        
-        File_View *file_view = file_view_init(new_view, &vars->layout);
-        result = file_view;
-        
-        View *old_view = command_data->view;
-        command_data->view = new_view;
-        
-        Partition old_part = command_data->part;
-        Temp_Memory temp = begin_temp_memory(&mem->part);
-        command_data->part = partition_sub_part(&mem->part, Kbytes(16));
-        
-        view_set_file(system, file_view, file.file, vars->font_set,
-                      style, vars->hooks[hook_open_file], command_data,
-                      &app_links);
-        
-        command_data->part = old_part;
-        end_temp_memory(temp);
-        command_data->view = old_view;
-        
-        new_view->map = app_get_map(vars, file.file->settings.base_map_id);
-    }
-    
     return(result);
 }
 
@@ -928,42 +902,81 @@ COMMAND_DECL(interactive_open){
     USE_DELAY(delay);
     USE_EXCHANGE(exchange);
     USE_FONT_SET(font_set);
-    
+
     char *filename = 0;
     int filename_len = 0;
-    
+    int do_in_background = 0;
+
     Command_Parameter *end = param_stack_end(&command->part);
     Command_Parameter *param = param_stack_first(&command->part, end);
     for (; param < end; param = param_next(param, end)){
-        if (param->param.param.type == dynamic_type_int &&
-            param->param.param.int_value == par_name &&
-            param->param.value.type == dynamic_type_string){
-            filename = param->param.value.str_value;
-            filename_len = param->param.value.str_len;
-            break;
+        if (param->param.param.type == dynamic_type_int){
+            if (param->param.param.int_value == par_name &&
+                    param->param.value.type == dynamic_type_string){
+                filename = param->param.value.str_value;
+                filename_len = param->param.value.str_len;
+            }
+            else if (param->param.param.int_value == par_do_in_background){
+                do_in_background = dynamic_to_int(&param->param.value);
+            }
         }
     }
     
     if (filename){
         String string = make_string(filename, filename_len);
-        app_open_file(system, vars, exchange,
-                      live_set, working_set, panel,
-                      command, string);
+        if (do_in_background){
+            delayed_open_background(delay, string);
+        }
+        else{
+            delayed_open(delay, string, panel);
+        }
     }
     else{
         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, working_set, font_set, delay);
+            style, working_set, font_set, delay);
         int_view->interaction = INTV_SYS_FILE_LIST;
         int_view->action = INTV_OPEN;
         copy(&int_view->query, "Open: ");
     }
 }
 
+internal void
+view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){
+    Live_Views *live_set = cmd->live_set;
+    Mem_Options *mem = cmd->mem;
+    Exchange *exchange = cmd->exchange;
+    System_Functions *system = cmd->system;
+    Editing_Layout *layout = cmd->layout;
+    App_Vars *vars = cmd->vars;
+    Style *style = cmd->style;
+    
+    View *new_view = live_set_alloc_view(live_set, mem);
+    view_replace_major(system, exchange, new_view, panel, live_set);
+
+    File_View *file_view = file_view_init(new_view, layout);
+
+    View *old_view = cmd->view;
+    cmd->view = new_view;
+
+    Partition old_part = cmd->part;
+    Temp_Memory temp = begin_temp_memory(&mem->part);
+    cmd->part = partition_sub_part(&mem->part, Kbytes(16));
+
+    view_set_file(system, file_view, file, vars->font_set,
+        style, vars->hooks[hook_open_file], cmd, &app_links);
+
+    cmd->part = old_part;
+    end_temp_memory(temp);
+    cmd->view = old_view;
+
+    new_view->map = app_get_map(vars, file->settings.base_map_id);
+}
+
 // TODO(allen): Improvements to reopen
 // - Preserve existing token stack
 // - Keep current version open and do some sort of diff to keep
@@ -976,7 +989,7 @@ COMMAND_DECL(reopen){
     USE_WORKING_SET(working_set);
     USE_VARS(vars);
     USE_STYLE(style);
-    
+
     i32 file_id = exchange_request_file(exchange, expand_str(file->name.source_path));
     i32 index = 0;
     if (file_id){
@@ -985,7 +998,7 @@ COMMAND_DECL(reopen){
         app_push_file_binding(vars, file_id, index);
 
         view_set_file(system, view, file, vars->font_set, style,
-                      vars->hooks[hook_open_file], command, &app_links);
+            vars->hooks[hook_open_file], command, &app_links);
     }
     else{
         // TODO(allen): feedback message
@@ -994,12 +1007,53 @@ COMMAND_DECL(reopen){
 
 COMMAND_DECL(save){
     ProfileMomentFunction();
-    REQ_FILE_VIEW(view);
-    REQ_FILE(file, view);
+    USE_FILE_VIEW(view);
+    USE_FILE(file, view);
     USE_DELAY(delay);
-    USE_PANEL(panel);
+    USE_WORKING_SET(working_set);
+
+    char *filename = 0;
+    int filename_len = 0;
+    int buffer_id = -1;
+
+    Command_Parameter *end = param_stack_end(&command->part);
+    Command_Parameter *param = param_stack_first(&command->part, end);
+    for (; param < end; param = param_next(param, end)){
+        int v = dynamic_to_int(&param->param.param);
+        if (v == par_name && param->param.value.type == dynamic_type_string){
+            filename = param->param.value.str_value;
+            filename_len = param->param.value.str_len;
+        }
+        else if (v == par_buffer_id && param->param.value.type == dynamic_type_int){
+            buffer_id = dynamic_to_int(&param->param.value);
+        }
+    }
     
-    delayed_save(delay, file->name.source_path, panel);
+    String name = {};
+    if (filename){
+        name = make_string(filename, filename_len);
+    }
+    else if (file){
+        name = file->name.source_path;
+    }
+    
+    if (name.size != 0){
+        if (buffer_id == -1){
+            if (file){
+                delayed_save(delay, name, file);
+            }
+        }
+        else{
+            file = working_set->files + buffer_id;
+            
+            if (!file->state.is_dummy && file_is_ready(file)){
+                delayed_save(delay, name, file);
+            }
+            else{
+                delayed_save(delay, name);
+            }
+        }
+    }
 }
 
 COMMAND_DECL(interactive_save_as){
@@ -1013,14 +1067,14 @@ COMMAND_DECL(interactive_save_as){
     USE_DELAY(delay);
     USE_EXCHANGE(exchange);
     USE_FONT_SET(font_set);
-    
+
     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,
-                              working_set, font_set, delay);
+        working_set, font_set, delay);
     int_view->interaction = INTV_SYS_FILE_LIST;
     int_view->action = INTV_SAVE_AS;
     copy(&int_view->query, "Save As: ");
@@ -1048,14 +1102,14 @@ COMMAND_DECL(interactive_switch_buffer){
     USE_DELAY(delay);
     USE_EXCHANGE(exchange);
     USE_FONT_SET(font_set);
-    
+
     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,
-                              working_set, font_set, delay);
+        working_set, font_set, delay);
     int_view->interaction = INTV_LIVE_FILE_LIST;
     int_view->action = INTV_SWITCH;
     copy(&int_view->query, "Switch File: ");
@@ -1072,14 +1126,14 @@ COMMAND_DECL(interactive_kill_buffer){
     USE_DELAY(delay);
     USE_EXCHANGE(exchange);
     USE_FONT_SET(font_set);
-    
+
     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,
-                              working_set, font_set, delay);
+        working_set, font_set, delay);
     int_view->interaction = INTV_LIVE_FILE_LIST;
     int_view->action = INTV_KILL;
     copy(&int_view->query, "Kill File: ");
@@ -1090,7 +1144,7 @@ COMMAND_DECL(kill_buffer){
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
     USE_DELAY(delay);
-    
+
     delayed_try_kill(delay, file->name.live_name, view->view_base.panel);
 }
 
@@ -1098,7 +1152,7 @@ COMMAND_DECL(toggle_line_wrap){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     Relative_Scrolling scrolling = view_get_relative_scrolling(view);
     if (view->unwrapped_lines){
         view->unwrapped_lines = 0;
@@ -1130,7 +1184,7 @@ COMMAND_DECL(toggle_tokens){
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
     USE_MEM(mem);
-    
+
     if (file->settings.tokens_exist){
         file_kill_tokens(system, &mem->general, file);
     }
@@ -1142,8 +1196,8 @@ COMMAND_DECL(toggle_tokens){
 
 internal void
 case_change_range(System_Functions *system,
-                  Mem_Options *mem, File_View *view, Editing_File *file,
-                  u8 a, u8 z, u8 char_delta){
+    Mem_Options *mem, File_View *view, Editing_File *file,
+    u8 a, u8 z, u8 char_delta){
 #if BUFFER_EXPERIMENT_SCALPEL <= 0
     Range range = make_range(view->cursor.pos, view->mark);
     if (range.start < range.end){
@@ -1152,12 +1206,12 @@ case_change_range(System_Functions *system,
         step.edit.start = range.start;
         step.edit.end = range.end;
         step.edit.len = range.end - range.start;
-        
+
         if (file->state.still_lexing)
             system->cancel_job(BACKGROUND_THREADS, file->state.lex_job);
-        
+
         file_update_history_before_edit(mem, file, step, 0, hist_normal);
-        
+
         u8 *data = (u8*)file->state.buffer.data;
         for (i32 i = range.start; i < range.end; ++i){
             if (data[i] >= a && data[i] <= z){
@@ -1193,7 +1247,7 @@ COMMAND_DECL(clean_all_lines){
     REQ_FILE(file, view);
     USE_LAYOUT(layout);
     USE_MEM(mem);
-    
+
     view_clean_whitespace(system, mem, view, layout);
 }
 
@@ -1201,7 +1255,7 @@ COMMAND_DECL(eol_dosify){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     file->settings.dos_write_mode = 1;
     file->state.last_4ed_edit_time = system->time();
 }
@@ -1210,7 +1264,7 @@ COMMAND_DECL(eol_nixify){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     file->settings.dos_write_mode = 0;
     file->state.last_4ed_edit_time = system->time();
 }
@@ -1221,11 +1275,11 @@ COMMAND_DECL(auto_tab_range){
     REQ_FILE(file, view);
     USE_LAYOUT(layout);
     USE_MEM(mem);
-    
+
     int r_start = 0, r_end = 0;
     int start_set = 0, end_set = 0;
     int clear_blank_lines = 1;
-    
+
     // TODO(allen): deduplicate
     Command_Parameter *end = param_stack_end(&command->part);
     Command_Parameter *param = param_stack_first(&command->part, end);
@@ -1236,18 +1290,18 @@ COMMAND_DECL(auto_tab_range){
             start_set = 1;
             r_start = dynamic_to_int(&param->param.value);
             break;
-            
+
             case par_range_end:
             end_set = 1;
             r_end = dynamic_to_int(&param->param.value);
             break;
-            
+
             case par_clear_blank_lines:
             clear_blank_lines = dynamic_to_bool(&param->param.value);
             break;
         }
     }
-    
+
     if (file->state.token_stack.tokens && file->state.tokens_complete){
         Range range = make_range(view->cursor.pos, view->mark);
         if (start_set) range.start = r_start;
@@ -1264,7 +1318,7 @@ COMMAND_DECL(auto_tab_line_at_cursor){
     USE_MEM(mem);
 
     int clear_blank_lines = 0;
-    
+
     Command_Parameter *end = param_stack_end(&command->part);
     Command_Parameter *param = param_stack_first(&command->part, end);
     for (; param < end; param = param_next(param, end)){
@@ -1275,7 +1329,7 @@ COMMAND_DECL(auto_tab_line_at_cursor){
             break;
         }
     }
-    
+
     if (file->state.token_stack.tokens && file->state.tokens_complete){
         i32 pos = view->cursor.pos;
         view_auto_tab_tokens(system, mem, view, layout, pos, pos, clear_blank_lines);
@@ -1298,24 +1352,24 @@ COMMAND_DECL(open_panel_vsplit){
     ProfileMomentFunction();
     USE_LAYOUT(layout);
     USE_PANEL(panel);
-    
+
     i32 panel_count = layout->panel_count;
     if (panel_count < layout->panel_max_count){
         Split_Result split = layout_split_panel(layout, panel, 1);
-        
+
         Panel *panel1 = panel;
         Panel *panel2 = split.panel;
-        
+
         panel2->screen_region = panel1->screen_region;
-        
+
         panel2->full.x0 = split.divider->pos;
         panel2->full.x1 = panel1->full.x1;
         panel1->full.x1 = split.divider->pos;
-        
+
         panel_fix_internal_area(panel1);
         panel_fix_internal_area(panel2);
         panel2->prev_inner = panel2->inner;
-        
+
         layout->active_panel = (i32)(panel2 - layout->panels);
     }
 }
@@ -1324,24 +1378,24 @@ COMMAND_DECL(open_panel_hsplit){
     ProfileMomentFunction();
     USE_LAYOUT(layout);
     USE_PANEL(panel);
-    
+
     i32 panel_count = layout->panel_count;
     if (panel_count < layout->panel_max_count){
         Split_Result split = layout_split_panel(layout, panel, 0);
-        
+
         Panel *panel1 = panel;
         Panel *panel2 = split.panel;
-        
+
         panel2->screen_region = panel1->screen_region;
-        
+
         panel2->full.y0 = split.divider->pos;
         panel2->full.y1 = panel1->full.y1;
         panel1->full.y1 = split.divider->pos;
-        
+
         panel_fix_internal_area(panel1);
         panel_fix_internal_area(panel2);
         panel2->prev_inner = panel2->inner;
-        
+
         layout->active_panel = (i32)(panel2 - layout->panels);
     }
 }
@@ -1352,16 +1406,16 @@ COMMAND_DECL(close_panel){
     USE_PANEL(panel);
     USE_VIEW(view);
     USE_EXCHANGE(exchange);
-    
+
     if (layout->panel_count > 1){
         if (view){
             live_set_free_view(system, exchange, command->live_set, view);
             panel->view = 0;
         }
-        
+
         Divider_And_ID div = layout_get_divider(layout, panel->parent);
         Assert(div.divider->child1 == -1 || div.divider->child2 == -1);
-        
+
         i32 child;
         if (div.divider->child1 == -1){
             child = div.divider->child2;
@@ -1385,16 +1439,16 @@ COMMAND_DECL(close_panel){
             Assert(layout->root == div.id);
             layout->root = child;
         }
-        
+
         if (child != -1){
             Divider_And_ID chi = layout_get_divider(layout, child);
             chi.divider->parent = parent;
             chi.divider->which_child = div.divider->which_child;
         }
-        
+
         layout_free_divider(layout, div.divider);
         layout_free_panel(layout, panel);
-        
+
         if (child == -1){
             panel = layout->panels;
             layout->active_panel = -1;
@@ -1412,7 +1466,7 @@ COMMAND_DECL(close_panel){
         else{
             layout->active_panel = layout->active_panel % layout->panel_count;
         }
-        
+
         layout_fix_all_panels(layout);
     }
 }
@@ -1421,7 +1475,7 @@ COMMAND_DECL(move_left){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     i32 pos = view->cursor.pos;
     if (pos > 0) --pos;
     view_cursor_move(view, pos);
@@ -1431,7 +1485,7 @@ COMMAND_DECL(move_right){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     i32 size = buffer_size(&file->state.buffer);
     i32 pos = view->cursor.pos;
     if (pos < size) ++pos;
@@ -1451,9 +1505,9 @@ COMMAND_DECL(delete){
         i32 start, end;
         start = cursor_pos;
         end = cursor_pos+1;
-        
+
         Assert(end - start > 0);
-        
+
         i32 next_cursor_pos = start;
         view_replace_range(system, mem, view, layout, start, end, 0, 0, next_cursor_pos);
         view_cursor_move(view, next_cursor_pos);
@@ -1466,17 +1520,17 @@ COMMAND_DECL(backspace){
     REQ_FILE(file, view);
     USE_LAYOUT(layout);
     USE_MEM(mem);
-    
+
     i32 size = buffer_size(&file->state.buffer);
     i32 cursor_pos = view->cursor.pos;
     if (cursor_pos > 0 && cursor_pos <= size){
         i32 start, end;
         end = cursor_pos;
         start = cursor_pos-1;
-        
+
         i32 shift = (end - start);
         Assert(shift > 0);
-        
+
         i32 next_cursor_pos = view->cursor.pos - shift;
         view_replace_range(system, mem, view, layout, start, end, 0, 0, next_cursor_pos);
         view_cursor_move(view, next_cursor_pos);
@@ -1488,7 +1542,7 @@ COMMAND_DECL(move_up){
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
     USE_FONT_SET(font_set);
-    
+
     f32 font_height = (f32)get_font_info(font_set, view->style->font_id)->height;
     f32 cy = view_get_cursor_y(view)-font_height;
     f32 px = view->preferred_x;
@@ -1515,7 +1569,7 @@ COMMAND_DECL(seek_end_of_line){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     i32 pos = view_find_end_of_line(view, view->cursor.pos);
     view_cursor_move(view, pos);
 }
@@ -1524,7 +1578,7 @@ COMMAND_DECL(seek_beginning_of_line){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
     REQ_FILE(file, view);
-    
+
     i32 pos = view_find_beginning_of_line(view, view->cursor.pos);
     view_cursor_move(view, pos);
 }
@@ -1532,10 +1586,10 @@ COMMAND_DECL(seek_beginning_of_line){
 COMMAND_DECL(page_down){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
-    
+
     f32 height = view_compute_height(view);
     f32 max_target_y = view_compute_max_target_y(view);
-    
+
     view->target_y += height;
     if (view->target_y > max_target_y) view->target_y = max_target_y;
 
@@ -1546,22 +1600,22 @@ COMMAND_DECL(page_down){
 COMMAND_DECL(page_up){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
-    
+
     f32 height = view_compute_height(view);
-    
+
     view->target_y -= height;
     if (view->target_y < 0) view->target_y = 0;
-    
+
     view->cursor = view_compute_cursor_from_xy(
         view, 0, view->target_y + (height - view->font_height)*.5f);
 }
 
 inline void
 open_theme_options(System_Functions *system, Exchange *exchange,
-                   App_Vars *vars, Live_Views *live_set, Mem_Options *mem, Panel *panel){
+    App_Vars *vars, Live_Views *live_set, Mem_Options *mem, Panel *panel){
     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;
     Color_View *color_view = color_view_init(new_view, &vars->working_set);
     color_view->hot_directory = &vars->hot_directory;
@@ -1579,20 +1633,20 @@ COMMAND_DECL(open_color_tweaker){
     USE_MEM(mem);
     USE_PANEL(panel);
     USE_EXCHANGE(exchange);
-    
+
     open_theme_options(system, exchange, vars, live_set, mem, panel);
 }
 
 inline void
 open_config_options(System_Functions *system, Exchange *exchange,
-                   App_Vars *vars, Live_Views *live_set, Mem_Options *mem, Panel *panel){
+    App_Vars *vars, Live_Views *live_set, Mem_Options *mem, Panel *panel){
     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;
     config_view_init(new_view, &vars->style,
-                     &vars->working_set, vars->font_set,
-                     &vars->settings);
+        &vars->working_set, vars->font_set,
+        &vars->settings);
 }
 
 COMMAND_DECL(open_config){
@@ -1602,7 +1656,7 @@ COMMAND_DECL(open_config){
     USE_MEM(mem);
     USE_PANEL(panel);
     USE_EXCHANGE(exchange);
-    
+
     open_config_options(system, exchange, vars, live_set, mem, panel);
 }
 
@@ -1615,13 +1669,13 @@ COMMAND_DECL(open_menu){
     USE_WORKING_SET(working_set);
     USE_STYLE(style);
     USE_EXCHANGE(exchange);
-    
+
     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;
     Menu_View *menu_view = menu_view_init(new_view, style, working_set,
-                                          &vars->delay, vars->font_set);
+        &vars->delay1, vars->font_set);
     AllowLocal(menu_view);
 }
 
@@ -1634,10 +1688,10 @@ COMMAND_DECL(open_debug_view){
     USE_PANEL(panel);
     USE_MEM(mem);
     USE_EXCHANGE(exchange);
-    
+
     View *new_view = live_set_alloc_view(live_set, mem);
     view_replace_major(system, exchange, new_view, panel, live_set);
-    
+
     new_view->map = &vars->map_debug;
     Debug_View *debug_view = debug_view_init(new_view);
     debug_view->font_id = style->font_id;
@@ -1664,14 +1718,14 @@ COMMAND_DECL(close_minor_view){
     USE_PANEL(panel);
     USE_LIVE_SET(live_set);
     USE_EXCHANGE(exchange);
-    
+
     view_remove_minor(system, exchange, panel, live_set);
 }
 
 COMMAND_DECL(cursor_mark_swap){
     ProfileMomentFunction();
     REQ_FILE_VIEW(view);
-    
+
     i32 pos = view->cursor.pos;
     view_cursor_move(view, view->mark);
     view->mark = pos;
@@ -1688,68 +1742,68 @@ COMMAND_DECL(set_settings){
     REQ_FILE_LOADING(file, view);
     USE_VARS(vars);
     USE_MEM(mem);
-    
+
     Command_Parameter *end = param_stack_end(&command->part);
     Command_Parameter *param = param_stack_first(&command->part, end);
     for (; param < end; param = param_next(param, end)){
         int p = dynamic_to_int(&param->param.param);
         switch (p){
-        case par_lex_as_cpp_file:
-        {
+            case par_lex_as_cpp_file:
+            {
 #if BUFFER_EXPERIMENT_SCALPEL <= 0
-            int v = dynamic_to_bool(&param->param.value);
-            if (file->settings.tokens_exist){
-                if (!v) file_kill_tokens(system, &mem->general, file);
-            }
-            else{
-                if (v) file_first_lex_parallel(system, &mem->general, file);
-            }
+                int v = dynamic_to_bool(&param->param.value);
+                if (file->settings.tokens_exist){
+                    if (!v) file_kill_tokens(system, &mem->general, file);
+                }
+                else{
+                    if (v) file_first_lex_parallel(system, &mem->general, file);
+                }
 #endif
-        }break;
-        
-        case par_wrap_lines:
-        {
-            int v = dynamic_to_bool(&param->param.value);
-            if (view->unwrapped_lines){
-                if (v){
-                    view->unwrapped_lines = 0;
-                    file->settings.unwrapped_lines = 0;
-                    
-                    if (!file->state.is_loading){
-                        Relative_Scrolling scrolling = view_get_relative_scrolling(view);
-                        view->target_x = 0;
-                        view->cursor =
-                            view_compute_cursor_from_pos(view, view->cursor.pos);
-                        view_set_relative_scrolling(view, scrolling);
+            }break;
+
+            case par_wrap_lines:
+            {
+                int v = dynamic_to_bool(&param->param.value);
+                if (view->unwrapped_lines){
+                    if (v){
+                        view->unwrapped_lines = 0;
+                        file->settings.unwrapped_lines = 0;
+
+                        if (!file->state.is_loading){
+                            Relative_Scrolling scrolling = view_get_relative_scrolling(view);
+                            view->target_x = 0;
+                            view->cursor =
+                                view_compute_cursor_from_pos(view, view->cursor.pos);
+                            view_set_relative_scrolling(view, scrolling);
+                        }
                     }
                 }
-            }
-            else{
-                if (!v){
-                    view->unwrapped_lines = 1;
-                    file->settings.unwrapped_lines = 1;
-                    
-                    if (!file->state.is_loading){
-                        Relative_Scrolling scrolling = view_get_relative_scrolling(view);
-                        view->cursor =
-                            view_compute_cursor_from_pos(view, view->cursor.pos);
-                        view_set_relative_scrolling(view, scrolling);
+                else{
+                    if (!v){
+                        view->unwrapped_lines = 1;
+                        file->settings.unwrapped_lines = 1;
+
+                        if (!file->state.is_loading){
+                            Relative_Scrolling scrolling = view_get_relative_scrolling(view);
+                            view->cursor =
+                                view_compute_cursor_from_pos(view, view->cursor.pos);
+                            view_set_relative_scrolling(view, scrolling);
+                        }
                     }
                 }
-            }
-        }break;
-        
-        case par_key_mapid:
-        {
-            int v = dynamic_to_int(&param->param.value);
-            if (v == mapid_global) file->settings.base_map_id = mapid_global;
-            else if (v == mapid_file) file->settings.base_map_id = mapid_file;
-            else if (v < mapid_global){
-                int index = app_get_map_index(vars, v);
-                if (index < vars->user_map_count) file->settings.base_map_id = v;
-                else file->settings.base_map_id = mapid_file;
-            }
-        }break;
+            }break;
+
+            case par_key_mapid:
+            {
+                int v = dynamic_to_int(&param->param.value);
+                if (v == mapid_global) file->settings.base_map_id = mapid_global;
+                else if (v == mapid_file) file->settings.base_map_id = mapid_file;
+                else if (v < mapid_global){
+                    int index = app_get_map_index(vars, v);
+                    if (index < vars->user_map_count) file->settings.base_map_id = v;
+                    else file->settings.base_map_id = mapid_file;
+                }
+            }break;
         }
     }
 }
@@ -1759,25 +1813,25 @@ COMMAND_DECL(set_settings){
 
 internal void
 build(System_Functions *system, Mem_Options *mem,
-      App_Vars *vars, Working_Set *working_set,
-      Font_Set *font_set, Style *style,
-      Live_Views *live_set, Exchange *exchange,
-      Panel *panel, Command_Data *command,
-      String hot_directory,
-      char *buffer_name, i32 buffer_name_len,
-      char *path, i32 path_len,
-      char *script, i32 script_len,
-      u32 flags){
+    App_Vars *vars, Working_Set *working_set,
+    Font_Set *font_set, Style *style,
+    Live_Views *live_set, Exchange *exchange,
+    Panel *panel, Command_Data *command,
+    String hot_directory,
+    char *buffer_name, i32 buffer_name_len,
+    char *path, i32 path_len,
+    char *script, i32 script_len,
+    u32 flags){
     if (buffer_name == 0 || path == 0 || script == 0){
         return;
     }
-    
+
     if (vars->cli_processes.count < vars->cli_processes.max){
         Editing_Layout *layout = &vars->layout;
         Editing_File *file = working_set_contains(working_set, make_string_slowly(buffer_name));
         i32 index;
         b32 bind_to_new_view = 1;
-        
+
         if (!file){
             Get_File_Result get_file = working_set_get_available_file(working_set);
             file = get_file.file;
@@ -1807,22 +1861,25 @@ build(System_Functions *system, Mem_Options *mem,
                 }
             }
         }
-        
+
         if (file){
             file_create_super_locked(system, mem, working_set, file, buffer_name, font_set, style->font_id);
             file->settings.unimportant = 1;
             table_add(&working_set->table, file->name.source_path, index);
-            
+
             if (bind_to_new_view){
+#if 0
                 View *new_view = live_set_alloc_view(live_set, mem);
                 view_replace_major(system, exchange, new_view, panel, live_set);
-                
+
                 File_View *file_view = file_view_init(new_view, layout);
                 view_set_file(system, file_view, file, font_set, style,
-                              vars->hooks[hook_open_file], command, &app_links);
+                    vars->hooks[hook_open_file], command, &app_links);
                 new_view->map = app_get_map(vars, file->settings.base_map_id);
+#endif
+                view_file_in_panel(command, panel, file);
             }
-            
+
             i32 i = vars->cli_processes.count++;
             CLI_Process *proc = vars->cli_processes.procs + i;
             if (!system->cli_call(path, script, &proc->cli)){
@@ -1839,7 +1896,7 @@ build(System_Functions *system, Mem_Options *mem,
     }
 }
 
-COMMAND_DECL(build){
+COMMAND_DECL(command_line){
     ProfileMomentFunction();
     USE_VARS(vars);
     USE_MEM(mem);
@@ -1853,73 +1910,73 @@ COMMAND_DECL(build){
     char *buffer_name = 0;
     char *path = 0;
     char *script = 0;
-    
+
     int buffer_name_len = 0;
     int path_len = 0;
     int script_len = 0;
     u32 flags = CLI_OverlapWithConflict;
-    
+
     Command_Parameter *end = param_stack_end(&command->part);
     Command_Parameter *param = param_stack_first(&command->part, end);
     for (; param < end; param = param_next(param, end)){
         int p = dynamic_to_int(&param->param.param);
         switch (p){
-        case par_name:
-        {
-            if (buffer_name == 0){
-                char *new_buffer_name = dynamic_to_string(&param->param.value, &buffer_name_len);
-                if (new_buffer_name){
-                    buffer_name = new_buffer_name;
+            case par_name:
+            {
+                if (buffer_name == 0){
+                    char *new_buffer_name = dynamic_to_string(&param->param.value, &buffer_name_len);
+                    if (new_buffer_name){
+                        buffer_name = new_buffer_name;
+                    }
                 }
-            }
-        }break;
+            }break;
 
-        case par_cli_path:
-        {
-            if (path == 0){
-                char *new_cli_path = dynamic_to_string(&param->param.value, &path_len);
-                if (new_cli_path){
-                    path = new_cli_path;
+            case par_cli_path:
+            {
+                if (path == 0){
+                    char *new_cli_path = dynamic_to_string(&param->param.value, &path_len);
+                    if (new_cli_path){
+                        path = new_cli_path;
+                    }
                 }
-            }
-        }break;
+            }break;
 
-        case par_cli_command:
-        {
-            if (script == 0){
-                char *new_command = dynamic_to_string(&param->param.value, &script_len);
-                if (new_command){
-                    script = new_command;
+            case par_cli_command:
+            {
+                if (script == 0){
+                    char *new_command = dynamic_to_string(&param->param.value, &script_len);
+                    if (new_command){
+                        script = new_command;
+                    }
                 }
-            }
-        }break;
-        
-        case par_cli_overlap_with_conflict:
-        {
-            if (dynamic_to_int(&param->param.value))
-                flags |= CLI_OverlapWithConflict;
-            else
-                flags &= (~CLI_OverlapWithConflict);
-        }break;
-        
-        case par_cli_always_bind_to_view:
-        {
-            if (dynamic_to_int(&param->param.value))
-                flags |= CLI_OverlapWithConflict;
-            else
-                flags &= (~CLI_OverlapWithConflict);
-        }break;
+            }break;
+
+            case par_cli_overlap_with_conflict:
+            {
+                if (dynamic_to_int(&param->param.value))
+                    flags |= CLI_OverlapWithConflict;
+                else
+                    flags &= (~CLI_OverlapWithConflict);
+            }break;
+
+            case par_cli_always_bind_to_view:
+            {
+                if (dynamic_to_int(&param->param.value))
+                    flags |= CLI_OverlapWithConflict;
+                else
+                    flags &= (~CLI_OverlapWithConflict);
+            }break;
         }
     }
-    
+
     build(system, mem, vars, working_set,
-          font_set, style, live_set, exchange,
-          panel, command,
-          vars->hot_directory.string,
-          buffer_name, buffer_name_len,
-          path, path_len,
-          script, script_len,
-          flags);
+        font_set, style, live_set, exchange,
+        panel, command,
+        vars->hot_directory.string,
+        buffer_name, buffer_name_len,
+        path, path_len,
+        script, script_len,
+        flags);
 }
 
 internal void
@@ -1964,7 +2021,7 @@ fill_view_summary(File_View_Summary *view, File_View *file_view, Live_Views *liv
 
 extern "C"{
     EXECUTE_COMMAND_SIG(external_exec_command_keep_stack){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Command_Function function = command_table[command_id];
         Command_Binding binding;
         binding.function = function;
@@ -1972,18 +2029,18 @@ extern "C"{
 
         update_command_data(cmd->vars, cmd);
     }
-    
+
     PUSH_PARAMETER_SIG(external_push_parameter){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Partition *part = &cmd->part;
         Command_Parameter *cmd_param = push_struct(part, Command_Parameter);
         cmd_param->type = 0;
         cmd_param->param.param = param;
         cmd_param->param.value = value;
     }
-    
+
     PUSH_MEMORY_SIG(external_push_memory){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Partition *part = &cmd->part;
         Command_Parameter *base = push_struct(part, Command_Parameter);
         char *result = push_array(part, char, len);
@@ -1995,75 +2052,89 @@ extern "C"{
         base->inline_string.len = len;
         return(result);
     }
-    
+
     CLEAR_PARAMETERS_SIG(external_clear_parameters){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         cmd->part.pos = 0;
     }
-    
+
     DIRECTORY_GET_HOT_SIG(external_directory_get_hot){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Hot_Directory *hot = &cmd->vars->hot_directory;
-        i32 copy_max = max - 1;
+        i32 copy_max = capacity - 1;
         hot_directory_clean_end(hot);
         if (copy_max > hot->string.size)
             copy_max = hot->string.size;
-        memcpy(buffer, hot->string.str, copy_max);
-        buffer[copy_max] = 0;
-        return(copy_max);
+        memcpy(out, hot->string.str, copy_max);
+        out[copy_max] = 0;
+        return(hot->string.size);
+    }
+    
+    GET_FILE_LIST_SIG(external_get_file_list){
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
+        System_Functions *system = cmd->system;
+        File_List result = {};
+        system->set_file_list(&result, make_string(dir, len));
+        return(result);
+    }
+    
+    FREE_FILE_LIST_SIG(external_free_file_list){
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
+        System_Functions *system = cmd->system;
+        system->set_file_list(&list, make_string(0, 0));
     }
     
     GET_BUFFER_MAX_INDEX_SIG(external_get_buffer_max_index){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Working_Set *working_set = cmd->working_set;
         int max = working_set->file_index_count;
         return(max);
     }
-    
+
     GET_BUFFER_SIG(external_get_buffer){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Editing_File *file;
         Working_Set *working_set = cmd->working_set;
         int max = working_set->file_index_count;
         Buffer_Summary buffer = {};
-        
+
         if (index >= 0 && index < max){
             file = working_set->files + index;
             if (!file->state.is_dummy){
                 fill_buffer_summary(&buffer, file, working_set);
             }
         }
-        
+
         return(buffer);
     }
-    
+
     GET_ACTIVE_BUFFER_SIG(external_get_active_buffer){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         File_View *view;
         Editing_File *file;
         Working_Set *working_set;
         Buffer_Summary buffer = {};
-        
+
         view = view_to_file_view(cmd->view);
         if (view){
             file = view->file;
             working_set = cmd->working_set;
-            
+
             if (file && !file->state.is_dummy){
                 fill_buffer_summary(&buffer, file, working_set);
             }
         }
-        
+
         return(buffer);
     }
-    
+
     GET_BUFFER_BY_NAME(external_get_buffer_by_name){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Editing_File *file;
         Working_Set *working_set;
         i32 index;
         Buffer_Summary buffer = {};
-        
+
         working_set = cmd->working_set;
         if (table_find(&working_set->table, make_string(filename, len), &index)){
             file = working_set->files + index;
@@ -2071,31 +2142,31 @@ extern "C"{
                 fill_buffer_summary(&buffer, file, working_set);
             }
         }
-        
+
         return(buffer);
     }
-    
+
     REFRESH_BUFFER_SIG(external_refresh_buffer){
         int result;
         *buffer = external_get_buffer(context, buffer->buffer_id);
         result = buffer->exists;
         return(result);
     }
-    
+
     BUFFER_SEEK_DELIMITER_SIG(external_buffer_seek_delimiter){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Editing_File *file;
         Working_Set *working_set;
         int result = 0;
         int size;
-        
+
         if (buffer->exists){
             working_set = cmd->working_set;
             file = working_set->files + buffer->buffer_id;
             if (!file->state.is_dummy && file_is_ready(file)){
                 size = buffer_size(&file->state.buffer);
                 result = 1;
-                
+
                 if (start < 0 && !seek_forward) *out = start;
                 else if (start >= size && seek_forward) *out = start;
                 else{
@@ -2106,16 +2177,16 @@ extern "C"{
                         *out = buffer_reverse_seek_delimiter(&file->state.buffer, start, delim);
                     }
                 }
-                
+
                 fill_buffer_summary(buffer, file, working_set);
             }
         }
 
         return(result);
     }
-    
+
     BUFFER_SEEK_STRING_SIG(external_buffer_seek_string){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Editing_File *file;
         Working_Set *working_set;
         Temp_Memory temp;
@@ -2123,13 +2194,13 @@ extern "C"{
         char *spare;
         int result = 0;
         int size;
-        
+
         if (buffer->exists){
             working_set = cmd->working_set;
             file = working_set->files + buffer->buffer_id;
             if (!file->state.is_dummy && file_is_ready(file)){
                 size = buffer_size(&file->state.buffer);
-                
+
                 if (start < 0 && !seek_forward) *out = start;
                 else if (start >= size && seek_forward) *out = start;
                 else{
@@ -2151,14 +2222,14 @@ extern "C"{
 
         return(result);
     }
-    
+
     BUFFER_READ_RANGE_SIG(external_buffer_read_range){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Editing_File *file;
         Working_Set *working_set;
         int result = 0;
         int size;
-        
+
         if (buffer->exists){
             working_set = cmd->working_set;
             file = working_set->files + buffer->buffer_id;
@@ -2171,23 +2242,23 @@ extern "C"{
                 fill_buffer_summary(buffer, file, working_set);
             }
         }
-        
+
         return(result);
     }
-    
+
     BUFFER_REPLACE_RANGE_SIG(external_buffer_replace_range){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Editing_File *file;
         Working_Set *working_set;
-        
+
         System_Functions *system;
         Mem_Options *mem;
         Editing_Layout *layout;
-        
+
         int result = 0;
         int size;
         int next_cursor, pos;
-        
+
         if (buffer->exists){
             working_set = cmd->working_set;
             file = working_set->files + buffer->buffer_id;
@@ -2195,61 +2266,41 @@ extern "C"{
                 size = buffer_size(&file->state.buffer);
                 if (0 <= start && start <= end && end <= size){
                     result = 1;
-                    
+
                     system = cmd->system;
                     mem = cmd->mem;
                     layout = cmd->layout;
-                    
+
                     pos = file->state.cursor_pos;
                     if (pos < start) next_cursor = pos;
                     else if (pos < end) next_cursor = start + len;
                     else next_cursor = pos + end - start + len;
-                    
+
                     file_replace_range(system, mem, file, layout,
                         start, end, str, len, next_cursor);
                 }
                 fill_buffer_summary(buffer, file, working_set);
             }
         }
-        
+
         return(result);
     }
-    
-    BUFFER_SAVE_SIG(external_buffer_save){
-        Command_Data *cmd = (Command_Data*)context->data;
-        Editing_File *file;
-        Working_Set *working_set;
-        Delay *delay;
-        int result = 0;
-        
-        if (buffer->exists){
-            delay = cmd->delay;
-            working_set = cmd->working_set;
-            file = working_set->files + buffer->buffer_id;
-            if (!file->state.is_dummy && file_is_ready(file) && buffer_needs_save(file)){
-                delayed_save(delay, file->name.source_path, file);
-                result = 1;
-            }
-        }
-        
-        return(result);
-    }
-    
+
     GET_VIEW_MAX_INDEX_SIG(external_get_view_max_index){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Live_Views *live_set = cmd->live_set;
         int max = live_set->max;
         return(max);
     }
-    
+
     GET_FILE_VIEW_SIG(external_get_file_view){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Live_Views *live_set = cmd->live_set;
         int max = live_set->max;
         View *vptr;
         File_View *file_view;
         File_View_Summary view = {};
-        
+
         if (index >= 0 && index < max){
             vptr = (View*)((char*)live_set->views + live_set->stride*index);
             file_view = view_to_file_view(vptr);
@@ -2257,37 +2308,37 @@ extern "C"{
                 fill_view_summary(&view, file_view, cmd->live_set, cmd->working_set);
             }
         }
-        
+
         return(view);
     }
-    
+
     GET_ACTIVE_FILE_VIEW_SIG(external_get_active_file_view){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         File_View_Summary view = {};
         File_View *file_view;
-        
+
         file_view = view_to_file_view(cmd->view);
         if (file_view){
             fill_view_summary(&view, file_view, cmd->live_set, cmd->working_set);
         }
-        
+
         return(view);
     }
-    
+
     REFRESH_FILE_VIEW_SIG(external_refresh_file_view){
         int result;
         *view = external_get_file_view(context, view->view_id);
         result = view->exists;
         return(result);
     }
-    
+
     VIEW_SET_CURSOR_SIG(external_view_set_cursor){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Live_Views *live_set;
         View *vptr;
         File_View *file_view;
         int result = 0;
-        
+
         if (view->exists){
             live_set = cmd->live_set;
             vptr = (View*)((char*)live_set->views + live_set->stride * view->view_id);
@@ -2301,18 +2352,18 @@ extern "C"{
                 fill_view_summary(view, file_view, cmd->live_set, cmd->working_set);
             }
         }
-        
+
         return(result);
     }
-    
+
     VIEW_SET_MARK_SIG(external_view_set_mark){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Live_Views *live_set;
         View *vptr;
         File_View *file_view;
         Full_Cursor cursor;
         int result = 0;
-        
+
         if (view->exists){
             live_set = cmd->live_set;
             vptr = (View*)((char*)live_set->views + live_set->stride * view->view_id);
@@ -2329,17 +2380,17 @@ extern "C"{
                 fill_view_summary(view, file_view, cmd->live_set, cmd->working_set);
             }
         }
-        
+
         return(result);
     }
-    
+
     VIEW_SET_HIGHLIGHT_SIG(external_view_set_highlight){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Live_Views *live_set;
         View *vptr;
         File_View *file_view;
         int result = 0;
-        
+
         if (view->exists){
             live_set = cmd->live_set;
             vptr = (View*)((char*)live_set->views + live_set->stride * view->view_id);
@@ -2355,19 +2406,19 @@ extern "C"{
                 fill_view_summary(view, file_view, cmd->live_set, cmd->working_set);
             }
         }
-        
+
         return(result);
     }
-    
+
     VIEW_SET_BUFFER_SIG(external_view_set_buffer){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Live_Views *live_set;
         View *vptr;
         File_View *file_view;
         Editing_File *file;
         Working_Set *working_set;
         int max, result = 0;
-        
+
         if (view->exists){
             live_set = cmd->live_set;
             vptr = (View*)((char*)live_set->views + live_set->stride * view->view_id);
@@ -2382,54 +2433,54 @@ extern "C"{
                             cmd->vars->hooks[hook_open_file], cmd, &app_links);
                     }
                 }
-                
+
                 fill_view_summary(view, file_view, cmd->live_set, cmd->working_set);
             }
         }
-        
+
         return(result);
     }
-    
+
     GET_USER_INPUT_SIG(external_get_user_input){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         System_Functions *system = cmd->system;
         Coroutine *coroutine = cmd->current_coroutine;
         User_Input result;
-        
+
         Assert(coroutine);
         *((u32*)coroutine->out+0) = get_type;
         *((u32*)coroutine->out+1) = abort_type;
         system->yield_coroutine(coroutine);
         result = *(User_Input*)coroutine->in;
-        
+
         return(result);
     }
-    
+
     START_QUERY_BAR_SIG(external_start_query_bar){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         Query_Slot *slot = 0;
         View *vptr;
         File_View *file_view;
-        
+
         vptr = cmd->view;
         file_view = view_to_file_view(vptr);
-        
+
         if (file_view){
             slot = alloc_query_slot(&file_view->query_set);
             slot->query_bar = bar;
         }
-        
+
         return(slot != 0);
     }
-    
+
     END_QUERY_BAR_SIG(external_end_query_bar){
-        Command_Data *cmd = (Command_Data*)context->data;
+        Command_Data *cmd = (Command_Data*)context->cmd_context;
         View *vptr;
         File_View *file_view;
-        
+
         vptr = cmd->view;
         file_view = view_to_file_view(vptr);
-        
+
         if (file_view){
             free_query_slot(&file_view->query_set, bar);
         }
@@ -2445,44 +2496,55 @@ internal void
 command_caller(Coroutine *coroutine){
     Command_In *cmd_in = (Command_In*)coroutine->in;
     Command_Data *cmd = cmd_in->cmd;
+    View *view = cmd->view;
+    // TODO(allen): this isn't really super awesome, could have issues if
+    // the file view get's change out under us.
+    File_View *fview = view_to_file_view(view);
+    if (fview) fview->next_mode = {};
     cmd_in->bind.function(cmd->system, cmd, cmd_in->bind);
+    fview = view_to_file_view(view);
+    if (fview) fview->mode = fview->next_mode;
 }
 
 internal void
-app_links_init(System_Functions *system){
+app_links_init(System_Functions *system, void *data, int size){
+    app_links.data = data;
+    app_links.size = size;
+    
     app_links.exec_command_keep_stack = external_exec_command_keep_stack;
     app_links.push_parameter = external_push_parameter;
     app_links.push_memory = external_push_memory;
     app_links.clear_parameters = external_clear_parameters;
-    
+
     app_links.directory_get_hot = external_directory_get_hot;
-    app_links.directory_has_file = system->directory_has_file;
+    app_links.file_exists = system->file_exists;
     app_links.directory_cd = system->directory_cd;
-    
+    app_links.get_file_list = external_get_file_list;
+    app_links.free_file_list = external_free_file_list;
+
     app_links.get_buffer_max_index = external_get_buffer_max_index;
     app_links.get_buffer = external_get_buffer;
     app_links.get_active_buffer = external_get_active_buffer;
     app_links.get_buffer_by_name = external_get_buffer_by_name;
-    
+
     app_links.refresh_buffer = external_refresh_buffer;
     app_links.buffer_seek_delimiter = external_buffer_seek_delimiter;
     app_links.buffer_seek_string = external_buffer_seek_string;
     app_links.buffer_read_range = external_buffer_read_range;
     app_links.buffer_replace_range = external_buffer_replace_range;
-    app_links.buffer_save = external_buffer_save;
-    
+
     app_links.get_view_max_index = external_get_view_max_index;
     app_links.get_file_view = external_get_file_view;
     app_links.get_active_file_view = external_get_active_file_view;
-    
+
     app_links.refresh_file_view = external_refresh_file_view;
     app_links.view_set_cursor = external_view_set_cursor;
     app_links.view_set_mark = external_view_set_mark;
     app_links.view_set_highlight = external_view_set_highlight;
     app_links.view_set_buffer = external_view_set_buffer;
-    
+
     app_links.get_user_input = external_get_user_input;
-    
+
     app_links.start_query_bar = external_start_query_bar;
     app_links.end_query_bar = external_end_query_bar;
 }
@@ -2491,7 +2553,7 @@ app_links_init(System_Functions *system){
 internal void
 setup_debug_commands(Command_Map *commands, Partition *part, Command_Map *parent){
     map_init(commands, part, 6, parent);
-    
+
     map_add(commands, 'm', MDFR_NONE, command_debug_memory);
     map_add(commands, 'o', MDFR_NONE, command_debug_os_events);
 }
@@ -2500,9 +2562,9 @@ setup_debug_commands(Command_Map *commands, Partition *part, Command_Map *parent
 internal void
 setup_ui_commands(Command_Map *commands, Partition *part, Command_Map *parent){
     map_init(commands, part, 32, parent);
-    
+
     commands->vanilla_keyboard_default.function = command_null;
-    
+
     // TODO(allen): This is hacky, when the new UI stuff happens, let's fix it, and by that
     // I mean actually fix it, don't just say you fixed it with something stupid again.
     u8 mdfr;
@@ -2531,7 +2593,7 @@ setup_top_commands(Command_Map *commands, Partition *part, Command_Map *parent){
 internal void
 setup_command_table(){
 #define SET(n) command_table[cmdid_##n] = command_##n
-    
+
     SET(null);
     SET(write_character);
     SET(seek_whitespace_right);
@@ -2595,8 +2657,8 @@ setup_command_table(){
     SET(cursor_mark_swap);
     SET(open_menu);
     SET(set_settings);
-    SET(build);
-    
+    SET(command_line);
+
 #undef SET
 }
 
@@ -2610,11 +2672,11 @@ app_hardcode_styles(App_Vars *vars){
     style = styles;
 
     i16 fonts = 1;
-    
+
     /////////////////
     style_set_name(style, make_lit_string("4coder"));
     style->font_id = fonts + 0;
-    
+
     style->main.back_color = 0xFF0C0C0C;
     style->main.margin_color = 0xFF181818;
     style->main.margin_hover_color = 0xFF252525;
@@ -2635,13 +2697,13 @@ app_hardcode_styles(App_Vars *vars){
     style->main.include_color = style->main.str_constant_color;
     style->main.preproc_color = style->main.default_color;
     style->main.special_character_color = 0xFFFF0000;
-    
+
     style->main.paste_color = 0xFFDDEE00;
     style->main.undo_color = 0xFF00DDEE;
-    
+
     style->main.highlight_junk_color = 0xff3a0000;
     style->main.highlight_white_color = 0xff003a3a;
-    
+
     file_info_style.bar_color = 0xFF888888;
     file_info_style.bar_active_color = 0xFF666666;
     file_info_style.base_color = 0xFF000000;
@@ -2650,17 +2712,17 @@ app_hardcode_styles(App_Vars *vars){
     style->main.file_info_style = file_info_style;
     style->font_changed = 1;
     ++style;
-    
+
     /////////////////
     *style = *(style-1);
     style_set_name(style, make_lit_string("4coder-mono"));
     style->font_id = fonts + 1;
     ++style;
-    
+
     /////////////////
     style_set_name(style, make_lit_string("Handmade Hero"));
     style->font_id = fonts + 1;
-    
+
     style->main.back_color = 0xFF161616;
     style->main.margin_color = 0xFF262626;
     style->main.margin_hover_color = 0xFF333333;
@@ -2668,7 +2730,7 @@ app_hardcode_styles(App_Vars *vars){
     style->main.cursor_color = 0xFF40FF40;
     style->main.at_cursor_color = style->main.back_color;
     style->main.mark_color = 0xFF808080;
-    style->main.highlight_color = 0xFF191970;
+    style->main.highlight_color = 0xFF703419;
     style->main.at_highlight_color = 0xFFCDAA7D;
     style->main.default_color = 0xFFCDAA7D;
     style->main.comment_color = 0xFF7F7F7F;
@@ -2681,14 +2743,14 @@ app_hardcode_styles(App_Vars *vars){
     style->main.include_color = style->main.str_constant_color;
     style->main.preproc_color = style->main.default_color;
     style->main.special_character_color = 0xFFFF0000;
-    
+
     style->main.paste_color = 0xFFFFBB00;
     style->main.undo_color = 0xFFFF00BB;
     style->main.undo_color = 0xFF80005D;
-    
+
     style->main.highlight_junk_color = 0xFF3A0000;
     style->main.highlight_white_color = 0xFF003A3A;
-    
+
     file_info_style.bar_color = 0xFFCACACA;
     file_info_style.bar_active_color = 0xFFA8A8A8;
     file_info_style.base_color = 0xFF000000;
@@ -2697,11 +2759,11 @@ app_hardcode_styles(App_Vars *vars){
     style->main.file_info_style = file_info_style;
     style->font_changed = 1;
     ++style;
-    
+
     /////////////////
     style_set_name(style, make_lit_string("Twilight"));
     style->font_id = fonts + 2;
-    
+
     style->main.back_color = 0xFF090D12;
     style->main.margin_color = 0xFF1A2634;
     style->main.margin_hover_color = 0xFF2D415B;
@@ -2722,13 +2784,13 @@ app_hardcode_styles(App_Vars *vars){
     style->main.include_color = style->main.str_constant_color;
     style->main.preproc_color = style->main.default_color;
     style->main.special_character_color = 0xFFFF0000;
-    
+
     style->main.paste_color = 0xFFDDEE00;
     style->main.undo_color = 0xFF00DDEE;
-    
+
     style->main.highlight_junk_color = 0xff3a0000;
     style->main.highlight_white_color = 0xFF151F2A;
-    
+
     file_info_style.bar_color = 0xFF315E68;
     file_info_style.bar_active_color = 0xFF0F3C46;
     file_info_style.base_color = 0xFF000000;
@@ -2737,11 +2799,11 @@ app_hardcode_styles(App_Vars *vars){
     style->main.file_info_style = file_info_style;
     style->font_changed = 1;
     ++style;
-    
+
     /////////////////
     style_set_name(style, make_lit_string("Wolverine"));
     style->font_id = fonts + 3;
-    
+
     style->main.back_color = 0xFF070711;
     style->main.margin_color = 0xFF111168;
     style->main.margin_hover_color = 0xFF191996;
@@ -2762,13 +2824,13 @@ app_hardcode_styles(App_Vars *vars){
     style->main.include_color = style->main.str_constant_color;
     style->main.preproc_color = style->main.default_color;
     style->main.special_character_color = 0xFFFF0000;
-    
+
     style->main.paste_color = 0xFF900090;
     style->main.undo_color = 0xFF606090;
-    
+
     style->main.highlight_junk_color = 0xff3a0000;
     style->main.highlight_white_color = 0xff003a3a;
-    
+
     file_info_style.bar_color = 0xFF7082F9;
     file_info_style.bar_active_color = 0xFF4E60D7;
     file_info_style.base_color = 0xFF000000;
@@ -2777,11 +2839,11 @@ app_hardcode_styles(App_Vars *vars){
     style->main.file_info_style = file_info_style;
     style->font_changed = 1;
     ++style;
-    
+
     /////////////////
     style_set_name(style, make_lit_string("stb"));
     style->font_id = fonts + 4;
-    
+
     style->main.back_color = 0xFFD6D6D6;
     style->main.margin_color = 0xFF9E9E9E;
     style->main.margin_hover_color = 0xFF7E7E7E;
@@ -2802,13 +2864,13 @@ app_hardcode_styles(App_Vars *vars){
     style->main.include_color = style->main.str_constant_color;
     style->main.preproc_color = style->main.default_color;
     style->main.special_character_color = 0xFF9A0000;
-    
+
     style->main.paste_color = 0xFF00B8B8;
     style->main.undo_color = 0xFFB800B8;
-    
+
     style->main.highlight_junk_color = 0xFFFF7878;
     style->main.highlight_white_color = 0xFFBCBCBC;
-    
+
     file_info_style.bar_color = 0xFF606060;
     file_info_style.bar_active_color = 0xFF3E3E3E;
     file_info_style.base_color = 0xFF000000;
@@ -2817,7 +2879,7 @@ app_hardcode_styles(App_Vars *vars){
     style->main.file_info_style = file_info_style;
     style->font_changed = 1;
     ++style;
-    
+
     vars->styles.count = (i32)(style - styles);
     vars->styles.max = ArrayCount(vars->styles.styles);
     style_copy(&vars->style, vars->styles.styles);
@@ -2858,7 +2920,7 @@ enum Command_Line_Action{
 
 void
 init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings,
-                           Command_Line_Parameters clparams){
+    Command_Line_Parameters clparams){
     char *arg;
     Command_Line_Action action = CLAct_Nothing;
     i32 i,index;
@@ -2939,14 +3001,14 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings,
                 plat_settings->maximize_window = 1;
                 action = CLAct_Nothing;
             }break;
-            
+
             case CLAct_WindowPosition:
             {
                 if (i + 1 < clparams.argc){
                     plat_settings->set_window_pos  = 1;
                     plat_settings->window_x = str_to_int(clparams.argv[i]);
                     plat_settings->window_y = str_to_int(clparams.argv[i+1]);
-                    
+
                     ++i;
                 }
                 action = CLAct_Nothing;
@@ -2962,9 +3024,9 @@ app_setup_memory(Application_Memory *memory){
     Assert(vars);
     *vars = {};
     vars->mem.part = _partition;
-    
+
     general_memory_open(&vars->mem.general, memory->target_memory, memory->target_memory_size);
-    
+
     return(vars);
 }
 
@@ -3006,32 +3068,32 @@ App_Read_Command_Line_Sig(app_read_command_line){
 }
 
 App_Init_Sig(app_init){
-    app_links_init(system);
-    
+    app_links_init(system, memory->user_memory, memory->user_memory_size);
+
     App_Vars *vars = (App_Vars*)memory->vars_memory;
     vars->config_api = api;
-    app_links.data = &vars->command_data;
-    
+    app_links.cmd_context = &vars->command_data;
+
     Partition *partition = &vars->mem.part;
     target->partition = partition;
-    
+
     i32 panel_max_count = vars->layout.panel_max_count = 16;
     i32 divider_max_count = panel_max_count - 1;
     vars->layout.panel_count = 1;
-    
+
     Panel *panels = vars->layout.panels =
         push_array(partition, Panel, panel_max_count);
-    
+
     Panel_Divider *dividers = vars->layout.dividers =
         push_array(partition, Panel_Divider, divider_max_count);
-    
+
     Panel_Divider *divider = dividers;
     for (i32 i = 0; i < divider_max_count-1; ++i, ++divider){
         divider->next_free = (divider + 1);
     }
     divider->next_free = 0;
     vars->layout.free_divider = dividers;
-    
+
     vars->live_set.count = 0;
     vars->live_set.max = 1 + 2*panel_max_count;
     i32 view_sizes[] = {
@@ -3043,7 +3105,7 @@ App_Init_Sig(app_init){
         sizeof(Debug_View),
 #endif
     };
-    
+
     i32 view_chunk_size = 0;
     for (i32 i = 0; i < ArrayCount(view_sizes); ++i){
         view_chunk_size = Max(view_chunk_size, view_sizes[i]);
@@ -3051,7 +3113,7 @@ App_Init_Sig(app_init){
     vars->live_set.stride = view_chunk_size;
     vars->live_set.views = (File_View*)
         push_block(partition, view_chunk_size*vars->live_set.max);
-    
+
     char *views_ = (char*)vars->live_set.views;
     for (i32 i = panel_max_count-2; i >= 0; --i){
         View *view = (View*)(views_ + i*view_chunk_size);
@@ -3063,9 +3125,9 @@ App_Init_Sig(app_init){
         view->next_free = 0;
     }
     vars->live_set.free_view = (View*)views_;
-    
+
     setup_command_table();
-    
+
     Command_Map *global = &vars->map_top;
     Assert(vars->config_api.get_bindings != 0);
 
@@ -3076,24 +3138,24 @@ App_Init_Sig(app_init){
         // So that it doesn't interfere with the command maps as they allocate
         // their own memory.
     i32 wanted_size = vars->config_api.get_bindings(data, size);
-    
+
     b32 did_top = 0;
     b32 did_file = 0;
     if (wanted_size <= size){
         partition_allocate(partition, wanted_size);
-        
+
         Binding_Unit *unit = (Binding_Unit*)data;
         if (unit->type == unit_header && unit->header.error == 0){
             Binding_Unit *end = unit + unit->header.total_size;
-            
+
             i32 user_map_count = unit->header.user_map_count;
-            
+
             vars->map_id_table = push_array(
                 &vars->mem.part, i32, user_map_count);
-            
+
             vars->user_maps = push_array(
                 &vars->mem.part, Command_Map, user_map_count);
-            
+
             vars->user_map_count = user_map_count;
 
             Command_Map *mapptr = 0;
@@ -3180,23 +3242,23 @@ App_Init_Sig(app_init){
             }
         }
     }
-    
+
     if (!did_top) setup_top_commands(&vars->map_top, &vars->mem.part, global);
     if (!did_file) setup_file_commands(&vars->map_file, &vars->mem.part, global);
-    
+
 #if !defined(FRED_SUPER)
     vars->hooks[hook_start] = 0;
 #endif
-    
+
     setup_ui_commands(&vars->map_ui, &vars->mem.part, global);
 #if FRED_INTERNAL
     setup_debug_commands(&vars->map_debug, &vars->mem.part, global);
 #endif
-    
+
     vars->font_set = &target->font_set;
-    
+
     font_set_init(vars->font_set, partition, 16, 4);
-    
+
     {
         struct Font_Setup{
             char *c_file_name;
@@ -3207,86 +3269,92 @@ App_Init_Sig(app_init){
         };
 
 #define LitStr(n) n, sizeof(n)-1
-        
+
         Font_Setup font_setup[] = {
             {LitStr("LiberationSans-Regular.ttf"),
-             LitStr("liberation sans"),
-             16},
+                LitStr("liberation sans"),
+                16},
 
             {LitStr("liberation-mono.ttf"),
-             LitStr("liberation mono"),
-             16},
-                        
+                LitStr("liberation mono"),
+                16},
+
             {LitStr("Hack-Regular.ttf"),
-             LitStr("hack"),
-             16},
-            
+                LitStr("hack"),
+                16},
+
             {LitStr("CutiveMono-Regular.ttf"),
-             LitStr("cutive mono"),
-             16},
-            
+                LitStr("cutive mono"),
+                16},
+
             {LitStr("Inconsolata-Regular.ttf"),
-             LitStr("inconsolata"),
-             16},
-            
+                LitStr("inconsolata"),
+                16},
+
         };
         i32 font_count = ArrayCount(font_setup);
-        
+
         for (i32 i = 0; i < font_count; ++i){
             String file_name = make_string(font_setup[i].c_file_name,
-                                           font_setup[i].file_name_len);
+                font_setup[i].file_name_len);
             String name = make_string(font_setup[i].c_name,
-                                      font_setup[i].name_len);
+                font_setup[i].name_len);
             i32 pt_size = font_setup[i].pt_size;
-            
+
             font_set_add(partition, vars->font_set, file_name, name, pt_size);
         }
     }
-    
+
     // NOTE(allen): file setup
     vars->working_set.file_index_count = 1;
     vars->working_set.file_max_count = 120;
     vars->working_set.files =
         push_array(partition, Editing_File, vars->working_set.file_max_count);
-    
+
     file_get_dummy(&vars->working_set.files[0]);
-    
+
     vars->working_set.table.max = vars->working_set.file_max_count * 3 / 2;
     vars->working_set.table.count = 0;
     vars->working_set.table.table =
         push_array(partition, File_Table_Entry, vars->working_set.table.max);
     memset(vars->working_set.table.table, 0, sizeof(File_Table_Entry) * vars->working_set.table.max);
-    
+
     // NOTE(allen): clipboard setup
     vars->working_set.clipboard_max_size = ArrayCount(vars->working_set.clipboards);
     vars->working_set.clipboard_size = 0;
     vars->working_set.clipboard_current = 0;
     vars->working_set.clipboard_rolling = 0;
-    
+
     // TODO(allen): more robust allocation solution for the clipboard
     if (clipboard.str){
         String *dest = working_set_next_clipboard_string(&vars->mem.general, &vars->working_set, clipboard.size);
         copy(dest, make_string((char*)clipboard.str, clipboard.size));
     }
-    
+
     // NOTE(allen): delay setup
-    vars->delay.max = 128;
-    vars->delay.acts = (Delayed_Action*)general_memory_allocate(
-        &vars->mem.general, vars->delay.max*sizeof(Delayed_Action), 0);
-    
+    vars->delay1.general = &vars->mem.general;
+    vars->delay1.max = 16;
+    vars->delay1.acts = (Delayed_Action*)general_memory_allocate(
+        &vars->mem.general, vars->delay1.max*sizeof(Delayed_Action), 0);
+
+    vars->delay2.general = &vars->mem.general;
+    vars->delay2.max = 16;
+    vars->delay2.acts = (Delayed_Action*)general_memory_allocate(
+        &vars->mem.general, vars->delay2.max*sizeof(Delayed_Action), 0);
+
     // NOTE(allen): style setup
     app_hardcode_styles(vars);
-    
+
     vars->palette_size = 40;
     vars->palette = push_array(partition, u32, vars->palette_size);
-    
+
     panel_init(&panels[0]);
 
     String hdbase = make_fixed_width_string(vars->hot_dir_base_);
     hot_directory_init(&vars->hot_directory, hdbase, current_directory, system->slash);
 
     vars->mini_str = make_string((char*)vars->mini_buffer, 0, 512);
-    
+
     // NOTE(allen): child proc list setup
     i32 max_children = 16;
     partition_align(partition, 8);
@@ -3304,31 +3372,31 @@ App_Step_Sig(app_step){
     ProfileStart(OS_syncing);
     Application_Step_Result app_result = *result;
     app_result.redraw = force_redraw;
-    
+
     App_Vars *vars = (App_Vars*)memory->vars_memory;
     target->partition = &vars->mem.part;
-    
+
     if (first_step || !time_step){
         app_result.redraw = 1;
     }
-    
+
     Panel *panels = vars->layout.panels;
     Panel *active_panel = &panels[vars->layout.active_panel];
-    
+
     // NOTE(allen): OS clipboard event handling
     if (clipboard.str){
         String *dest = working_set_next_clipboard_string(&vars->mem.general, &vars->working_set, clipboard.size);
         dest->size = eol_convert_in(dest->str, clipboard.str, clipboard.size);
     }
-    
+
     // TODO(allen): profile this make sure it's not costing me too much power.
     // NOTE(allen): check files are up to date
     for (i32 i = 0; i < vars->working_set.file_index_count; ++i){
         Editing_File *file = vars->working_set.files + i;
-        
+
         if (!file->state.is_dummy){
             u64 time_stamp = system->file_time_stamp(make_c_str(file->name.source_path));
-            
+
             if (time_stamp > 0){
                 file->state.last_sys_write_time = time_stamp;
                 if (file->state.last_sys_write_time != file->state.last_4ed_write_time){
@@ -3337,24 +3405,24 @@ App_Step_Sig(app_step){
             }
         }
     }
-    
+
     // NOTE(allen): update child processes
     if (time_step){
         Temp_Memory temp = begin_temp_memory(&vars->mem.part);
         u32 max = Kbytes(32);
         char *dest = push_array(&vars->mem.part, char, max);
         u32 amount;
-        
+
         i32 count = vars->cli_processes.count;
         for (i32 i = 0; i < count; ++i){
             CLI_Process *proc = vars->cli_processes.procs + i;
             Editing_File *out_file = proc->out_file;
-            
+
             if (out_file != 0){
                 i32 new_cursor = out_file->state.cursor_pos;
 
                 for (system->cli_begin_update(&proc->cli);
-                     system->cli_update_step(&proc->cli, dest, max, &amount);){
+                    system->cli_update_step(&proc->cli, dest, max, &amount);){
                     amount = eol_in_place_convert_in(dest, amount);
                     Edit_Spec spec = {};
                     spec.step.type = ED_NORMAL;
@@ -3365,11 +3433,11 @@ App_Step_Sig(app_step){
                     spec.step.post_pos = spec.step.edit.start + amount;
                     spec.str = (u8*)dest;
                     file_do_single_edit(system, &vars->mem, out_file,
-                                        &vars->layout, spec, hist_normal);
+                        &vars->layout, spec, hist_normal);
                     app_result.redraw = 1;
                     new_cursor = spec.step.post_pos;
                 }
-            
+
                 if (system->cli_end_update(&proc->cli)){
                     *proc = vars->cli_processes.procs[--count];
                     --i;
@@ -3378,7 +3446,7 @@ App_Step_Sig(app_step){
                     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);
@@ -3388,11 +3456,11 @@ App_Step_Sig(app_step){
                     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);
+                        &vars->layout, spec, hist_normal);
                     app_result.redraw = 1;
                     new_cursor = spec.step.post_pos;
                 }
-            
+
                 Panel *panel = vars->layout.panels;
                 i32 panel_count = vars->layout.panel_count;
                 for (i32 i = 0; i < panel_count; ++i, ++panel){
@@ -3405,24 +3473,24 @@ App_Step_Sig(app_step){
                 }
             }
         }
-        
+
         vars->cli_processes.count = count;
         end_temp_memory(temp);
     }
-    
+
     // NOTE(allen): reorganizing panels on screen
     i32 prev_width = vars->layout.full_width;
     i32 prev_height = vars->layout.full_height;
     i32 prev_y_off = 0;
     i32 prev_x_off = 0;
-    
+
     i32 y_off = 0;
     i32 x_off = 0;
     i32 full_width = vars->layout.full_width = target->width;
     i32 full_height = vars->layout.full_height = target->height;
-    
+
     if (prev_width != full_width || prev_height != full_height ||
-        prev_x_off != x_off || prev_y_off != y_off){
+            prev_x_off != x_off || prev_y_off != y_off){
         layout_refit(&vars->layout, prev_x_off, prev_y_off, prev_width, prev_height);
         int view_count = vars->layout.panel_max_count;
         for (i32 view_i = 0; view_i < view_count; ++view_i){
@@ -3435,7 +3503,7 @@ App_Step_Sig(app_step){
         }
         app_result.redraw = 1;
     }
-    
+
     // NOTE(allen): prepare input information
     Key_Summary key_data = {};
     for (i32 i = 0; i < input->press_count; ++i){
@@ -3444,11 +3512,11 @@ App_Step_Sig(app_step){
     for (i32 i = 0; i < input->hold_count; ++i){
         key_data.keys[key_data.count++] = input->hold[i];
     }
-    
+
     mouse->wheel = -mouse->wheel;
-    
+
     ProfileEnd(OS_syncing);
-    
+
     ProfileStart(hover_status);
     // NOTE(allen): detect mouse hover status
     i32 mx = mouse->x;
@@ -3458,7 +3526,7 @@ App_Step_Sig(app_step){
     Panel *mouse_panel = 0;
     i32 mouse_panel_i = 0;
     i32 panel_count = vars->layout.panel_count;
-    
+
     mouse_panel = panels;
     for (mouse_panel_i = 0; mouse_panel_i < panel_count; ++mouse_panel_i, ++mouse_panel){
         if (hit_check(mx, my, mouse_panel->inner)){
@@ -3470,17 +3538,17 @@ App_Step_Sig(app_step){
             break;
         }
     }
-    
+
     if (!(mouse_in_edit_area || mouse_in_margin_area)){
         mouse_panel = 0;
         mouse_panel_i = 0;
     }
-    
+
     b32 mouse_on_divider = 0;
     b32 mouse_divider_vertical = 0;
     i32 mouse_divider_id = 0;
     i32 mouse_divider_side = 0;
-    
+
     if (mouse_in_margin_area){
         Panel *panel = mouse_panel;
         if (mx >= panel->inner.x0 && mx < panel->inner.x1){
@@ -3501,20 +3569,20 @@ App_Step_Sig(app_step){
                 mouse_divider_side = 1;
             }
         }
-        
+
         if (vars->layout.panel_count > 1){
             i32 which_child;
             mouse_divider_id = panel->parent;
             which_child = panel->which_child;
             for (;;){
                 Divider_And_ID div = layout_get_divider(&vars->layout, mouse_divider_id);
-                
+
                 if (which_child == mouse_divider_side &&
-                    div.divider->v_divider == mouse_divider_vertical){
+                        div.divider->v_divider == mouse_divider_vertical){
                     mouse_on_divider = 1;
                     break;
                 }
-                
+
                 if (mouse_divider_id == vars->layout.root){
                     break;
                 }
@@ -3530,11 +3598,11 @@ App_Step_Sig(app_step){
         }
     }
     ProfileEnd(hover_status);
-    
+
     // NOTE(allen): prepare to start executing commands
     ProfileStart(command_coroutine);
     Command_Data *cmd = &vars->command_data;
-    
+
     cmd->mem = &vars->mem;
     cmd->panel = active_panel;
     cmd->view = active_panel->view;
@@ -3542,60 +3610,52 @@ App_Step_Sig(app_step){
     cmd->layout = &vars->layout;
     cmd->live_set = &vars->live_set;
     cmd->style = &vars->style;
-    cmd->delay = &vars->delay;
+    cmd->delay = &vars->delay1;
     cmd->vars = vars;
     cmd->exchange = exchange;
     cmd->screen_width = target->width;
     cmd->screen_height = target->height;
     cmd->system = system;
-    
+
     Temp_Memory param_stack_temp = begin_temp_memory(&vars->mem.part);
     cmd->part = partition_sub_part(&vars->mem.part, 16 << 10);
-    
+
     if (first_step){
         if (vars->hooks[hook_start]){
             vars->hooks[hook_start](&app_links);
             cmd->part.pos = 0;
         }
-        
+
         i32 i;
         String file_name;
-        File_View *fview;
-        Editing_File *file;
         Panel *panel = vars->layout.panels;
         for (i = 0; i < vars->settings.init_files_count; ++i, ++panel){
             file_name = make_string_slowly(vars->settings.init_files[i]);
-            
+
             if (i < vars->layout.panel_count){
-                fview = app_open_file(system, vars, exchange, &vars->live_set, &vars->working_set, panel, cmd, file_name);
-                
+                delayed_open(&vars->delay1, file_name, panel);
                 if (i == 0){
-                    if (fview){
-                        file = fview->file;
-                        if (file){
-                            file->preload.start_line = vars->settings.initial_line;
-                        }
-                    }
+                    delayed_set_line(&vars->delay1, panel, vars->settings.initial_line);
                 }
             }
             else{
-                app_open_file_background(vars, exchange, &vars->working_set, file_name);
+                delayed_open_background(&vars->delay1, file_name);
             }
         }
     }
     ProfileEnd(hover_status);
-    
+
     // NOTE(allen): process the command_coroutine if it is unfinished
     ProfileStart(command_coroutine);
     b8 consumed_input[6] = {0};
-    
+
     if (vars->command_coroutine != 0){
         Coroutine *command_coroutine = vars->command_coroutine;
         u32 get_flags = vars->command_coroutine_flags[0];
         u32 abort_flags = vars->command_coroutine_flags[1];
-        
+
         get_flags |= abort_flags;
-        
+
         if ((get_flags & EventOnAnyKey) || (get_flags & EventOnEsc)){
             for (i32 key_i = 0; key_i < key_data.count; ++key_i){
                 Key_Event_Data key = get_single_key(&key_data, key_i);
@@ -3613,14 +3673,14 @@ App_Step_Sig(app_step){
                 user_in.key = key;
                 user_in.command = (unsigned long long)cmd_bind.custom;
                 user_in.abort = 0;
-                
+
                 if ((EventOnEsc & abort_flags) && key.keycode == key_esc){
                     user_in.abort = 1;
                 }
                 else if (EventOnAnyKey & abort_flags){
                     user_in.abort = 1;
                 }
-                
+
                 if (EventOnAnyKey & get_flags){
                     pass_in = 1;
                     consumed_input[0] = 1;
@@ -3631,16 +3691,16 @@ App_Step_Sig(app_step){
                     }
                     consumed_input[1] = 1;
                 }
-                
+
                 if (pass_in){
                     cmd->current_coroutine = vars->command_coroutine;
-                    vars->command_coroutine = system->resume_coroutine(command_coroutine, &user_in,
-                        vars->command_coroutine_flags);
+                    vars->command_coroutine = system->resume_coroutine(command_coroutine,
+                        &user_in, vars->command_coroutine_flags);
                     app_result.redraw = 1;
-                    
+
                     // TOOD(allen): Deduplicate
-                    // TODO(allen): Allow a view to clean up however it wants after a command finishes,
-                    // or after transfering to another view mid command.
+                    // TODO(allen): Allow a view to clean up however it wants after a command 
+                    // finishes, or after transfering to another view mid command.
                     File_View *fview = view_to_file_view(view);
                     if (fview != 0 && vars->command_coroutine == 0){
                         init_query_set(&fview->query_set);
@@ -3649,16 +3709,17 @@ App_Step_Sig(app_step){
                 }
             }
         }
-        
+
         if (vars->command_coroutine != 0 && (get_flags & EventOnMouse)){
             View *view = active_panel->view;
             b32 pass_in = 0;
-            
+
             User_Input user_in;
             user_in.type = UserInputMouse;
             user_in.mouse = *mouse;
+            user_in.command = 0;
             user_in.abort = 0;
-            
+
             if (abort_flags & EventOnMouseMove){
                 user_in.abort = 1;
             }
@@ -3666,7 +3727,7 @@ App_Step_Sig(app_step){
                 pass_in = 1;
                 consumed_input[2] = 1;
             }
-            
+
             if (mouse->press_l || mouse->release_l || mouse->l){
                 if (abort_flags & EventOnLeftButton){
                     user_in.abort = 1;
@@ -3676,7 +3737,7 @@ App_Step_Sig(app_step){
                     consumed_input[3] = 1;
                 }
             }
-            
+
             if (mouse->press_r || mouse->release_r || mouse->r){
                 if (abort_flags & EventOnRightButton){
                     user_in.abort = 1;
@@ -3686,7 +3747,7 @@ App_Step_Sig(app_step){
                     consumed_input[4] = 1;
                 }
             }
-            
+
             if (mouse->wheel != 0){
                 if (abort_flags & EventOnWheel){
                     user_in.abort = 1;
@@ -3696,7 +3757,7 @@ App_Step_Sig(app_step){
                     consumed_input[5] = 1;
                 }
             }
-            
+
             if (pass_in){
                 cmd->current_coroutine = vars->command_coroutine;
                 vars->command_coroutine = system->resume_coroutine(command_coroutine, &user_in,
@@ -3714,79 +3775,15 @@ App_Step_Sig(app_step){
         }
     }
     ProfileEnd(command_coroutine);
-    
-    // NOTE(allen): command execution
-    ProfileStart(command);
-    
-    cmd->panel = active_panel;
-    cmd->view = active_panel->view;
-    
-    if (!consumed_input[0] || !consumed_input[1]){
-        b32 consumed_input2[2] = {0};
-        
-        for (i32 key_i = 0; key_i < key_data.count; ++key_i){
-            switch (vars->state){
-                case APP_STATE_EDIT:
-                {
-                    Key_Event_Data key = get_single_key(&key_data, key_i);
-                    b32 hit_esc = (key.keycode == key_esc);
-                    cmd->key = key;
-                    
-                    if (hit_esc || !consumed_input[0]){
-                        if (hit_esc){
-                            consumed_input[0] = 1;
-                        }
-                        else{
-                            consumed_input[1] = 1;
-                        }
-                        
-                        View *view = active_panel->view;
-                        
-                        Command_Map *map = 0;
-                        if (view) map = view->map;
-                        if (map == 0) map = &vars->map_top;
-                        Command_Binding cmd_bind = map_extract_recursive(map, key);
-                        
-                        if (cmd_bind.function){
-                            Coroutine *command_coroutine = system->create_coroutine(command_caller);
-                            vars->command_coroutine = command_coroutine;
 
-                            Command_In cmd_in;
-                            cmd_in.cmd = cmd;
-                            cmd_in.bind = cmd_bind;
-                            
-                            cmd->current_coroutine = vars->command_coroutine;
-                            vars->command_coroutine = system->launch_coroutine(vars->command_coroutine,
-                                &cmd_in, vars->command_coroutine_flags);
-                            app_result.redraw = 1;
-                        }
-                    }
-                }break;
-                
-                case APP_STATE_RESIZING:
-                {
-                    if (key_data.count > 0){
-                        vars->state = APP_STATE_EDIT;
-                    }
-                }break;
-            }
-        }
-        
-        consumed_input[0] |= consumed_input2[0];
-        consumed_input[1] |= consumed_input2[1];
-    }
-    
-    active_panel = panels + vars->layout.active_panel;
-    ProfileEnd(command);
-    
     // NOTE(allen): pass raw input to the panels
     ProfileStart(step);
     View *active_view = active_panel->view;
-    
+
     Input_Summary dead_input = {};
     dead_input.mouse.x = mouse->x;
     dead_input.mouse.y = mouse->y;
-    
+
     Input_Summary active_input = {};
     active_input.mouse.x = mouse->x;
     active_input.mouse.y = mouse->y;
@@ -3803,25 +3800,25 @@ App_Step_Sig(app_step){
             }
         }
     }
-    
+
     Mouse_State mouse_state = *mouse;
-    
+
     if (consumed_input[3]){
         mouse_state.l = 0;
         mouse_state.press_l = 0;
         mouse_state.release_l = 0;
     }
-    
+
     if (consumed_input[4]){
         mouse_state.r = 0;
         mouse_state.press_r = 0;
         mouse_state.release_r = 0;
     }
-    
+
     if (consumed_input[5]){
         mouse_state.wheel = 0;
     }
-    
+
     {
         Panel *panel = panels;
         for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){
@@ -3834,111 +3831,176 @@ App_Step_Sig(app_step){
                     input.mouse = mouse_state;
                 }
                 if (view_->do_view(system, exchange, view_, panel->inner, active_view,
-                                   VMSG_STEP, 0, &input, &active_input)){
+                        VMSG_STEP, 0, &input, &active_input)){
                     app_result.redraw = 1;
                 }
             }
         }
     }
     ProfileEnd(step);
-    
+
+    // NOTE(allen): command execution
+    ProfileStart(command);
+
+    cmd->panel = active_panel;
+    cmd->view = active_panel->view;
+
+    if (!consumed_input[0] || !consumed_input[1]){
+        b32 consumed_input2[2] = {0};
+
+        for (i32 key_i = 0; key_i < key_data.count; ++key_i){
+            switch (vars->state){
+                case APP_STATE_EDIT:
+                {
+                    Key_Event_Data key = get_single_key(&key_data, key_i);
+                    b32 hit_esc = (key.keycode == key_esc);
+                    cmd->key = key;
+
+                    if (hit_esc || !consumed_input[0]){
+                        View *view = active_panel->view;
+
+                        Command_Map *map = 0;
+                        if (view) map = view->map;
+                        if (map == 0) map = &vars->map_top;
+                        Command_Binding cmd_bind = map_extract_recursive(map, key);
+
+                        if (cmd_bind.function){
+                            if (hit_esc){
+                                consumed_input2[1] = 1;
+                            }
+                            else{
+                                consumed_input2[0] = 1;
+                            }
+                            
+                            Coroutine *command_coroutine = system->create_coroutine(command_caller);
+                            vars->command_coroutine = command_coroutine;
+
+                            Command_In cmd_in;
+                            cmd_in.cmd = cmd;
+                            cmd_in.bind = cmd_bind;
+
+                            cmd->current_coroutine = vars->command_coroutine;
+                            vars->command_coroutine = system->launch_coroutine(vars->command_coroutine,
+                                &cmd_in, vars->command_coroutine_flags);
+                            vars->prev_command = cmd_bind;
+                            app_result.redraw = 1;
+                        }
+                    }
+                }break;
+
+                case APP_STATE_RESIZING:
+                {
+                    if (key_data.count > 0){
+                        vars->state = APP_STATE_EDIT;
+                    }
+                }break;
+            }
+        }
+
+        consumed_input[0] |= consumed_input2[0];
+        consumed_input[1] |= consumed_input2[1];
+    }
+
+    active_panel = panels + vars->layout.active_panel;
+    ProfileEnd(command);
+
     ProfileStart(resizing);
     // NOTE(allen): panel resizing
     switch (vars->state){
-    case APP_STATE_EDIT:
-    {
-        if (mouse->press_l && mouse_on_divider){
-            vars->state = APP_STATE_RESIZING;
-            Divider_And_ID div = layout_get_divider(&vars->layout, mouse_divider_id);
-            vars->resizing.divider = div.divider;
-            
-            i32 min, max;
-            {
-                i32 mid, MIN, MAX;
-                mid = div.divider->pos;
-                if (mouse_divider_vertical){
-                    MIN = 0;
-                    MAX = MIN + vars->layout.full_width;
+        case APP_STATE_EDIT:
+        {
+            if (mouse->press_l && mouse_on_divider){
+                vars->state = APP_STATE_RESIZING;
+                Divider_And_ID div = layout_get_divider(&vars->layout, mouse_divider_id);
+                vars->resizing.divider = div.divider;
+
+                i32 min, max;
+                {
+                    i32 mid, MIN, MAX;
+                    mid = div.divider->pos;
+                    if (mouse_divider_vertical){
+                        MIN = 0;
+                        MAX = MIN + vars->layout.full_width;
+                    }
+                    else{
+                        MIN = 0;
+                        MAX = MIN + vars->layout.full_height;
+                    }
+                    min = MIN;
+                    max = MAX;
+
+                    i32 divider_id = div.id;
+                    do{
+                        Divider_And_ID other_div = layout_get_divider(&vars->layout, divider_id);
+                        b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical);
+                        i32 pos = other_div.divider->pos;
+                        if (divider_match && pos > mid && pos < max){
+                            max = pos;
+                        }
+                        else if (divider_match && pos < mid && pos > min){
+                            min = pos;
+                        }
+                        divider_id = other_div.divider->parent;
+                    }while(divider_id != -1);
+
+                    Temp_Memory temp = begin_temp_memory(&vars->mem.part);
+                    i32 *divider_stack = push_array(&vars->mem.part, i32, vars->layout.panel_count);
+                    i32 top = 0;
+                    divider_stack[top++] = div.id;
+
+                    while (top > 0){
+                        Divider_And_ID other_div = layout_get_divider(&vars->layout, divider_stack[--top]);
+                        b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical);
+                        i32 pos = other_div.divider->pos;
+                        if (divider_match && pos > mid && pos < max){
+                            max = pos;
+                        }
+                        else if (divider_match && pos < mid && pos > min){
+                            min = pos;
+                        }
+                        if (other_div.divider->child1 != -1){
+                            divider_stack[top++] = other_div.divider->child1;
+                        }
+                        if (other_div.divider->child2 != -1){
+                            divider_stack[top++] = other_div.divider->child2;
+                        }
+                    }
+
+                    end_temp_memory(temp);
+                }
+
+                vars->resizing.min = min;
+                vars->resizing.max = max;
+            }
+        }break;
+
+        case APP_STATE_RESIZING:
+        {
+            app_result.redraw = 1;
+            if (mouse->l){
+                Panel_Divider *divider = vars->resizing.divider;
+                if (divider->v_divider){
+                    divider->pos = mx;
                 }
                 else{
-                    MIN = 0;
-                    MAX = MIN + vars->layout.full_height;
+                    divider->pos = my;
                 }
-                min = MIN;
-                max = MAX;
-                
-                i32 divider_id = div.id;
-                do{
-                    Divider_And_ID other_div = layout_get_divider(&vars->layout, divider_id);
-                    b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical);
-                    i32 pos = other_div.divider->pos;
-                    if (divider_match && pos > mid && pos < max){
-                        max = pos;
-                    }
-                    else if (divider_match && pos < mid && pos > min){
-                        min = pos;
-                    }
-                    divider_id = other_div.divider->parent;
-                }while(divider_id != -1);
-                
-                Temp_Memory temp = begin_temp_memory(&vars->mem.part);
-                i32 *divider_stack = push_array(&vars->mem.part, i32, vars->layout.panel_count);
-                i32 top = 0;
-                divider_stack[top++] = div.id;
-                
-                while (top > 0){
-                    Divider_And_ID other_div = layout_get_divider(&vars->layout, divider_stack[--top]);
-                    b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical);
-                    i32 pos = other_div.divider->pos;
-                    if (divider_match && pos > mid && pos < max){
-                        max = pos;
-                    }
-                    else if (divider_match && pos < mid && pos > min){
-                        min = pos;
-                    }
-                    if (other_div.divider->child1 != -1){
-                        divider_stack[top++] = other_div.divider->child1;
-                    }
-                    if (other_div.divider->child2 != -1){
-                        divider_stack[top++] = other_div.divider->child2;
-                    }
+
+                if (divider->pos < vars->resizing.min){
+                    divider->pos = vars->resizing.min;
                 }
-                
-                end_temp_memory(temp);
-            }
-            
-            vars->resizing.min = min;
-            vars->resizing.max = max;
-        }
-    }break;
-    
-    case APP_STATE_RESIZING:
-    {
-        app_result.redraw = 1;
-        if (mouse->l){
-            Panel_Divider *divider = vars->resizing.divider;
-            if (divider->v_divider){
-                divider->pos = mx;
+                else if (divider->pos > vars->resizing.max){
+                    divider->pos = vars->resizing.max - 1;
+                }
+
+                layout_fix_all_panels(&vars->layout);
             }
             else{
-                divider->pos = my;
+                vars->state = APP_STATE_EDIT;
             }
-            
-            if (divider->pos < vars->resizing.min){
-                divider->pos = vars->resizing.min;
-            }
-            else if (divider->pos > vars->resizing.max){
-                divider->pos = vars->resizing.max - 1;
-            }
-            
-            layout_fix_all_panels(&vars->layout);
-        }
-        else{
-            vars->state = APP_STATE_EDIT;
-        }
-    }break;
+        }break;
     }
-    
+
     if (mouse_in_edit_area && mouse_panel != 0 && mouse->press_l){
         active_panel = mouse_panel;
         vars->layout.active_panel = mouse_panel_i;
@@ -3946,238 +4008,22 @@ App_Step_Sig(app_step){
     }
     ProfileEnd(resizing);
     
-    // NOTE(allen): process as many delayed actions as possible
-    ProfileStart(delayed_actions);
-    if (vars->delay.count > 0){
-        Style *style = &vars->style;
-        Working_Set *working_set = &vars->working_set;
-        Live_Views *live_set = &vars->live_set;
-        Mem_Options *mem = &vars->mem;
-        General_Memory *general = &vars->mem.general;
-        
-        i32 count = vars->delay.count;
-        vars->delay.count = 0;
-        
-        for (i32 i = 0; i < count; ++i){
-            Delayed_Action *act = vars->delay.acts + i;
-            String *string = &act->string;
-            Panel *panel = act->panel;
-            Editing_File *file = act->file;
-            
-            switch (act->type){
-            case DACT_OPEN:
-            {
-                cmd->view = (View*)
-                    app_open_file(system, vars, exchange,
-                                  live_set, working_set, panel,
-                                  cmd, *string);
-            }break;
-            
-            case DACT_SAVE_AS:
-            {
-                if (!file){
-                    View *view = panel->view;
-                    File_View *fview = view_to_file_view(view);
-                    
-                    if (!fview && view->is_minor) fview = view_to_file_view(view->major);
-                    
-                    if (fview){
-                        file = working_set_lookup_file(working_set, *string);
-                    }
-                }
-                if (file && !file->state.is_dummy){
-                    i32 sys_id = file_save_and_set_names(system, exchange, mem, working_set, file, string->str);
-                    app_push_file_binding(vars, sys_id, get_file_id(working_set, file));
-                }
-            }break;
-            
-            case DACT_SAVE:
-            {
-                if (!file){
-                    file = working_set_lookup_file(working_set, *string);
-                }
-                if (!file->state.is_dummy && buffer_needs_save(file)){
-                    i32 sys_id = file_save(system, exchange, mem, file, file->name.source_path.str);
-                    app_push_file_binding(vars, sys_id, get_file_id(working_set, file));
-                }
-            }break;
-            
-            case DACT_NEW:
-            {
-                Get_File_Result file = working_set_get_available_file(working_set);
-                file_create_empty(system, mem, working_set, file.file, string->str,
-                                  vars->font_set, style->font_id);
-                table_add(&working_set->table, file.file->name.source_path, file.index);
-                
-                View *new_view = live_set_alloc_view(live_set, mem);
-                view_replace_major(system, exchange, new_view, panel, live_set);
-                
-                File_View *file_view = file_view_init(new_view, &vars->layout);
-                cmd->view = (View*)file_view;
-                view_set_file(system, file_view, file.file, vars->font_set, style,
-                              vars->hooks[hook_open_file], cmd, &app_links);
-                new_view->map = app_get_map(vars, file.file->settings.base_map_id);
-#if BUFFER_EXPERIMENT_SCALPEL <= 0
-                if (file.file->settings.tokens_exist)
-                    file_first_lex_parallel(system, general, file.file);
-#endif
-            }break;
-            
-            case DACT_SWITCH:
-            {
-                Editing_File *file = working_set_lookup_file(working_set, *string);
-                if (file){
-                    View *new_view = live_set_alloc_view(live_set, mem);
-                    view_replace_major(system, exchange, new_view, panel, live_set);
-                    
-                    File_View *file_view = file_view_init(new_view, &vars->layout);
-                    cmd->view = (View*)file_view;
-                    
-                    view_set_file(system, file_view, file, vars->font_set, style,
-                                  vars->hooks[hook_open_file], cmd, &app_links);
-                    
-                    new_view->map = app_get_map(vars, file->settings.base_map_id);
-                }
-            }break;
-            
-            case DACT_KILL:
-            {
-                Editing_File *file = working_set_lookup_file(working_set, *string);
-                if (file){
-                    table_remove(&working_set->table, file->name.source_path);
-                    kill_file(system, exchange, general, file, live_set, &vars->layout);
-                }
-            }break;
-            
-            case DACT_TRY_KILL:
-            {
-                Editing_File *file = working_set_lookup_file(working_set, *string);
-                if (file){
-                    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,
-                                                  working_set, vars->font_set, &vars->delay);
-                        int_view->interaction = INTV_SURE_TO_KILL_INTER;
-                        int_view->action = INTV_SURE_TO_KILL;
-                        copy(&int_view->query, "Are you sure?");
-                        copy(&int_view->dest, file->name.live_name);
-                    }
-                    else{
-                        table_remove(&working_set->table, file->name.source_path);
-                        kill_file(system, exchange, general, file, live_set, &vars->layout);
-                        view_remove_minor(system, exchange, panel, live_set);
-                    }
-                }
-            }break;
-            
-            case DACT_CLOSE_MINOR:
-            {
-                view_remove_minor(system, exchange, panel, live_set);
-            }break;
-            
-            case DACT_CLOSE_MAJOR:
-            {
-                view_remove_major(system, exchange, panel, live_set);
-            }break;
-            
-            case DACT_THEME_OPTIONS:
-            {
-                open_theme_options(system, exchange, vars, live_set, mem, panel);
-            }break;
-
-            case DACT_KEYBOARD_OPTIONS:
-            {
-                open_config_options(system, exchange, vars, live_set, mem, panel);
-            }break;
-            }
-        }
-    }
-    ProfileEnd(delayed_actions);
-    
-    end_temp_memory(param_stack_temp);
-    
-    ProfileStart(resize);
-    // NOTE(allen): send resize messages to panels that have changed size
-    {
-        Panel *panel = panels;
-        for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){
-            i32_Rect prev = panel->prev_inner;
-            i32_Rect inner = panel->inner;
-            if (prev.x0 != inner.x0 || prev.y0 != inner.y0 ||
-                prev.x1 != inner.x1 || prev.y1 != inner.y1){
-                View *view = panel->view;
-                if (view){
-                    view->do_view(system, exchange,
-                                  view, inner, active_view,
-                                  VMSG_RESIZE, 0, &dead_input, &active_input);
-                    view = (view->is_minor)?view->major:0;
-                    if (view){
-                        view->do_view(system, exchange,
-                                      view, inner, active_view,
-                                      VMSG_RESIZE, 0, &dead_input, &active_input);
-                    }
-                }
-            }
-            panel->prev_inner = inner;
-        }
-    }
-    ProfileEnd(resize);
-    
-    ProfileStart(style_change);
-    // NOTE(allen): send style change messages if the style has changed
-    if (vars->style.font_changed){
-        vars->style.font_changed = 0;
-
-        Editing_File *file = vars->working_set.files;
-        for (i32 i = vars->working_set.file_index_count; i > 0; --i, ++file){
-            if (buffer_good(&file->state.buffer) && !file->state.is_dummy){
-                Render_Font *font = get_font_info(vars->font_set, vars->style.font_id)->font;
-                float *advance_data = 0;
-                if (font) advance_data = font->advance_data;
-                
-                file_measure_starts_widths(system, &vars->mem.general,
-                                           &file->state.buffer, advance_data);
-            }
-        }
-        
-        Panel *panel = panels;
-        for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){
-            View *view = panel->view;
-            if (view){
-                view->do_view(system, exchange,
-                              view, panel->inner, active_view,
-                              VMSG_STYLE_CHANGE, 0, &dead_input, &active_input);
-                view = (view->is_minor)?view->major:0;
-                if (view){
-                    view->do_view(system, exchange,
-                                  view, panel->inner, active_view,
-                                  VMSG_STYLE_CHANGE, 0, &dead_input, &active_input);
-                }
-            }
-        }
-    }
-    ProfileEnd(style_change);
-
-    // NOTE(allen): processing bindings between system and application
+    // NOTE(allen): processing sys app bindings
     ProfileStart(sys_app_bind_processing);
     for (i32 i = 0; i < vars->sys_app_count; ++i){
         Sys_App_Binding *binding;
         b32 remove = 0;
         b32 failed = 0;
         binding = vars->sys_app_bindings + i;
-        
+
         byte *data;
         i32 size, max;
         Editing_File *ed_file;
         Editing_File_Preload preload_settings;
         char *filename;
-        
+
         Working_Set *working_set = &vars->working_set;
-        
+
         if (exchange_file_ready(exchange, binding->sys_id, &data, &size, &max)){
             ed_file = working_set->files + binding->app_id;
             filename = exchange_file_filename(exchange, binding->sys_id);
@@ -4185,21 +4031,41 @@ App_Step_Sig(app_step){
             if (data){
                 String val = make_string((char*)data, size);
                 file_create_from_string(system, &vars->mem, working_set, ed_file, filename,
-                                        vars->font_set, vars->style.font_id, val);
-                
-                if (ed_file->settings.tokens_exist)
+                    vars->font_set, vars->style.font_id, val);
+
+                if (ed_file->settings.tokens_exist){
                     file_first_lex_parallel(system, &vars->mem.general, ed_file);
+                }
+                
+                if ((binding->success & SysAppCreateView) && binding->panel != 0){
+                    view_file_in_panel(cmd, binding->panel, ed_file);
+                }
+                
+                app_result.redraw = 1;
             }
             else{
-                file_create_empty(system, &vars->mem, working_set, ed_file, filename,
-                                  vars->font_set, vars->style.font_id);
+                if (binding->fail & SysAppCreateNewBuffer){
+                    file_create_empty(system, &vars->mem, working_set, ed_file, filename,
+                        vars->font_set, vars->style.font_id);
+                    if (binding->fail & SysAppCreateView){
+                        view_file_in_panel(cmd, binding->panel, ed_file);
+                    }
+                }
+                else{
+                    table_remove(&vars->working_set.table, ed_file->name.source_path);
+                    file_get_dummy(ed_file);
+                }
+                
+                app_result.redraw = 1;
             }
-
-            for (File_View_Iter iter = file_view_iter_init(&vars->layout, ed_file, 0);
-                file_view_iter_good(iter);
-                iter = file_view_iter_next(iter)){
-                view_file_loaded_init(system, iter.view, 0);
-                view_cursor_move(iter.view, preload_settings.start_line, 0);
+            
+            if (!ed_file->state.is_dummy){
+                for (File_View_Iter iter = file_view_iter_init(&vars->layout, ed_file, 0);
+                    file_view_iter_good(iter);
+                    iter = file_view_iter_next(iter)){
+                    view_file_loaded_init(system, iter.view, 0);
+                    view_cursor_move(iter.view, preload_settings.start_line, 0);
+                }
             }
             
             exchange_free_file(exchange, binding->sys_id);
@@ -4232,6 +4098,305 @@ App_Step_Sig(app_step){
     }
     ProfileEnd(sys_app_bind_processing);
     
+    // NOTE(allen): process as many delayed actions as possible
+    ProfileStart(delayed_actions);
+    if (vars->delay1.count > 0){
+        Style *style = &vars->style;
+        Working_Set *working_set = &vars->working_set;
+        Live_Views *live_set = &vars->live_set;
+        Mem_Options *mem = &vars->mem;
+        General_Memory *general = &vars->mem.general;
+        
+        i32 count = vars->delay1.count;
+        vars->delay1.count = 0;
+        vars->delay2.count = 0;
+        
+        Delayed_Action *act = vars->delay1.acts;
+        for (i32 i = 0; i < count; ++i, ++act){
+            String string = act->string;
+            Panel *panel = act->panel;
+            Editing_File *file = act->file;
+            i32 integer = act->integer;
+            
+            // TODO(allen): Paramter checking in each DACT case.
+            switch (act->type){
+                case DACT_OPEN:
+                {
+                    App_Open_File_Result result;
+                    
+                    result = app_open_file_background(vars, exchange, working_set, string);
+                    
+                    if (result.is_new){
+                        if (result.file){
+                            if (result.sys_id){
+                                Sys_App_Binding *binding = app_push_file_binding(vars, result.sys_id, result.file_index);
+                                binding->success = SysAppCreateView;
+                                binding->fail = 0;
+                                binding->panel = panel;
+                            }
+                            else{
+                                delayed_action_repush(&vars->delay2, act);
+                            }
+                        }
+                    }
+                    else{
+                        if (result.file->state.is_dummy || result.file->state.is_loading){
+                            // do nothing
+                        }
+                        else{
+                            view_file_in_panel(cmd, panel, result.file);
+                        }
+                    }
+                }break;
+                
+                case DACT_OPEN_BACKGROUND:
+                {
+                    App_Open_File_Result result;
+                    result = app_open_file_background(vars, exchange, working_set, string);
+                    if (result.is_new && result.file == 0){
+                        delayed_action_repush(&vars->delay2, act);
+                    }
+                    else{
+                        Sys_App_Binding *binding = app_push_file_binding(vars, result.sys_id, result.file_index);
+                        binding->success = 0;
+                        binding->fail = 0;
+                        binding->panel = panel;
+                    }
+                }break;
+                
+                case DACT_SET_LINE:
+                {
+                    // TODO(allen): deduplicate
+                    View *view = panel->view;
+                    File_View *fview = view_to_file_view(view);
+                    if (!file){
+                        if (!fview && view->is_minor) fview = view_to_file_view(view->major);
+                        if (fview){
+                            file = working_set_lookup_file(working_set, string);
+                        }
+                    }
+                    if (file && !file->state.is_dummy){
+                        if (file->state.is_loading){
+                            file->preload.start_line = integer;
+                        }
+                        else{
+                            view_cursor_move(fview, integer, 0);
+                        }
+                    }
+                }break;
+
+                case DACT_SAVE_AS:
+                {
+                    // TODO(allen): deduplicate
+                    View *view = panel->view;
+                    File_View *fview = view_to_file_view(view);
+                    if (!file){
+                        if (!fview && view->is_minor) fview = view_to_file_view(view->major);
+                        if (fview){
+                            file = working_set_lookup_file(working_set, string);
+                        }
+                    }
+                    if (file && !file->state.is_dummy){
+                        i32 sys_id = file_save_and_set_names(system, exchange, mem, working_set, file, string.str);
+                        if (sys_id){
+                            app_push_file_binding(vars, sys_id, get_file_id(working_set, file));
+                        }
+                        else{
+                            delayed_action_repush(&vars->delay2, act);
+                        }
+                    }
+                }break;
+                
+                case DACT_SAVE:
+                {
+                    if (!file){
+                        if (panel){
+                            View *view = panel->view;
+                            File_View *fview = view_to_file_view(view);
+                            if (fview){
+                                file = fview->file;
+                            }
+                        }
+                        else{
+                            file = working_set_lookup_file(working_set, string);
+                        }
+                    }
+                    if (!file->state.is_dummy && buffer_needs_save(file)){
+                        i32 sys_id = file_save(system, exchange, mem, file, file->name.source_path.str);
+                        if (sys_id){
+                            app_push_file_binding(vars, sys_id, get_file_id(working_set, file));
+                        }
+                        else{
+                            delayed_action_repush(&vars->delay2, act);
+                        }
+                    }
+                }break;
+
+                case DACT_NEW:
+                {
+                    Get_File_Result file = working_set_get_available_file(working_set);
+                    file_create_empty(system, mem, working_set, file.file, string.str,
+                        vars->font_set, style->font_id);
+                    table_add(&working_set->table, file.file->name.source_path, file.index);
+
+                    View *new_view = live_set_alloc_view(live_set, mem);
+                    view_replace_major(system, exchange, new_view, panel, live_set);
+
+                    File_View *file_view = file_view_init(new_view, &vars->layout);
+                    cmd->view = (View*)file_view;
+                    view_set_file(system, file_view, file.file, vars->font_set, style,
+                        vars->hooks[hook_open_file], cmd, &app_links);
+                    new_view->map = app_get_map(vars, file.file->settings.base_map_id);
+#if BUFFER_EXPERIMENT_SCALPEL <= 0
+                    if (file.file->settings.tokens_exist)
+                        file_first_lex_parallel(system, general, file.file);
+#endif
+                }break;
+
+                case DACT_SWITCH:
+                {
+                    Editing_File *file = working_set_lookup_file(working_set, string);
+                    if (file){
+                        View *new_view = live_set_alloc_view(live_set, mem);
+                        view_replace_major(system, exchange, new_view, panel, live_set);
+
+                        File_View *file_view = file_view_init(new_view, &vars->layout);
+                        cmd->view = (View*)file_view;
+
+                        view_set_file(system, file_view, file, vars->font_set, style,
+                            vars->hooks[hook_open_file], cmd, &app_links);
+
+                        new_view->map = app_get_map(vars, file->settings.base_map_id);
+                    }
+                }break;
+
+                case DACT_KILL:
+                {
+                    Editing_File *file = working_set_lookup_file(working_set, string);
+                    if (file){
+                        table_remove(&working_set->table, file->name.source_path);
+                        kill_file(system, exchange, general, file, live_set, &vars->layout);
+                    }
+                }break;
+
+                case DACT_TRY_KILL:
+                {
+                    Editing_File *file = working_set_lookup_file(working_set, string);
+                    if (file){
+                        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,
+                                working_set, vars->font_set, &vars->delay1);
+                            int_view->interaction = INTV_SURE_TO_KILL_INTER;
+                            int_view->action = INTV_SURE_TO_KILL;
+                            copy(&int_view->query, "Are you sure?");
+                            copy(&int_view->dest, file->name.live_name);
+                        }
+                        else{
+                            table_remove(&working_set->table, file->name.source_path);
+                            kill_file(system, exchange, general, file, live_set, &vars->layout);
+                            view_remove_minor(system, exchange, panel, live_set);
+                        }
+                    }
+                }break;
+
+                case DACT_CLOSE_MINOR:
+                {
+                    view_remove_minor(system, exchange, panel, live_set);
+                }break;
+
+                case DACT_CLOSE_MAJOR:
+                {
+                    view_remove_major(system, exchange, panel, live_set);
+                }break;
+
+                case DACT_THEME_OPTIONS:
+                {
+                    open_theme_options(system, exchange, vars, live_set, mem, panel);
+                }break;
+
+                case DACT_KEYBOARD_OPTIONS:
+                {
+                    open_config_options(system, exchange, vars, live_set, mem, panel);
+                }break;
+            }
+            
+            if (string.str){
+                general_memory_free(&mem->general, string.str);
+            }
+        }
+        Swap(vars->delay1, vars->delay2);
+    }
+    ProfileEnd(delayed_actions);
+
+    end_temp_memory(param_stack_temp);
+
+    ProfileStart(resize);
+    // NOTE(allen): send resize messages to panels that have changed size
+    {
+        Panel *panel = panels;
+        for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){
+            i32_Rect prev = panel->prev_inner;
+            i32_Rect inner = panel->inner;
+            if (prev.x0 != inner.x0 || prev.y0 != inner.y0 ||
+                    prev.x1 != inner.x1 || prev.y1 != inner.y1){
+                View *view = panel->view;
+                if (view){
+                    view->do_view(system, exchange,
+                        view, inner, active_view,
+                        VMSG_RESIZE, 0, &dead_input, &active_input);
+                    view = (view->is_minor)?view->major:0;
+                    if (view){
+                        view->do_view(system, exchange,
+                            view, inner, active_view,
+                            VMSG_RESIZE, 0, &dead_input, &active_input);
+                    }
+                }
+            }
+            panel->prev_inner = inner;
+        }
+    }
+    ProfileEnd(resize);
+
+    ProfileStart(style_change);
+    // NOTE(allen): send style change messages if the style has changed
+    if (vars->style.font_changed){
+        vars->style.font_changed = 0;
+
+        Editing_File *file = vars->working_set.files;
+        for (i32 i = vars->working_set.file_index_count; i > 0; --i, ++file){
+            if (buffer_good(&file->state.buffer) && !file->state.is_dummy){
+                Render_Font *font = get_font_info(vars->font_set, vars->style.font_id)->font;
+                float *advance_data = 0;
+                if (font) advance_data = font->advance_data;
+
+                file_measure_starts_widths(system, &vars->mem.general,
+                    &file->state.buffer, advance_data);
+            }
+        }
+
+        Panel *panel = panels;
+        for (i32 panel_i = vars->layout.panel_count; panel_i > 0; --panel_i, ++panel){
+            View *view = panel->view;
+            if (view){
+                view->do_view(system, exchange,
+                    view, panel->inner, active_view,
+                    VMSG_STYLE_CHANGE, 0, &dead_input, &active_input);
+                view = (view->is_minor)?view->major:0;
+                if (view){
+                    view->do_view(system, exchange,
+                        view, panel->inner, active_view,
+                        VMSG_STYLE_CHANGE, 0, &dead_input, &active_input);
+                }
+            }
+        }
+    }
+    ProfileEnd(style_change);
+    
     ProfileStart(redraw);
     if (mouse_panel != vars->prev_mouse_panel) app_result.redraw = 1;
     if (app_result.redraw){
diff --git a/4ed.h b/4ed.h
index 2f178dbe..ab05756e 100644
--- a/4ed.h
+++ b/4ed.h
@@ -17,6 +17,8 @@ struct Application_Memory{
     i32 vars_memory_size;
     void *target_memory;
     i32 target_memory_size;
+    void *user_memory;
+    i32 user_memory_size;
 };
 
 #define KEY_INPUT_BUFFER_SIZE 4
diff --git a/4ed_color_view.cpp b/4ed_color_view.cpp
index d6b3601c..fd604225 100644
--- a/4ed_color_view.cpp
+++ b/4ed_color_view.cpp
@@ -1510,7 +1510,7 @@ do_file_list_box(System_Functions *system, UI_State *state, UI_Layout *layout,
             b8 is_folder = (info->folder != 0);
             b8 ext_match = (match(file_extension(filename), p4c_extension) != 0);
             b8 name_match = (filename_match(front_name, &absolutes, filename, case_sensitive) != 0);
-            b8 is_loaded = (file != 0);
+            b8 is_loaded = (file != 0 && file_is_ready(file));
             
             String message = message_nothing;
             if (is_loaded){
diff --git a/4ed_delay.cpp b/4ed_delay.cpp
index cddd049d..45e3e87d 100644
--- a/4ed_delay.cpp
+++ b/4ed_delay.cpp
@@ -1,5 +1,7 @@
 enum Action_Type{
     DACT_OPEN,
+    DACT_OPEN_BACKGROUND,
+    DACT_SET_LINE,
     DACT_SAVE_AS,
     DACT_SAVE,
     DACT_NEW,
@@ -17,18 +19,33 @@ struct Delayed_Action{
     String string;
     Panel* panel;
     Editing_File* file;
+    i32 integer;
 };
 
 struct Delay{
+    General_Memory* general;
     Delayed_Action* acts;
     i32 count;
     i32 max;
 };
 
+internal String
+str_alloc_copy(General_Memory *general, String str){
+    String result;
+    result.memory_size = str.memory_size + 1;
+    result.size = str.size;
+    result.str = (char*)general_memory_allocate(general, result.memory_size, 0);
+    memcpy(result.str, str.str, str.size);
+    result.str[result.size] = 0;
+    return(result);}
+
 inline Delayed_Action*
 delayed_action_(Delay *delay, Action_Type type){
     Delayed_Action *result;
-    Assert(delay->count < delay->max);
+    if (delay->count == delay->max){
+        delay->max *= 2;
+        delay->acts = (Delayed_Action*)general_memory_reallocate(delay->general, delay->acts, delay->count*sizeof(Delayed_Action), delay->max*sizeof(Delayed_Action), 0);
+    }
     result = delay->acts + delay->count++;
     *result = {};
     result->type = type;
@@ -43,11 +60,19 @@ delayed_action_(Delay *delay, Action_Type type, Panel* panel){
     return(result);
 }
 
+inline Delayed_Action*
+delayed_action_(Delay *delay, Action_Type type, String string){
+    Delayed_Action *result;
+    result = delayed_action_(delay, type);
+    result->string = str_alloc_copy(delay->general, string);
+    return(result);
+}
+
 inline Delayed_Action*
 delayed_action_(Delay *delay, Action_Type type, String string, Panel* panel){
     Delayed_Action *result;
     result = delayed_action_(delay, type);
-    result->string = string;
+    result->string = str_alloc_copy(delay->general, string);
     result->panel = panel;
     return(result);
 }
@@ -56,12 +81,33 @@ inline Delayed_Action*
 delayed_action_(Delay *delay, Action_Type type, String string, Editing_File* file){
     Delayed_Action *result;
     result = delayed_action_(delay, type);
-    result->string = string;
+    result->string = str_alloc_copy(delay->general, string);
     result->file = file;
     return(result);
 }
 
+inline Delayed_Action*
+delayed_action_(Delay *delay, Action_Type type, Panel* panel, i32 integer){
+    Delayed_Action *result;
+    result = delayed_action_(delay, type);
+    result->panel = panel;
+    result->integer = integer;
+    return(result);
+}
+
+inline Delayed_Action*
+delayed_action_repush(Delay *delay, Delayed_Action *act){
+    Delayed_Action *new_act = delayed_action_(delay, (Action_Type)0);
+    *new_act = *act;
+    if (act->string.str){
+        new_act->string = str_alloc_copy(delay->general, act->string);
+    }
+    return(new_act);
+}
+
 #define delayed_open(delay, ...) delayed_action_(delay, DACT_OPEN, __VA_ARGS__)
+#define delayed_open_background(delay, ...) delayed_action_(delay, DACT_OPEN_BACKGROUND, __VA_ARGS__)
+#define delayed_set_line(delay, ...) delayed_action_(delay, DACT_SET_LINE, __VA_ARGS__)
 #define delayed_save_as(delay, ...) delayed_action_(delay, DACT_SAVE_AS, __VA_ARGS__)
 #define delayed_save(delay, ...) delayed_action_(delay, DACT_SAVE, __VA_ARGS__)
 #define delayed_new(delay, ...) delayed_action_(delay, DACT_NEW, __VA_ARGS__)
diff --git a/4ed_exchange.cpp b/4ed_exchange.cpp
index 06c9d696..7908cace 100644
--- a/4ed_exchange.cpp
+++ b/4ed_exchange.cpp
@@ -198,7 +198,6 @@ exchange_free_file(Exchange *exchange, i32 file_id){
         ex__file_remove(file);
         ex__file_insert(&files->free_list, file);
         ex__check(files);
-        --files->num_active;
     }
 }
 
diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp
index 06de587b..7926f7b7 100644
--- a/4ed_file_view.cpp
+++ b/4ed_file_view.cpp
@@ -31,8 +31,8 @@ struct File_View_Widget{
     File_View_Widget_Type type;
     i32 height;
     struct{
-        bool32 undo_line;
-        bool32 history_line;
+        b32 undo_line;
+        b32 history_line;
     } timeline;
 };
 
@@ -208,36 +208,33 @@ file_save(System_Functions *system, Exchange *exchange, Mem_Options *mem,
           Editing_File *file, char *filename){
 	i32 result = 0;
     
-#if BUFFER_EXPERIMENT_SCALPEL <= 3
     i32 max, size;
-    byte *data;
     b32 dos_write_mode = file->settings.dos_write_mode;
-
-    if (dos_write_mode)
-        max = buffer_size(&file->state.buffer) + file->state.buffer.line_count + 1;
-    else
-        max = buffer_size(&file->state.buffer);
+    char *data;
+    Buffer_Type *buffer = &file->state.buffer;
     
-    data = (byte*)general_memory_allocate(&mem->general, max, 0);
+    if (dos_write_mode)
+        max = buffer_size(buffer) + buffer->line_count + 1;
+    else
+        max = buffer_size(buffer);
+    
+    data = (char*)general_memory_allocate(&mem->general, max, 0);
     Assert(data);
     
     if (dos_write_mode)
-        size = buffer_convert_out(&file->state.buffer, (char*)data, max);
+        size = buffer_convert_out(buffer, data, max);
     else
-        buffer_stringify(&file->state.buffer, 0, size = max, (char*)data);
+        buffer_stringify(buffer, 0, size = max, data);
     
-    i32 filename_len = str_size(filename);
-    result = exchange_save_file(exchange, filename, filename_len,
-                                data, size, max);
+    result = exchange_save_file(exchange, filename, str_size(filename), (byte*)data, size, max);
     
     if (result == 0){
         general_memory_free(&mem->general, data);
     }
     
     file_synchronize_times(system, file, filename);
-#endif
     
-    return result;
+    return(result);
 }
 
 inline b32
@@ -270,28 +267,41 @@ enum File_Bubble_Type{
 #define GROW_SUCCESS 2
 
 internal i32
-file_grow_starts_as_needed(General_Memory *general, Buffer_Type *buffer, i32 additional_lines){
-    bool32 result = GROW_NOT_NEEDED;
-#if BUFFER_EXPERIMENT_SCALPEL <= 3
+file_grow_starts_widths_as_needed(General_Memory *general, Buffer_Type *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;
+    Assert(max == buffer->widths_max);
+    
     if (target_lines > max || max == 0){
         max = LargeRoundUp(target_lines + max, Kbytes(1));
-        i32 *new_lines = (i32*)
-            general_memory_reallocate(general, buffer->line_starts,
-                                      sizeof(i32)*count, sizeof(i32)*max, BUBBLE_STARTS);
+        
+        f32 *new_widths = (f32*)general_memory_reallocate(
+            general, buffer->line_widths,
+            sizeof(f32)*count, sizeof(f32)*max, BUBBLE_WIDTHS);
+        
+        i32 *new_lines = (i32*)general_memory_reallocate(
+            general, buffer->line_starts,
+            sizeof(i32)*count, sizeof(i32)*max, BUBBLE_STARTS);
+
         if (new_lines){
             buffer->line_starts = new_lines;
             buffer->line_max = max;
+        }
+        if (new_widths){
+            buffer->line_widths = new_widths;
+            buffer->widths_max = max;
+        }
+        if (new_lines && new_widths){
             result = GROW_SUCCESS;
         }
         else{
             result = GROW_FAILED;
         }
     }
-#endif
-    return result;
+    
+    return(result);
 }
 
 internal void
@@ -345,16 +355,14 @@ file_measure_starts_widths(System_Functions *system, General_Memory *general,
 }
 
 internal void
-file_remeasure_starts(System_Functions *system,
+file_remeasure_starts_(System_Functions *system,
                       General_Memory *general, Buffer_Type *buffer,
                       i32 line_start, i32 line_end, i32 line_shift,
                       i32 character_shift){
-#if BUFFER_EXPERIMENT_SCALPEL <= 3
     ProfileMomentFunction();
     Assert(buffer->line_starts);
-    file_grow_starts_as_needed(general, buffer, line_shift);
+    file_grow_starts_widths_as_needed(general, buffer, line_shift);
     buffer_remeasure_starts(buffer, line_start, line_end, line_shift, character_shift);
-#endif
 }
 
 struct Opaque_Font_Advance{
@@ -370,9 +378,9 @@ get_opaque_font_advance(Render_Font *font){
     return result;
 }
 
+#if 0
 internal void
 file_grow_widths_as_needed(General_Memory *general, Buffer_Type *buffer){
-#if BUFFER_EXPERIMENT_SCALPEL <= 3
     i32 line_count = buffer->line_count;
     if (line_count > buffer->widths_max || buffer->widths_max == 0){
         i32 new_max = LargeRoundUp(line_count, Kbytes(1));
@@ -388,18 +396,16 @@ file_grow_widths_as_needed(General_Memory *general, Buffer_Type *buffer){
         }
         buffer->widths_max = new_max;
     }
-#endif
 }
+#endif
 
 internal void
-file_remeasure_widths(System_Functions *system,
+file_remeasure_widths_(System_Functions *system,
                       General_Memory *general, Buffer_Type *buffer, Render_Font *font,
                       i32 line_start, i32 line_end, i32 line_shift){
-#if BUFFER_EXPERIMENT_SCALPEL <= 3
     ProfileMomentFunction();
-    file_grow_widths_as_needed(general, buffer);
+    file_grow_starts_widths_as_needed(general, buffer, line_shift);
     buffer_remeasure_widths(buffer, font->advance_data, line_start, line_end, line_shift);
-#endif
 }
 
 inline i32
@@ -1806,20 +1812,18 @@ file_do_single_edit(System_Functions *system,
         if (old_data) general_memory_free(general, old_data);
     }
     
+    Buffer_Type *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;
     
-    file_remeasure_starts(system, general, &file->state.buffer,
-                          line_start, line_end, line_shift, shift_amount);
-
     Render_Font *font = get_font_info(file->settings.set, file->state.font_id)->font;
-    if (font){
-        file_remeasure_widths(system, general, &file->state.buffer,
-                              font, line_start, line_end, line_shift);
-    }
+    
+    file_grow_starts_widths_as_needed(general, buffer, line_shift);
+    buffer_remeasure_starts(buffer, line_start, line_end, line_shift, shift_amount);
+    buffer_remeasure_widths(buffer, font->advance_data, line_start, line_end, line_shift);
     
     i32 panel_count = layout->panel_count;
     Panel *current_panel = layout->panels;
@@ -2276,13 +2280,11 @@ working_set_lookup_file(Working_Set *working_set, String string){
 
 internal void
 clipboard_copy(System_Functions *system, General_Memory *general, Working_Set *working, Range range, Editing_File *file){
-#if BUFFER_EXPERIMENT_SCALPEL <= 3
     i32 size = range.end - range.start;
     String *dest = working_set_next_clipboard_string(general, working, size);
     buffer_stringify(&file->state.buffer, range.start, range.end, dest->str);
     dest->size = size;
     system->post_clipboard(*dest);
-#endif
 }
 
 internal Edit_Spec
@@ -2290,7 +2292,6 @@ file_compute_whitespace_edit(Mem_Options *mem, Editing_File *file, i32 cursor_po
                              Buffer_Edit *edits, char *str_base, i32 str_size,
                              Buffer_Edit *inverse_array, char *inv_str, i32 inv_max,
                              i32 edit_count){
-#if BUFFER_EXPERIMENT_SCALPEL <= 3
     General_Memory *general = &mem->general;
     
     i32 inv_str_pos = 0;
@@ -2315,16 +2316,12 @@ file_compute_whitespace_edit(Mem_Options *mem, Editing_File *file, i32 cursor_po
     spec.step.inverse_child_count = edit_count;
     spec.step.pre_pos = cursor_pos;
     spec.step.post_pos = cursor_pos;
-#else
-    Edit_Spec spec = {};
-#endif
     
     return spec;
 }
 
 internal void
 view_clean_whitespace(System_Functions *system, Mem_Options *mem, File_View *view, Editing_Layout *layout){
-#if BUFFER_EXPERIMENT_SCALPEL <= 3
     Editing_File *file = view->file;
     Assert(file && !file->state.is_dummy);
     Partition *part = &mem->part;
@@ -2378,7 +2375,6 @@ view_clean_whitespace(System_Functions *system, Mem_Options *mem, File_View *vie
     }
     
     end_temp_memory(temp);
-#endif
 }
 
 internal void
@@ -3294,7 +3290,8 @@ command_reverse_search(System_Functions*,Command_Data*,Command_Binding);
 inline void
 free_file_view(View *view){
     File_View *fview = (File_View*)view;
-    general_memory_free(&view->mem->general, fview->line_wrap_y);
+    if (fview->line_wrap_y)
+        general_memory_free(&view->mem->general, fview->line_wrap_y);
     if (fview->links)
         general_memory_free(&view->mem->general, fview->links);
 }
diff --git a/4ed_interactive_view.cpp b/4ed_interactive_view.cpp
index b95cc8e7..6ef77bad 100644
--- a/4ed_interactive_view.cpp
+++ b/4ed_interactive_view.cpp
@@ -34,6 +34,7 @@ struct Interactive_View{
     UI_State state;
     Interactive_View_Interaction interaction;
     Interactive_View_Action action;
+    int finished;
     
     char query_[256];
     String query;
@@ -98,8 +99,9 @@ interactive_view_complete(Interactive_View *view){
 
 internal i32
 step_draw_int_view(System_Functions *system, Interactive_View *view,
-                   Render_Target *target, i32_Rect rect,
-                   Input_Summary *user_input, b32 input_stage){
+    Render_Target *target, i32_Rect rect,
+    Input_Summary *user_input, b32 input_stage){
+    if (view->finished) return 0;
     i32 result = 0;
     
     UI_State state =
@@ -182,6 +184,7 @@ step_draw_int_view(System_Functions *system, Interactive_View *view,
     }
     
     if (complete){
+        view->finished = 1;
         interactive_view_complete(view);
     }
     
@@ -222,6 +225,7 @@ interactive_view_init(System_Functions *system, View *view,
     result->working_set = working_set;
     result->font_set = font_set;
     result->delay = delay;
+    result->finished = 0;
     return result;
 }
 
diff --git a/4ed_metagen.cpp b/4ed_metagen.cpp
index 8922ebbf..4758ff46 100644
--- a/4ed_metagen.cpp
+++ b/4ed_metagen.cpp
@@ -112,6 +112,8 @@ char* generate_keycode_enum(){
 char daction_enum_name[] = "Action_Type";
 char *daction_enum[] = {
     "OPEN",
+    "OPEN_BACKGROUND",
+    "SET_LINE",
     "SAVE_AS",
     "SAVE",
     "NEW",
@@ -124,6 +126,18 @@ char *daction_enum[] = {
     "KEYBOARD_OPTIONS"
 };
 
+char str_alloc_copy[] =
+"internal String\n"
+"str_alloc_copy(General_Memory *general, String str){\n"
+"    String result;\n"
+"    result.memory_size = str.memory_size + 1;\n"
+"    result.size = str.size;\n"
+"    result.str = (char*)general_memory_allocate(general, result.memory_size, 0);\n"
+"    memcpy(result.str, str.str, str.size);\n"
+"    result.str[result.size] = 0;\n"
+"    return(result);"
+"}\n\n";
+
 char daction_name[] = "Delayed_Action";
 Struct_Field daction_fields[] = {
     {"Action_Type", "type"},
@@ -132,27 +146,31 @@ Struct_Field daction_fields_primary[] = {
     {"String", "string"},
     {"Panel*", "panel"},
     {"Editing_File*", "file"},
+    {"i32", "integer"},
 };
 enum Daction_Field_Handle{
     dfph_null,
     dfph_string,
     dfph_panel,
     dfph_file,
+    dfph_integer,
 };
 Daction_Field_Handle dact_param_sets[] = {
     dfph_panel, dfph_null,
+    dfph_string, dfph_null,
     dfph_string, dfph_panel, dfph_null,
-    dfph_string, dfph_file, dfph_null
+    dfph_string, dfph_file, dfph_null,
+    dfph_panel, dfph_integer, dfph_null,
 };
 
 char delay_name[] = "Delay";
 Struct_Field delay_fields[] = {
+    {"General_Memory*", "general"},
     {"Delayed_Action*", "acts"},
     {"i32", "count"},
     {"i32", "max"},
 };
 
-// TODO(allen): Make delay buffer expandable (general memory probably)
 char delayed_action_function_top[] = 
 "inline Delayed_Action*\n"
 "delayed_action_(Delay *delay, Action_Type type";
@@ -160,7 +178,11 @@ char delayed_action_function_top[] =
 char delayed_action_function_bottom[] = 
 "){\n"
 "    Delayed_Action *result;\n"
-"    Assert(delay->count < delay->max);\n"
+"    if (delay->count == delay->max){\n"
+"        delay->max *= 2;\n"
+"        delay->acts = (Delayed_Action*)general_memory_reallocate("
+"delay->general, delay->acts, delay->count*sizeof(Delayed_Action), delay->max*sizeof(Delayed_Action), 0);\n"
+"    }\n"
 "    result = delay->acts + delay->count++;\n"
 "    *result = {};\n"
 "    result->type = type;\n"
@@ -177,6 +199,9 @@ char delayed_action_specialized_middle[] =
 char delayed_action_special_line[] =
 "    result->%s = %s;\n";
 
+char delayed_action_special_string_line[] =
+"    result->%s = str_alloc_copy(delay->general, %s);\n";
+
 char delayed_action_specialized_bottom[] =
 "    return(result);\n"
 "}\n\n";
@@ -184,6 +209,17 @@ char delayed_action_specialized_bottom[] =
 char delayed_action_macro[] =
 "#define delayed_%s(delay, ...) delayed_action_(delay, DACT_%s, __VA_ARGS__)\n";
 
+char delayed_action_repush_function[] =
+"inline Delayed_Action*\n"
+"delayed_action_repush(Delay *delay, Delayed_Action *act){\n"
+"    Delayed_Action *new_act = delayed_action_(delay, (Action_Type)0);\n"
+"    *new_act = *act;\n"
+"    if (act->string.str){\n"
+"        new_act->string = str_alloc_copy(delay->general, act->string);\n"
+"    }\n"
+"    return(new_act);\n"
+"}\n\n";
+
 char* generate_delayed_action(){
     FILE *file;
     char *filename = "4ed_delay.cpp";
@@ -207,6 +243,7 @@ char* generate_delayed_action(){
     struct_fields(file, delay_fields, ArrayCount(delay_fields));
     struct_end(file);
     
+    fprintf(file, "%s", str_alloc_copy);
     fprintf(file, "%s%s", delayed_action_function_top, delayed_action_function_bottom);
     
     for (i = 0; i < ArrayCount(dact_param_sets); ++i){
@@ -218,12 +255,20 @@ char* generate_delayed_action(){
         }
         fprintf(file, "%s", delayed_action_specialized_middle);
         for (; dact_param_sets[j] != dfph_null; ++j){
-            Struct_Field field = daction_fields_primary[dact_param_sets[j] - 1];
-            fprintf(file, delayed_action_special_line, field.name, field.name);
+            int handle = (int)(dact_param_sets[j]);
+            Struct_Field field = daction_fields_primary[handle - 1];
+            if (handle == dfph_string){
+                fprintf(file, delayed_action_special_string_line, field.name, field.name);
+            }
+            else{
+                fprintf(file, delayed_action_special_line, field.name, field.name);
+            }
         }
         fprintf(file, "%s", delayed_action_specialized_bottom);
     }
     
+    fprintf(file, "%s", delayed_action_repush_function);
+    
     for (i = 0; i < ArrayCount(daction_enum); ++i){
         to_lower(daction_enum[i], scratch);
         fprintf(file, delayed_action_macro, scratch, daction_enum[i]);
diff --git a/4ed_system.h b/4ed_system.h
index 9d4e5feb..07aab46d 100644
--- a/4ed_system.h
+++ b/4ed_system.h
@@ -13,17 +13,6 @@ struct Plat_Handle{
     u32 d[4];
 };
 
-struct File_Info{
-    String filename;
-    b32 folder;
-};
-
-struct File_List{
-    void *block;
-    File_Info *infos;
-    i32 count, block_size;
-};
-
 #define Sys_File_Time_Stamp_Sig(name) u64 name(char *filename)
 typedef Sys_File_Time_Stamp_Sig(System_File_Time_Stamp);
 
@@ -187,8 +176,8 @@ struct System_Functions{
     System_Set_File_List *set_file_list;
 
     // file system navigation (4coder_custom.h): 2
-    Directory_Has_File *directory_has_file;
-    Directory_CD *directory_cd;
+    File_Exists_Function *file_exists;
+    Directory_CD_Function *directory_cd;
 
     // clipboard: 1
     System_Post_Clipboard *post_clipboard;
diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp
index 0607791a..59ab0b86 100644
--- a/buffer/4coder_buffer_abstract.cpp
+++ b/buffer/4coder_buffer_abstract.cpp
@@ -120,7 +120,7 @@ buffer_reverse_seek_delimiter(Buffer_Type *buffer, int pos, char delim){
         buffer_backify_next(&loop)){
         end = loop.size + loop.absolute_pos;
         data = loop.data - loop.absolute_pos;
-        for (; pos > 0; --pos){
+        for (; pos >= 0; --pos){
             if (data[pos] == delim) goto double_break;
         }
     }
diff --git a/win32_4ed.cpp b/win32_4ed.cpp
index 7843a53f..21b023e4 100644
--- a/win32_4ed.cpp
+++ b/win32_4ed.cpp
@@ -24,6 +24,8 @@
 
 #include "4ed_dll_reader.h"
 
+#include <stdlib.h>
+
 #include "4coder_custom.cpp"
 
 #undef exec_command
@@ -261,7 +263,17 @@ internal Data
 system_load_file(char *filename){
     Data result = {};
     HANDLE file;
-    file = CreateFile((char*)filename, GENERIC_READ, 0, 0,
+    
+    String fname_str = make_string_slowly(filename);
+    if (fname_str.size >= 1024) return result;
+    
+    char fixed_space[1024];
+    String fixed_str = make_fixed_width_string(fixed_space);
+    copy(&fixed_str, fname_str);
+    terminate_with_null(&fixed_str);
+    replace_char(fixed_str, '/', '\\');
+    
+    file = CreateFile((char*)fixed_str.str, GENERIC_READ, 0, 0,
                       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
     if (!file || file == INVALID_HANDLE_VALUE){
         return result;
@@ -397,8 +409,9 @@ Sys_Set_File_List_Sig(system_set_file_list){
 
             i32 required_size = count + file_count * sizeof(File_Info);
             if (file_list->block_size < required_size){
-                Win32FreeMemory(file_list->block);    
+                Win32FreeMemory(file_list->block);
                 file_list->block = Win32GetMemory(required_size);
+                file_list->block_size = required_size;
             }
             
             file_list->infos = (File_Info*)file_list->block;
@@ -436,37 +449,32 @@ Sys_Set_File_List_Sig(system_set_file_list){
             }
         }
     }
+    else{
+        Win32FreeMemory(file_list->block);
+    }
 }
 
 internal
-DIRECTORY_HAS_FILE_SIG(system_directory_has_file){
-    char *full_filename;
-    char space[1024];
+FILE_EXISTS_SIG(system_file_exists){
+    char full_filename_space[1024];
+    String full_filename;
     HANDLE file;
     b32 result;
-    i32 len;
-
-    full_filename = 0;
-    len = str_size(filename);
-    if (dir.memory_size - dir.size - 1 >= len){
-        full_filename = dir.str;
-        memcpy(dir.str + dir.size, filename, len + 1);
-    }
-    else if (dir.size + len + 1 < 1024){
-        full_filename = space;
-        memcpy(full_filename, dir.str, dir.size);
-        memcpy(full_filename + dir.size, filename, len + 1);
-    }
 
     result = 0;
-    if (full_filename){
-        file = CreateFile((char*)full_filename, GENERIC_READ, 0, 0,
-                          OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+    
+    if (len < sizeof(full_filename_space)){
+        full_filename = make_fixed_width_string(full_filename_space);
+        copy(&full_filename, make_string(filename, len));
+        terminate_with_null(&full_filename);
+        
+        file = CreateFile(full_filename.str, GENERIC_READ, 0, 0,
+            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+        
         if (file != INVALID_HANDLE_VALUE){
             CloseHandle(file);
             result = 1;
         }
-        dir.str[dir.size] = 0;
     }
     
     return(result);
@@ -480,34 +488,35 @@ b32 Win32DirectoryExists(char *path){
 
 internal
 DIRECTORY_CD_SIG(system_directory_cd){
+    String directory = make_string(dir, *len, capacity);
     b32 result = 0;
     i32 old_size;
-    i32 len;
     
     if (rel_path[0] != 0){
         if (rel_path[0] == '.' && rel_path[1] == 0){
             result = 1;
         }
         else if (rel_path[0] == '.' && rel_path[1] == '.' && rel_path[2] == 0){
-            result = remove_last_folder(dir);
-            terminate_with_null(dir);
+            result = remove_last_folder(&directory);
+            terminate_with_null(&directory);
         }
         else{
-            len = str_size(rel_path);
-            if (dir->size + len + 1 > dir->memory_size){
-                old_size = dir->size;
-                append_partial(dir, rel_path);
-                append_partial(dir, "\\");
-                if (Win32DirectoryExists(dir->str)){
+            if (directory.size + rel_len + 1 > directory.memory_size){
+                old_size = directory.size;
+                append_partial(&directory, rel_path);
+                append_partial(&directory, "\\");
+                if (Win32DirectoryExists(directory.str)){
                     result = 1;
                 }
                 else{
-                    dir->size = old_size;
+                    directory.size = old_size;
                 }
             }
         }
     }
     
+    *len = directory.size;
+    
     return(result);
 }
 
@@ -975,7 +984,7 @@ Sys_To_Binary_Path(system_to_binary_path){
     i32 size = GetModuleFileName(0, out_filename->str, max);
     if (size > 0 && size < max-1){
         out_filename->size = size;
-        truncate_to_path_of_directory(out_filename);
+        remove_last_folder(out_filename);
         if (append(out_filename, filename) && terminate_with_null(out_filename)){
             translate_success = 1;
         }
@@ -1047,7 +1056,7 @@ Win32LoadSystemCode(){
     win32vars.system->file_time_stamp = system_file_time_stamp;
     win32vars.system->set_file_list = system_set_file_list;
 
-    win32vars.system->directory_has_file = system_directory_has_file;
+    win32vars.system->file_exists = system_file_exists;
     win32vars.system->directory_cd = system_directory_cd;
 
     win32vars.system->post_clipboard = system_post_clipboard;
@@ -1555,20 +1564,23 @@ UpdateLoop(LPVOID param){
                     }
                 }
             }
-            
-            Assert(d == exchange_vars.file.num_active);
-            
+
+            int free_list_count = 0;
             for (file = exchange_vars.file.free_list.next;
-                 file != &exchange_vars.file.free_list;
-                 file = file->next){
+                file != &exchange_vars.file.free_list;
+                file = file->next){
+                ++free_list_count;
                 if (file->data){
                     system_free_memory(file->data);
                 }
             }
 
             if (exchange_vars.file.free_list.next != &exchange_vars.file.free_list){
+                Assert(free_list_count != 0);
                 ex__insert_range(exchange_vars.file.free_list.next, exchange_vars.file.free_list.prev,
-                                 &exchange_vars.file.available);
+                    &exchange_vars.file.available);
+                
+                exchange_vars.file.num_active -= free_list_count;
             }
 
             ex__check(&exchange_vars.file);
@@ -1633,19 +1645,19 @@ main(int argc, char **argv){
     for (i32 i = 0; i+1 < ArrayCount(win32vars.coroutine_data); ++i){
         win32vars.coroutine_data[i].next = win32vars.coroutine_data + i + 1;
     }
-    
+
     LPVOID base;
 #if FRED_INTERNAL
     base = (LPVOID)Tbytes(1);
 #else
     base = (LPVOID)0;
 #endif
-    
-	memory_vars.vars_memory_size = Mbytes(2);
+
+    memory_vars.vars_memory_size = Mbytes(2);
     memory_vars.vars_memory = VirtualAlloc(base, memory_vars.vars_memory_size,
-                                           MEM_COMMIT | MEM_RESERVE,
-                                           PAGE_READWRITE);
-    
+        MEM_COMMIT | MEM_RESERVE,
+        PAGE_READWRITE);
+
 #if FRED_INTERNAL
     base = (LPVOID)Tbytes(2);
 #else
@@ -1653,6 +1665,12 @@ main(int argc, char **argv){
 #endif
     memory_vars.target_memory_size = Mbytes(512);
     memory_vars.target_memory = VirtualAlloc(base, memory_vars.target_memory_size,
+        MEM_COMMIT | MEM_RESERVE,
+        PAGE_READWRITE);
+    
+    base = (LPVOID)0;
+    memory_vars.user_memory_size = Mbytes(2);
+    memory_vars.user_memory = VirtualAlloc(base, memory_vars.target_memory_size,
                                              MEM_COMMIT | MEM_RESERVE,
                                              PAGE_READWRITE);
     //
@@ -1905,7 +1923,7 @@ main(int argc, char **argv){
     }
 
     
-    File_Slot file_slots[120];
+    File_Slot file_slots[32];
     sysshared_init_file_exchange(&exchange_vars, file_slots, ArrayCount(file_slots), 0);
     
     Font_Load_Parameters params[32];