From c221d97f130b37581410e2b8f50c15d3eb977441 Mon Sep 17 00:00:00 2001
From: Allen Webster <editor@4coder.net>
Date: Fri, 28 Oct 2016 10:11:56 -0400
Subject: [PATCH] a4.0.12 ready

---
 4coder_default_bindings.cpp  | 93 +++++------------------------------
 4coder_default_include.cpp   | 94 ++++++++++++++++++++++++++++++++++++
 4ed.cpp                      | 11 +++++
 4ed_api_implementation.cpp   |  5 +-
 build.c                      |  3 ++
 power/4coder_experiments.cpp | 33 +++----------
 6 files changed, 132 insertions(+), 107 deletions(-)

diff --git a/4coder_default_bindings.cpp b/4coder_default_bindings.cpp
index fbfab126..81c01275 100644
--- a/4coder_default_bindings.cpp
+++ b/4coder_default_bindings.cpp
@@ -124,87 +124,10 @@ CUSTOM_COMMAND_SIG(seek_whitespace_down_end_line){
     exec_command(app, seek_end_of_line);
 }
 
-static bool32 enable_code_wrapping = 1;
-static int32_t default_wrap_width = 672;
-
 HOOK_SIG(my_start){
     init_memory(app);
     
-    {
-        FILE *file = fopen("config.4coder", "rb");
-        if (file){
-            Temp_Memory temp = begin_temp_memory(&global_part);
-            
-            fseek(file, 0, SEEK_END);
-            int32_t size = ftell(file);
-            char *mem = (char*)push_block(&global_part, size+1);
-            fseek(file, 0, SEEK_SET);
-            fread(mem, 1, size+1, file);
-            fclose(file);
-            
-            Cpp_Token_Array array;
-            array.count = 0;
-            array.max_count = (1 << 20)/sizeof(Cpp_Token);
-            array.tokens = push_array(&global_part, Cpp_Token, array.max_count);
-            
-            Cpp_Lex_Data S = cpp_lex_data_init();
-            Cpp_Lex_Result result = cpp_lex_step(&S, mem, size, HAS_NULL_TERM, &array, NO_OUT_LIMIT);
-            
-            if (result == LexResult_Finished){
-                
-                for (int32_t i = 0; i < array.count; ++i){
-                int32_t read_setting_failed = 1;
-                    Cpp_Token id_token = array.tokens[i];
-                if (id_token.type == CPP_TOKEN_IDENTIFIER){
-                    ++i;
-                    if (i < array.count){
-                    Cpp_Token eq_token = array.tokens[i];
-                        if (eq_token.type == CPP_TOKEN_EQEQ){
-                            ++i;
-                            if (i < array.count){
-                                Cpp_Token val_token = array.tokens[i];
-                                {
-                                ++i;
-                                    if (i < array.count){
-                                        Cpp_Token semicolon_token = array.tokens[i];
-                                        if (semicolon_token.type == CPP_TOKEN_SEMICOLON){
-                                            read_setting_failed = 0;
-                                            
-                                            String id = make_string(mem + id_token.start, id_token.size);
-                                            
-                                            if (match(id, "enable_code_wrapping")){
-                                                if (val_token.type == CPP_TOKEN_BOOLEAN_CONSTANT){
-                                                    String val = make_string(mem + val_token.start, val_token.size);
-                                                    if (val.str[0] == 't'){
-                                                        enable_code_wrapping = 1;
-                                                    }
-                                                    else{
-                                                        enable_code_wrapping = 0;
-                                                    }
-                                                }
-                                                }
-                                        }
-                                }
-                            }
-                            }
-                        }
-                    }
-                }
-                
-                if (read_setting_failed){
-                    for (; i < array.count; ++i){
-                        Cpp_Token token = array.tokens[i];
-                        if (token.type == CPP_TOKEN_SEMICOLON){
-                            break;
-                        }
-                    }
-                }
-            }
-            }
-            
-            end_temp_memory(temp);
-        }
-    }
+    process_config_file(app);
     
     change_theme(app, literal("4coder"));
     change_font(app, literal("Liberation Sans"), true);
@@ -297,15 +220,25 @@ OPEN_FILE_HOOK_SIG(my_file_settings){
         wrap_lines = 0;
     }
     
-    buffer_set_setting(app, &buffer, BufferSetting_Lex, treat_as_code);
-    buffer_set_setting(app, &buffer, BufferSetting_WrapLine, wrap_lines);
     buffer_set_setting(app, &buffer, BufferSetting_WrapPosition, default_wrap_width);
     buffer_set_setting(app, &buffer, BufferSetting_MapID, (treat_as_code)?((int32_t)my_code_map):((int32_t)mapid_file));
     
     if (treat_as_code && enable_code_wrapping && buffer.size < (1 << 20)){
+        // NOTE(allen|a4.0.12): There is a little bit of grossness going on here.
+        // If we set BufferSetting_Lex to true, it will launch a lexing job.
+        // If a lexing job is active when we set BufferSetting_VirtualWhitespace on
+        //  that call can fail.
+        // Unfortunantely without tokens virtual whitespace doesn't really make sense.
+        // So for now I have it automatically turning on lexing when virtual whitespace
+        //  is turned on.
+        // Cleaning some of that up is a goal for future versions.
         buffer_set_setting(app, &buffer, BufferSetting_WrapLine, 1);
         buffer_set_setting(app, &buffer, BufferSetting_VirtualWhitespace, 1);
     }
+    else{
+        buffer_set_setting(app, &buffer, BufferSetting_WrapLine, wrap_lines);
+        buffer_set_setting(app, &buffer, BufferSetting_Lex, treat_as_code);
+    }
     
     // no meaning for return
     return(0);
diff --git a/4coder_default_include.cpp b/4coder_default_include.cpp
index d87709e4..0cbf1874 100644
--- a/4coder_default_include.cpp
+++ b/4coder_default_include.cpp
@@ -3486,5 +3486,99 @@ COMMAND_CALLER_HOOK(default_command_caller){
     return(0);
 }
 
+// NOTE(allen|a4.0.12): A primordial config system (actually really hate this but it seems best)
+
+static bool32 enable_code_wrapping = 1;
+static int32_t default_wrap_width = 672;
+
+#include <stdio.h>
+
+static void
+process_config_file(Application_Links *app){
+    FILE *file = fopen("config.4coder", "rb");
+    if (file){
+        Temp_Memory temp = begin_temp_memory(&global_part);
+        
+        fseek(file, 0, SEEK_END);
+        int32_t size = ftell(file);
+        char *mem = (char*)push_block(&global_part, size+1);
+        fseek(file, 0, SEEK_SET);
+        fread(mem, 1, size, file);
+        mem[size] = 0;
+        fclose(file);
+        
+        Cpp_Token_Array array;
+        array.count = 0;
+        array.max_count = (1 << 20)/sizeof(Cpp_Token);
+        array.tokens = push_array(&global_part, Cpp_Token, array.max_count);
+        
+        Cpp_Lex_Data S = cpp_lex_data_init();
+        Cpp_Lex_Result result = cpp_lex_step(&S, mem, size+1, HAS_NULL_TERM, &array, NO_OUT_LIMIT);
+        
+        if (result == LexResult_Finished){
+            
+            for (int32_t i = 0; i < array.count; ++i){
+                int32_t read_setting_failed = 1;
+                Cpp_Token id_token = array.tokens[i];
+                if (id_token.type == CPP_TOKEN_IDENTIFIER){
+                    ++i;
+                    if (i < array.count){
+                        Cpp_Token eq_token = array.tokens[i];
+                        if (eq_token.type == CPP_TOKEN_EQ){
+                            ++i;
+                            if (i < array.count){
+                                Cpp_Token val_token = array.tokens[i];
+                                {
+                                    ++i;
+                                    if (i < array.count){
+                                        Cpp_Token semicolon_token = array.tokens[i];
+                                        if (semicolon_token.type == CPP_TOKEN_SEMICOLON){
+                                            read_setting_failed = 0;
+                                            
+                                            String id = make_string(mem + id_token.start, id_token.size);
+                                            
+                                            if (match(id, "enable_code_wrapping")){
+                                                if (val_token.type == CPP_TOKEN_BOOLEAN_CONSTANT){
+                                                    String val = make_string(mem + val_token.start, val_token.size);
+                                                    if (val.str[0] == 't'){
+                                                        enable_code_wrapping = 1;
+                                                    }
+                                                    else{
+                                                        enable_code_wrapping = 0;
+                                                    }
+                                                }
+                                            }
+                                            else if (match(id, "default_wrap_width")){
+                                                if (val_token.type == CPP_TOKEN_INTEGER_CONSTANT){
+                                                    String val = make_string(mem + val_token.start, val_token.size);
+                                                    default_wrap_width = str_to_int(val);
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                
+                if (read_setting_failed){
+                    for (; i < array.count; ++i){
+                        Cpp_Token token = array.tokens[i];
+                        if (token.type == CPP_TOKEN_SEMICOLON){
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        
+        end_temp_memory(temp);
+    }
+    else{
+        print_message(app, literal("Did not find config.4coder, using default settings"));
+    }
+}
+
 #endif
 
diff --git a/4ed.cpp b/4ed.cpp
index 0d7569f3..421d208a 100644
--- a/4ed.cpp
+++ b/4ed.cpp
@@ -2583,6 +2583,17 @@ App_Step_Sig(app_step){
                             "and if you load README.txt you'll find all the key combos there are.\n"
                             "\n"
                             "Newest features:\n"
+                            "-Text files wrap lines at whitespace when possible\n"
+                            "-New code wrapping feature is on by default\n"
+                            "-Introduced a 'config.4coder' for setting several wrapping options:"
+                            "  enable_code_wrapping: set to false if you want the text like behavior\n"
+                            "  default_wrap_width: the wrap width to set in new files\n"
+                            "-<ctrl 2> decrease the current buffer's wrap width\n"
+                            "-<ctrl 3> increase the current buffer's wrap width\n"
+                            "-In the customization layer new settings for the buffer are exposed dealing with wrapping\n"
+                            "-In the customization layer there is a call for setting what keys the GUI should use\n"
+                            "\n"
+                            "New in alpha 4.0.11:\n"
                             "-The commands for going to next error, previous error, etc now work\n"
                             "  on any buffer with jump locations including *search*\n"
                             "-4coder now supports proper, borderless, fullscreen with the flag -F\n"
diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp
index 2aebafc1..49d943cc 100644
--- a/4ed_api_implementation.cpp
+++ b/4ed_api_implementation.cpp
@@ -860,7 +860,10 @@ DOC_SEE(Buffer_Setting_ID)
                 b32 full_remeasure = 0;
                 if (value){
                     if (!file->settings.virtual_white){
-                        if (file->settings.tokens_exist && !file->state.still_lexing){
+                        if (!file->settings.tokens_exist){
+                            file_first_lex_serial(system, &models->mem, file);
+                        }
+                        if (!file->state.still_lexing){
                         file->settings.virtual_white = 1;
                         full_remeasure = 1;
                         }
diff --git a/build.c b/build.c
index 52eac7a3..cfba01c3 100644
--- a/build.c
+++ b/build.c
@@ -720,6 +720,7 @@ standard_build(char *cdir, uint32_t flags){
 
 #define PACK_DIR "../distributions"
 #define PACK_DATA_DIR "../data/dist_files"
+#define DATA_DIR "../data/test"
 
 #define PACK_ALPHA_PAR_DIR "../current_dist"
 #define PACK_SUPER_PAR_DIR "../current_dist_super"
@@ -785,6 +786,7 @@ package(char *cdir){
     copy_all (PACK_DATA_DIR"/*", PACK_ALPHA_DIR);
     copy_file(0, "README.txt", PACK_ALPHA_DIR, 0);
     copy_file(0, "TODO.txt", PACK_ALPHA_DIR, 0);
+    copy_file(DATA_DIR, "config.4coder", PACK_ALPHA_DIR, 0);
     
     get_4coder_dist_name(&str, 1, "alpha", "zip");
     zip(PACK_ALPHA_PAR_DIR, "4coder", str.str);
@@ -803,6 +805,7 @@ package(char *cdir){
     copy_all (PACK_DATA_DIR"/*", PACK_SUPER_DIR);
     copy_file(0, "README.txt", PACK_SUPER_DIR, 0);
     copy_file(0, "TODO.txt", PACK_SUPER_DIR, 0);
+    copy_file(DATA_DIR, "config.4coder", PACK_SUPER_DIR, 0);
     
     copy_all ("4coder_*.h", PACK_SUPER_DIR);
     copy_all ("4coder_*.cpp", PACK_SUPER_DIR);
diff --git a/power/4coder_experiments.cpp b/power/4coder_experiments.cpp
index 770c1714..ac4c6536 100644
--- a/power/4coder_experiments.cpp
+++ b/power/4coder_experiments.cpp
@@ -609,33 +609,14 @@ CUSTOM_COMMAND_SIG(write_explicit_enum_values){
     end_temp_memory(temp);
 }
 
-// TODO(allen): Query theme settings
-#if 0
-CUSTOM_COMMAND_SIG(save_theme_settings){
-    FILE *file = fopen(".4coder_settings", "rb");
-    char theme_name[128];
-    char font_name[128];
-    
-    fscanf(file, "%*128s %*128s", theme_name, font_name);
-    
-    if (file){
-        replace_char(theme_name, '#', ' ');
-        replace_char(font_name, '#', ' ');
-        
-        fclose(file);
-        
-        change_theme(app, theme_name, strlen(theme_name));
-        change_font(app, font_name, strlen(font_name));
-    }
-}
-#endif
-
 #include <stdio.h>
 
 #define SETTINGS_FILE ".4coder_settings"
 HOOK_SIG(experimental_start){
     init_memory(app);
     
+    process_config_file(app);
+    
     char theme_name[128];
     char font_name[128];
     
@@ -664,13 +645,13 @@ HOOK_SIG(experimental_start){
         
         change_theme(app, theme_name, theme_len);
         change_font(app, font_name, font_len, true);
-        
-        exec_command(app, open_panel_vsplit);
-        exec_command(app, hide_scrollbar);
-        exec_command(app, change_active_panel);
-        exec_command(app, hide_scrollbar);
     }
     
+    exec_command(app, open_panel_vsplit);
+    exec_command(app, hide_scrollbar);
+    exec_command(app, change_active_panel);
+    exec_command(app, hide_scrollbar);
+    
     return(0);
 }