diff --git a/bin/4ed_build.cpp b/bin/4ed_build.cpp index 4362da1a..235e2813 100644 --- a/bin/4ed_build.cpp +++ b/bin/4ed_build.cpp @@ -1,613 +1,613 @@ -/* - * Mr. 4th Dimention - Allen Webster - * - * ??.??.???? - * - * 4coder development build rule. - * - */ - -// TOP - -//#define FM_PRINT_COMMANDS - -#include "4coder_base_types.h" -#include "4coder_version.h" - -#include "4coder_base_types.cpp" -#include "4coder_malloc_allocator.cpp" - -#define FTECH_FILE_MOVING_IMPLEMENTATION -#include "4coder_file_moving.h" - - -// -// OS and compiler index -// - -enum{ - Platform_Windows, - Platform_Linux, - Platform_Mac, - // - Platform_COUNT, - Platform_None = Platform_COUNT, -}; - -char *platform_names[] = { - "win", - "linux", - "mac", -}; - -enum{ - Compiler_CL, - Compiler_GCC, - // - Compiler_COUNT, - Compiler_None = Compiler_COUNT, -}; - -char *compiler_names[] = { - "cl", - "gcc", -}; - -#if OS_WINDOWS -# define This_OS Platform_Windows -#elif OS_LINUX -# define This_OS Platform_Linux -#elif OS_MAC -# define This_OS Platform_Mac -#else -# error This platform is not enumerated. -#endif - -#if COMPILER_CL -# define This_Compiler Compiler_CL -#elif COMPILER_GCC -# define This_Compiler Compiler_GCC -#else -# error This compilers is not enumerated. -#endif - -// -// Universal directories -// - -#define BUILD_DIR "../build" -#define PACK_DIR "../distributions" -#define SITE_DIR "../site" - -#define FOREIGN "../4coder-non-source/foreign" -#define FOREIGN_WIN "..\\4coder-non-source\\foreign" - -char *includes[] = { "custom", FOREIGN "/freetype2", 0, }; - -// -// Platform layer file tables -// - -char *windows_platform_layer[] = { "platform_win32/win32_4ed.cpp", 0 }; -char *linux_platform_layer[] = { "platform_linux/linux_4ed.cpp", 0 }; -char *mac_platform_layer[] = { "platform_mac/mac_4ed.m", "platform_mac/mac_4ed.cpp", 0 }; - -char **platform_layers[Platform_COUNT] = { - windows_platform_layer, - linux_platform_layer , - mac_platform_layer , -}; - -char *windows_cl_platform_inc[] = { "platform_all", 0 }; -char *linux_gcc_platform_inc[] = { "platform_all", "platform_unix", 0 }; -char *mac_gcc_platform_inc[] = { "platform_all", "platform_unix", 0 }; - -char **platform_includes[Platform_COUNT][Compiler_COUNT] = { - {windows_cl_platform_inc, 0 }, - {0 , linux_gcc_platform_inc}, - {0 , mac_gcc_platform_inc }, -}; - -char *default_custom_target = "../code/custom/4coder_default_bindings.cpp"; - -// NOTE(allen): Architectures - -enum{ - Arch_X64, - Arch_X86, - - // - Arch_COUNT, - Arch_None = Arch_COUNT, -}; - -char *arch_names[] = { - "x64", - "x86", -}; - -// NOTE(allen): Build flags - -enum{ - OPTS = 0x1, - LIBS = 0x2, - ICON = 0x4, - SHARED_CODE = 0x8, - DEBUG_INFO = 0x10, - OPTIMIZATION = 0x20, - SUPER = 0x40, - INTERNAL = 0x80, - SHIP = 0x100, -}; - -internal char** -get_defines_from_flags(Arena *arena, u32 flags){ - char **result = 0; - if (HasFlag(flags, SHIP)){ - result = fm_list(arena, fm_list_one_item(arena, "SHIP_MODE"), result); - } - if (HasFlag(flags, INTERNAL)){ - result = fm_list(arena, fm_list_one_item(arena, "FRED_INTERNAL"), result); - } - if (HasFlag(flags, SUPER)){ - result = fm_list(arena, fm_list_one_item(arena, "FRED_SUPER"), result); - } - return(result); -} - -// -// build implementation: cl -// - -#if COMPILER_CL - -#define CL_OPTS \ -"-W4 -wd4310 -wd4100 -wd4201 -wd4505 -wd4996 " \ -"-wd4127 -wd4510 -wd4512 -wd4610 -wd4390 " \ -"-wd4611 -wd4189 -WX -GR- -EHa- -nologo -FC" - -#define CL_LIBS_X64 \ -"user32.lib winmm.lib gdi32.lib opengl32.lib comdlg32.lib " \ -FOREIGN_WIN "\\x64\\freetype.lib" - -#define CL_LIBS_X86 \ -"user32.lib winmm.lib gdi32.lib opengl32.lib comdlg32.lib " \ -FOREIGN_WIN "\\x86\\freetype.lib" - -#define CL_ICON "..\\4coder-non-source\\res\\icon.res" - -internal void -build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, char *out_path, char *out_file, char **defines, char **exports, char **inc_folders){ - Temp_Dir temp = fm_pushdir(out_path); - - Build_Line line; - fm_init_build_line(&line); - - if (arch == Arch_X86){ - fm_add_to_line(line, "%s\\custom\\bin\\setup_cl_x86.bat &", code_path); - } - - fm_add_to_line(line, "cl"); - - if (flags & OPTS){ - fm_add_to_line(line, CL_OPTS); - } - - switch (arch){ - case Arch_X64: fm_add_to_line(line, "-DFTECH_64_BIT"); break; - case Arch_X86: fm_add_to_line(line, "-DFTECH_32_BIT"); break; - default: InvalidPath; - } - - fm_add_to_line(line, "-I%s", code_path); - if (inc_folders != 0){ - for (u32 i = 0; inc_folders[i] != 0; ++i){ - char *str = fm_str(arena, code_path, "/", inc_folders[i]); - fm_add_to_line(line, "-I%s", str); - } - } - - if (flags & LIBS){ - switch (arch){ - case Arch_X64: fm_add_to_line(line, CL_LIBS_X64); break; - case Arch_X86: fm_add_to_line(line, CL_LIBS_X86); break; - default: InvalidPath; - } - } - - if (flags & ICON){ - fm_add_to_line(line, CL_ICON); - } - - if (flags & DEBUG_INFO){ - fm_add_to_line(line, "-Zi"); - fm_add_to_line(line, "-DDO_CRAZY_EXPENSIVE_ASSERTS"); - } - - if (flags & OPTIMIZATION){ - fm_add_to_line(line, "-O2"); - } - - if (flags & SHARED_CODE){ - fm_add_to_line(line, "-LD"); - } - - if (defines != 0){ - for (u32 i = 0; defines[i] != 0; ++i){ - char *define_flag = fm_str(arena, "-D", defines[i]); - fm_add_to_line(line, "%s", define_flag); - } - } - - for (u32 i = 0; code_files[i]; ++i){ - fm_add_to_line(line, "\"%s\\%s\"", code_path, code_files[i]); - } - - fm_add_to_line(line, "-Fe%s", out_file); - - fm_add_to_line(line, "-link -INCREMENTAL:NO -RELEASE -PDBALTPATH:%%_PDB%%"); - switch (arch){ - case Arch_X64: fm_add_to_line(line, "-MACHINE:X64"); break; - case Arch_X86: fm_add_to_line(line, "-MACHINE:X86"); break; - default: InvalidPath; - } - - if (flags & DEBUG_INFO){ - fm_add_to_line(line, "-DEBUG"); - } - - if (flags & SHARED_CODE){ - Assert(exports != 0); - fm_add_to_line(line, "-OPT:REF"); - for (u32 i = 0; exports[i] != 0; ++i){ - char *str = fm_str(arena, "-EXPORT:", exports[i]); - fm_add_to_line(line, "%s", str); - } - } - else{ - fm_add_to_line(line, "-NODEFAULTLIB:library"); - } - - fm_finish_build_line(&line); - - //printf("%s\n", line.build_options); - systemf("%s", line.build_options); - fm_popdir(temp); - - fflush(stdout); -} - -// -// build implementation: gcc -// - -#elif COMPILER_GCC - -#if OS_LINUX - -# define GCC_OPTS \ -"-Wno-write-strings " \ -"-D_GNU_SOURCE -fPIC " \ -"-fno-threadsafe-statics -pthread " \ -"-Wno-unused-result" - -#define GCC_LIBS_COMMON \ -"-lX11 -lpthread -lm -lrt " \ -"-lGL -ldl -lXfixes -lfreetype -lfontconfig" - -#define GCC_LIBS_X64 GCC_LIBS_COMMON -#define GCC_LIBS_X86 GCC_LIBS_COMMON - -#elif OS_MAC - -# define GCC_OPTS \ -"-Wno-write-strings -Wno-deprecated-declarations " \ -"-Wno-comment -Wno-switch -Wno-null-dereference " \ -"-Wno-tautological-compare " \ -"-Wno-unused-result " - -#define GCC_LIBS_COMMON \ -"-framework Cocoa -framework QuartzCore " \ -"-framework CoreServices " \ -"-framework OpenGL -framework IOKit " - -#define GCC_LIBS_X64 GCC_LIBS_COMMON \ -FOREIGN "/x64/libfreetype-mac.a" - -#define GCC_LIBS_X86 GCC_LIBS_COMMON \ -FOREIGN "/x86/libfreetype-mac.a" - -#else -# error gcc options not set for this platform -#endif - -internal void -build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, char *out_path, char *out_file, char **defines, char **exports, char **inc_folders){ - Build_Line line; - fm_init_build_line(&line); - - switch (arch){ - case Arch_X64: - fm_add_to_line(line, "-m64"); - fm_add_to_line(line, "-DFTECH_64_BIT"); break; - - case Arch_X86: - fm_add_to_line(line, "-m32"); - fm_add_to_line(line, "-DFTECH_32_BIT"); break; - - default: InvalidPath; - } - - if (flags & OPTS){ - fm_add_to_line(line, GCC_OPTS); - } - - fm_add_to_line(line, "-I%s", code_path); - if (inc_folders != 0){ - for (u32 i = 0; inc_folders[i] != 0; ++i){ - char *str = fm_str(arena, code_path, "/", inc_folders[i]); - fm_add_to_line(line, "-I%s", str); - } - } - - if (flags & DEBUG_INFO){ - fm_add_to_line(line, "-g -O0"); - } - - if (flags & OPTIMIZATION){ - fm_add_to_line(line, "-O3"); - } - - if (flags & SHARED_CODE){ - fm_add_to_line(line, "-shared"); - } - - if (defines != 0){ - for (u32 i = 0; defines[i]; ++i){ - char *define_flag = fm_str(arena, "-D", defines[i]); - fm_add_to_line(line, "%s", define_flag); - } - } - - fm_add_to_line(line, "-I\"%s\"", code_path); - for (u32 i = 0; code_files[i] != 0; ++i){ - fm_add_to_line(line, "\"%s/%s\"", code_path, code_files[i]); - } - - if (flags & LIBS){ - if (arch == Arch_X64){ - fm_add_to_line(line, GCC_LIBS_X64); - } - else if (arch == Arch_X86) - { - fm_add_to_line(line, GCC_LIBS_X86); - } - } - - fm_finish_build_line(&line); - - Temp_Dir temp = fm_pushdir(out_path); - systemf("g++ %s -o %s", line.build_options, out_file); - fm_popdir(temp); -} - -#else -# error build function not defined for this compiler -#endif - -internal void -build(Arena *arena, u32 flags, u32 arch, char *code_path, char *code_file, char *out_path, char *out_file, char **defines, char **exports, char **inc_folders){ - char **code_files = fm_list_one_item(arena, code_file); - build(arena, flags, arch, code_path, code_files, out_path, out_file, defines, exports, inc_folders); -} - -internal void -build_and_run(Arena *arena, char *cdir, char *filename, char *name, u32 flags){ - char *dir = fm_str(arena, BUILD_DIR); - - { - char *file = fm_str(arena, filename); - BEGIN_TIME_SECTION(); - build(arena, flags, Arch_X64, cdir, file, dir, name, get_defines_from_flags(arena, flags), 0, includes); - END_TIME_SECTION(fm_str(arena, "build ", name)); - } - - if (prev_error == 0){ - char *cmd = fm_str(arena, dir, "/", name); - BEGIN_TIME_SECTION(); - fm_execute_in_dir(cdir, cmd, 0); - END_TIME_SECTION(fm_str(arena, "run ", name)); - } -} - -internal void -buildsuper(Arena *arena, char *cdir, char *file, u32 arch){ - printf("BUILDSUPER: cdir: %s; file: %s; arch: %u\n", cdir, file, arch); - - BEGIN_TIME_SECTION(); - Temp_Dir temp = fm_pushdir(fm_str(arena, BUILD_DIR)); - - char *build_script = fm_str(arena, "custom/bin/buildsuper_", arch_names[arch], BAT); - - char *build_command = fm_str(arena, "\"", cdir, "/", build_script, "\" \"", file, "\""); - if (This_OS == Platform_Windows){ - build_command = fm_str(arena, "call ", build_command); - } - systemf("%s", build_command); - - fm_popdir(temp); - END_TIME_SECTION("build custom"); - fflush(stdout); -} - -internal void -build_main(Arena *arena, char *cdir, b32 update_local_theme, u32 flags, u32 arch){ - char *dir = fm_str(arena, BUILD_DIR); - - { - char *file = fm_str(arena, "4ed_app_target.cpp"); - char **exports = fm_list_one_item(arena, "app_get_functions"); - - char **build_includes = includes; - - BEGIN_TIME_SECTION(); - build(arena, OPTS | SHARED_CODE | flags, arch, cdir, file, dir, "4ed_app" DLL, get_defines_from_flags(arena, flags), exports, build_includes); - END_TIME_SECTION("build 4ed_app"); - } - - { - BEGIN_TIME_SECTION(); - char **inc = (char**)fm_list(arena, includes, platform_includes[This_OS][This_Compiler]); - build(arena, OPTS | LIBS | ICON | flags, arch, cdir, platform_layers[This_OS], dir, "4ed", get_defines_from_flags(arena, flags), 0, inc); - END_TIME_SECTION("build 4ed"); - } - - if (update_local_theme){ - BEGIN_TIME_SECTION(); - char *themes_folder = fm_str(arena, "../build/themes"); - char *source_themes_folder = fm_str(arena, "ship_files/themes"); - fm_clear_folder(themes_folder); - fm_make_folder_if_missing(arena, themes_folder); - fm_copy_all(source_themes_folder, themes_folder); - END_TIME_SECTION("move files"); - } - - fflush(stdout); -} - -internal void -standard_build(Arena *arena, char *cdir, u32 flags, u32 arch){ - buildsuper(arena, cdir, fm_str(arena, default_custom_target), arch); - build_main(arena, cdir, true, flags, arch); -} - -internal char* -get_4coder_dist_name(Arena *arena, u32 platform, char *tier, u32 arch){ - char *name = fm_str(arena, "4coder-" MAJOR_STR "-" MINOR_STR "-" PATCH_STR "-", tier); - if (platform != Platform_None){ - name = fm_str(arena, name, "-", platform_names[platform]); - } - if (arch != Arch_None){ - name = fm_str(arena, name, "-", arch_names[arch]); - } - return(name); -} - -enum{ - Tier_Demo, - Tier_Super, - Tier_COUNT, -}; - -internal void -package(Arena *arena, char *cdir){ - // NOTE(allen): meta - char *build_dir = fm_str(arena, BUILD_DIR); - char *pack_dir = fm_str(arena, PACK_DIR); - char *dist_files[3]; - dist_files[0] = fm_str(arena, "../4coder-non-source/dist_files"); - dist_files[1] = fm_str(arena, "ship_files"); - dist_files[2] = fm_str(arena, "ship_files_super"); - - printf("build dir: %s\n", build_dir); - printf("pack dir: %s\n", pack_dir); - printf("dist files: %s, %s, %s\n", dist_files[0], dist_files[1], dist_files[2]); - fflush(stdout); - - char *tier_names[] = { "demo", "super", }; - u32 base_flags = SHIP | DEBUG_INFO | OPTIMIZATION; - u32 tier_flags[] = { 0, SUPER, }; - - fm_make_folder_if_missing(arena, pack_dir); - - for (u32 i = 0; i < Tier_COUNT; i += 1){ - char *tier_name = tier_names[i]; - u32 flags = base_flags | tier_flags[i]; - - Temp_Memory temp = begin_temp(arena); - char *current_dist_tier = fm_str(arena, ".." SLASH "current_dist_", tier_name); - - for (u32 arch = 0; arch < Arch_COUNT; ++arch){ - char *arch_name = arch_names[arch]; - char *parent_dir = fm_str(arena, current_dist_tier, "_", arch_name); - char *dir = fm_str(arena, parent_dir, SLASH "4coder"); - char *zip_dir = fm_str(arena, pack_dir, SLASH, tier_name, "_", arch_name); - - printf("\nbuild: %s_%s\n", tier_name, arch_name); - printf("parent_dir: %s\n", parent_dir); - printf("dir: %s\n", dir); - printf("zip_dir: %s\n", zip_dir); - fflush(stdout); - - buildsuper(arena, cdir, fm_str(arena, default_custom_target), arch); - build_main(arena, cdir, false, flags, arch); - - fm_make_folder_if_missing(arena, parent_dir); - fm_clear_folder(parent_dir); - fm_make_folder_if_missing(arena, dir); - fm_copy_file(fm_str(arena, build_dir, "/4ed" EXE), fm_str(arena, dir, "/4ed" EXE)); - fm_copy_file(fm_str(arena, build_dir, "/4ed_app" DLL), fm_str(arena, dir, "/4ed_app" DLL)); - fm_copy_file(fm_str(arena, build_dir, "/custom_4coder" DLL), fm_str(arena, dir, "/custom_4coder" DLL)); - - i32 dist_file_count = ArrayCount(dist_files); - if (i == Tier_Demo){ - dist_file_count -= 1; - } - - for (i32 j = 0; j < dist_file_count; j += 1){ - fm_copy_all(dist_files[j], dir); - } - - if (i == Tier_Super){ - char *custom_src_dir = fm_str(arena, cdir, SLASH, "custom"); - char *custom_dst_dir = fm_str(arena, dir, SLASH, "custom"); - fm_make_folder_if_missing(arena, custom_dst_dir); - fm_copy_all(custom_src_dir, custom_dst_dir); - } - - char *dist_name = get_4coder_dist_name(arena, This_OS, tier_name, arch); - char *zip_name = fm_str(arena, zip_dir, SLASH, dist_name, ".zip"); - fm_make_folder_if_missing(arena, zip_dir); - fm_zip(parent_dir, "4coder", zip_name); - } - - end_temp(temp); - } -} - -int main(int argc, char **argv){ - Arena arena = fm_init_system(); - - char cdir[256]; - BEGIN_TIME_SECTION(); - i32 n = fm_get_current_directory(cdir, sizeof(cdir)); - Assert(n < sizeof(cdir)); - END_TIME_SECTION("current directory"); - - u32 flags = SUPER; - u32 arch = Arch_X64; - #if defined(DEV_BUILD) || defined(DEV_BUILD_X86) - flags |= DEBUG_INFO | INTERNAL; - #endif -#if defined(OPT_BUILD) || defined(OPT_BUILD_X86) - flags |= OPTIMIZATION; - #endif -#if defined(DEV_BUILD_X86) || defined(OPT_BUILD_X86) - arch = Arch_X86; -#endif - -#if defined(DEV_BUILD) || defined(OPT_BUILD) || defined(DEV_BUILD_X86) -standard_build(&arena, cdir, flags, arch); - -#elif defined(PACKAGE) - package(&arena, cdir); - -#else -# error No build type specified. -#endif - - return(error_state); -} - -// BOTTOM - +/* + * Mr. 4th Dimention - Allen Webster + * + * ??.??.???? + * + * 4coder development build rule. + * + */ + +// TOP + +//#define FM_PRINT_COMMANDS + +#include "4coder_base_types.h" +#include "4coder_version.h" + +#include "4coder_base_types.cpp" +#include "4coder_malloc_allocator.cpp" + +#define FTECH_FILE_MOVING_IMPLEMENTATION +#include "4coder_file_moving.h" + + +// +// OS and compiler index +// + +enum{ + Platform_Windows, + Platform_Linux, + Platform_Mac, + // + Platform_COUNT, + Platform_None = Platform_COUNT, +}; + +char *platform_names[] = { + "win", + "linux", + "mac", +}; + +enum{ + Compiler_CL, + Compiler_GCC, + // + Compiler_COUNT, + Compiler_None = Compiler_COUNT, +}; + +char *compiler_names[] = { + "cl", + "gcc", +}; + +#if OS_WINDOWS +# define This_OS Platform_Windows +#elif OS_LINUX +# define This_OS Platform_Linux +#elif OS_MAC +# define This_OS Platform_Mac +#else +# error This platform is not enumerated. +#endif + +#if COMPILER_CL +# define This_Compiler Compiler_CL +#elif COMPILER_GCC +# define This_Compiler Compiler_GCC +#else +# error This compilers is not enumerated. +#endif + +// +// Universal directories +// + +#define BUILD_DIR "../build" +#define PACK_DIR "../distributions" +#define SITE_DIR "../site" + +#define FOREIGN "../4coder-non-source/foreign" +#define FOREIGN_WIN "..\\4coder-non-source\\foreign" + +char *includes[] = { "custom", FOREIGN "/freetype2", 0, }; + +// +// Platform layer file tables +// + +char *windows_platform_layer[] = { "platform_win32/win32_4ed.cpp", 0 }; +char *linux_platform_layer[] = { "platform_linux/linux_4ed.cpp", 0 }; +char *mac_platform_layer[] = { "platform_mac/mac_4ed.m", "platform_mac/mac_4ed.cpp", 0 }; + +char **platform_layers[Platform_COUNT] = { + windows_platform_layer, + linux_platform_layer , + mac_platform_layer , +}; + +char *windows_cl_platform_inc[] = { "platform_all", 0 }; +char *linux_gcc_platform_inc[] = { "platform_all", "platform_unix", 0 }; +char *mac_gcc_platform_inc[] = { "platform_all", "platform_unix", 0 }; + +char **platform_includes[Platform_COUNT][Compiler_COUNT] = { + {windows_cl_platform_inc, 0 }, + {0 , linux_gcc_platform_inc}, + {0 , mac_gcc_platform_inc }, +}; + +char *default_custom_target = "../code/custom/4coder_default_bindings.cpp"; + +// NOTE(allen): Architectures + +enum{ + Arch_X64, + Arch_X86, + + // + Arch_COUNT, + Arch_None = Arch_COUNT, +}; + +char *arch_names[] = { + "x64", + "x86", +}; + +// NOTE(allen): Build flags + +enum{ + OPTS = 0x1, + LIBS = 0x2, + ICON = 0x4, + SHARED_CODE = 0x8, + DEBUG_INFO = 0x10, + OPTIMIZATION = 0x20, + SUPER = 0x40, + INTERNAL = 0x80, + SHIP = 0x100, +}; + +internal char** +get_defines_from_flags(Arena *arena, u32 flags){ + char **result = 0; + if (HasFlag(flags, SHIP)){ + result = fm_list(arena, fm_list_one_item(arena, "SHIP_MODE"), result); + } + if (HasFlag(flags, INTERNAL)){ + result = fm_list(arena, fm_list_one_item(arena, "FRED_INTERNAL"), result); + } + if (HasFlag(flags, SUPER)){ + result = fm_list(arena, fm_list_one_item(arena, "FRED_SUPER"), result); + } + return(result); +} + +// +// build implementation: cl +// + +#if COMPILER_CL + +#define CL_OPTS \ +"-W4 -wd4310 -wd4100 -wd4201 -wd4505 -wd4996 " \ +"-wd4127 -wd4510 -wd4512 -wd4610 -wd4390 " \ +"-wd4611 -wd4189 -WX -GR- -EHa- -nologo -FC" + +#define CL_LIBS_X64 \ +"user32.lib winmm.lib gdi32.lib opengl32.lib comdlg32.lib " \ +FOREIGN_WIN "\\x64\\freetype.lib" + +#define CL_LIBS_X86 \ +"user32.lib winmm.lib gdi32.lib opengl32.lib comdlg32.lib " \ +FOREIGN_WIN "\\x86\\freetype.lib" + +#define CL_ICON "..\\4coder-non-source\\res\\icon.res" + +internal void +build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, char *out_path, char *out_file, char **defines, char **exports, char **inc_folders){ + Temp_Dir temp = fm_pushdir(out_path); + + Build_Line line; + fm_init_build_line(&line); + + if (arch == Arch_X86){ + fm_add_to_line(line, "%s\\custom\\bin\\setup_cl_x86.bat &", code_path); + } + + fm_add_to_line(line, "cl"); + + if (flags & OPTS){ + fm_add_to_line(line, CL_OPTS); + } + + switch (arch){ + case Arch_X64: fm_add_to_line(line, "-DFTECH_64_BIT"); break; + case Arch_X86: fm_add_to_line(line, "-DFTECH_32_BIT"); break; + default: InvalidPath; + } + + fm_add_to_line(line, "-I%s", code_path); + if (inc_folders != 0){ + for (u32 i = 0; inc_folders[i] != 0; ++i){ + char *str = fm_str(arena, code_path, "/", inc_folders[i]); + fm_add_to_line(line, "-I%s", str); + } + } + + if (flags & LIBS){ + switch (arch){ + case Arch_X64: fm_add_to_line(line, CL_LIBS_X64); break; + case Arch_X86: fm_add_to_line(line, CL_LIBS_X86); break; + default: InvalidPath; + } + } + + if (flags & ICON){ + fm_add_to_line(line, CL_ICON); + } + + if (flags & DEBUG_INFO){ + fm_add_to_line(line, "-Zi"); + fm_add_to_line(line, "-DDO_CRAZY_EXPENSIVE_ASSERTS"); + } + + if (flags & OPTIMIZATION){ + fm_add_to_line(line, "-O2"); + } + + if (flags & SHARED_CODE){ + fm_add_to_line(line, "-LD"); + } + + if (defines != 0){ + for (u32 i = 0; defines[i] != 0; ++i){ + char *define_flag = fm_str(arena, "-D", defines[i]); + fm_add_to_line(line, "%s", define_flag); + } + } + + for (u32 i = 0; code_files[i]; ++i){ + fm_add_to_line(line, "\"%s\\%s\"", code_path, code_files[i]); + } + + fm_add_to_line(line, "-Fe%s", out_file); + + fm_add_to_line(line, "-link -INCREMENTAL:NO -RELEASE -PDBALTPATH:%%_PDB%%"); + switch (arch){ + case Arch_X64: fm_add_to_line(line, "-MACHINE:X64"); break; + case Arch_X86: fm_add_to_line(line, "-MACHINE:X86"); break; + default: InvalidPath; + } + + if (flags & DEBUG_INFO){ + fm_add_to_line(line, "-DEBUG"); + } + + if (flags & SHARED_CODE){ + Assert(exports != 0); + fm_add_to_line(line, "-OPT:REF"); + for (u32 i = 0; exports[i] != 0; ++i){ + char *str = fm_str(arena, "-EXPORT:", exports[i]); + fm_add_to_line(line, "%s", str); + } + } + else{ + fm_add_to_line(line, "-NODEFAULTLIB:library"); + } + + fm_finish_build_line(&line); + + //printf("%s\n", line.build_options); + systemf("%s", line.build_options); + fm_popdir(temp); + + fflush(stdout); +} + +// +// build implementation: gcc +// + +#elif COMPILER_GCC + +#if OS_LINUX + +# define GCC_OPTS \ +"-Wno-write-strings " \ +"-D_GNU_SOURCE -fPIC " \ +"-fno-threadsafe-statics -pthread " \ +"-Wno-unused-result" + +#define GCC_LIBS_COMMON \ +"-lX11 -lpthread -lm -lrt " \ +"-lGL -ldl -lXfixes -lfreetype -lfontconfig" + +#define GCC_LIBS_X64 GCC_LIBS_COMMON +#define GCC_LIBS_X86 GCC_LIBS_COMMON + +#elif OS_MAC + +# define GCC_OPTS \ +"-Wno-write-strings -Wno-deprecated-declarations " \ +"-Wno-comment -Wno-switch -Wno-null-dereference " \ +"-Wno-tautological-compare " \ +"-Wno-unused-result " + +#define GCC_LIBS_COMMON \ +"-framework Cocoa -framework QuartzCore " \ +"-framework CoreServices " \ +"-framework OpenGL -framework IOKit " + +#define GCC_LIBS_X64 GCC_LIBS_COMMON \ +FOREIGN "/x64/libfreetype-mac.a" + +#define GCC_LIBS_X86 GCC_LIBS_COMMON \ +FOREIGN "/x86/libfreetype-mac.a" + +#else +# error gcc options not set for this platform +#endif + +internal void +build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, char *out_path, char *out_file, char **defines, char **exports, char **inc_folders){ + Build_Line line; + fm_init_build_line(&line); + + switch (arch){ + case Arch_X64: + fm_add_to_line(line, "-m64"); + fm_add_to_line(line, "-DFTECH_64_BIT"); break; + + case Arch_X86: + fm_add_to_line(line, "-m32"); + fm_add_to_line(line, "-DFTECH_32_BIT"); break; + + default: InvalidPath; + } + + if (flags & OPTS){ + fm_add_to_line(line, GCC_OPTS); + } + + fm_add_to_line(line, "-I%s", code_path); + if (inc_folders != 0){ + for (u32 i = 0; inc_folders[i] != 0; ++i){ + char *str = fm_str(arena, code_path, "/", inc_folders[i]); + fm_add_to_line(line, "-I%s", str); + } + } + + if (flags & DEBUG_INFO){ + fm_add_to_line(line, "-g -O0"); + } + + if (flags & OPTIMIZATION){ + fm_add_to_line(line, "-O3"); + } + + if (flags & SHARED_CODE){ + fm_add_to_line(line, "-shared"); + } + + if (defines != 0){ + for (u32 i = 0; defines[i]; ++i){ + char *define_flag = fm_str(arena, "-D", defines[i]); + fm_add_to_line(line, "%s", define_flag); + } + } + + fm_add_to_line(line, "-I\"%s\"", code_path); + for (u32 i = 0; code_files[i] != 0; ++i){ + fm_add_to_line(line, "\"%s/%s\"", code_path, code_files[i]); + } + + if (flags & LIBS){ + if (arch == Arch_X64){ + fm_add_to_line(line, GCC_LIBS_X64); + } + else if (arch == Arch_X86) + { + fm_add_to_line(line, GCC_LIBS_X86); + } + } + + fm_finish_build_line(&line); + + Temp_Dir temp = fm_pushdir(out_path); + systemf("g++ %s -o %s", line.build_options, out_file); + fm_popdir(temp); +} + +#else +# error build function not defined for this compiler +#endif + +internal void +build(Arena *arena, u32 flags, u32 arch, char *code_path, char *code_file, char *out_path, char *out_file, char **defines, char **exports, char **inc_folders){ + char **code_files = fm_list_one_item(arena, code_file); + build(arena, flags, arch, code_path, code_files, out_path, out_file, defines, exports, inc_folders); +} + +internal void +build_and_run(Arena *arena, char *cdir, char *filename, char *name, u32 flags){ + char *dir = fm_str(arena, BUILD_DIR); + + { + char *file = fm_str(arena, filename); + BEGIN_TIME_SECTION(); + build(arena, flags, Arch_X64, cdir, file, dir, name, get_defines_from_flags(arena, flags), 0, includes); + END_TIME_SECTION(fm_str(arena, "build ", name)); + } + + if (prev_error == 0){ + char *cmd = fm_str(arena, dir, "/", name); + BEGIN_TIME_SECTION(); + fm_execute_in_dir(cdir, cmd, 0); + END_TIME_SECTION(fm_str(arena, "run ", name)); + } +} + +internal void +buildsuper(Arena *arena, char *cdir, char *file, u32 arch){ + printf("BUILDSUPER: cdir: %s; file: %s; arch: %u\n", cdir, file, arch); + + BEGIN_TIME_SECTION(); + Temp_Dir temp = fm_pushdir(fm_str(arena, BUILD_DIR)); + + char *build_script = fm_str(arena, "custom/bin/buildsuper_", arch_names[arch], BAT); + + char *build_command = fm_str(arena, "\"", cdir, "/", build_script, "\" \"", file, "\""); + if (This_OS == Platform_Windows){ + build_command = fm_str(arena, "call ", build_command); + } + systemf("%s", build_command); + + fm_popdir(temp); + END_TIME_SECTION("build custom"); + fflush(stdout); +} + +internal void +build_main(Arena *arena, char *cdir, b32 update_local_theme, u32 flags, u32 arch){ + char *dir = fm_str(arena, BUILD_DIR); + + { + char *file = fm_str(arena, "4ed_app_target.cpp"); + char **exports = fm_list_one_item(arena, "app_get_functions"); + + char **build_includes = includes; + + BEGIN_TIME_SECTION(); + build(arena, OPTS | SHARED_CODE | flags, arch, cdir, file, dir, "4ed_app" DLL, get_defines_from_flags(arena, flags), exports, build_includes); + END_TIME_SECTION("build 4ed_app"); + } + + { + BEGIN_TIME_SECTION(); + char **inc = (char**)fm_list(arena, includes, platform_includes[This_OS][This_Compiler]); + build(arena, OPTS | LIBS | ICON | flags, arch, cdir, platform_layers[This_OS], dir, "4ed", get_defines_from_flags(arena, flags), 0, inc); + END_TIME_SECTION("build 4ed"); + } + + if (update_local_theme){ + BEGIN_TIME_SECTION(); + char *themes_folder = fm_str(arena, "../build/themes"); + char *source_themes_folder = fm_str(arena, "ship_files/themes"); + fm_clear_folder(themes_folder); + fm_make_folder_if_missing(arena, themes_folder); + fm_copy_all(source_themes_folder, themes_folder); + END_TIME_SECTION("move files"); + } + + fflush(stdout); +} + +internal void +standard_build(Arena *arena, char *cdir, u32 flags, u32 arch){ + buildsuper(arena, cdir, fm_str(arena, default_custom_target), arch); + build_main(arena, cdir, true, flags, arch); +} + +internal char* +get_4coder_dist_name(Arena *arena, u32 platform, char *tier, u32 arch){ + char *name = fm_str(arena, "4coder-" MAJOR_STR "-" MINOR_STR "-" PATCH_STR "-", tier); + if (platform != Platform_None){ + name = fm_str(arena, name, "-", platform_names[platform]); + } + if (arch != Arch_None){ + name = fm_str(arena, name, "-", arch_names[arch]); + } + return(name); +} + +enum{ + Tier_Demo, + Tier_Super, + Tier_COUNT, +}; + +internal void +package(Arena *arena, char *cdir){ + // NOTE(allen): meta + char *build_dir = fm_str(arena, BUILD_DIR); + char *pack_dir = fm_str(arena, PACK_DIR); + char *dist_files[3]; + dist_files[0] = fm_str(arena, "../4coder-non-source/dist_files"); + dist_files[1] = fm_str(arena, "ship_files"); + dist_files[2] = fm_str(arena, "ship_files_super"); + + printf("build dir: %s\n", build_dir); + printf("pack dir: %s\n", pack_dir); + printf("dist files: %s, %s, %s\n", dist_files[0], dist_files[1], dist_files[2]); + fflush(stdout); + + char *tier_names[] = { "demo", "super", }; + u32 base_flags = SHIP | DEBUG_INFO | OPTIMIZATION; + u32 tier_flags[] = { 0, SUPER, }; + + fm_make_folder_if_missing(arena, pack_dir); + + for (u32 i = 0; i < Tier_COUNT; i += 1){ + char *tier_name = tier_names[i]; + u32 flags = base_flags | tier_flags[i]; + + Temp_Memory temp = begin_temp(arena); + char *current_dist_tier = fm_str(arena, ".." SLASH "current_dist_", tier_name); + + for (u32 arch = 0; arch < Arch_COUNT; ++arch){ + char *arch_name = arch_names[arch]; + char *parent_dir = fm_str(arena, current_dist_tier, "_", arch_name); + char *dir = fm_str(arena, parent_dir, SLASH "4coder"); + char *zip_dir = fm_str(arena, pack_dir, SLASH, tier_name, "_", arch_name); + + printf("\nbuild: %s_%s\n", tier_name, arch_name); + printf("parent_dir: %s\n", parent_dir); + printf("dir: %s\n", dir); + printf("zip_dir: %s\n", zip_dir); + fflush(stdout); + + buildsuper(arena, cdir, fm_str(arena, default_custom_target), arch); + build_main(arena, cdir, false, flags, arch); + + fm_make_folder_if_missing(arena, parent_dir); + fm_clear_folder(parent_dir); + fm_make_folder_if_missing(arena, dir); + fm_copy_file(fm_str(arena, build_dir, "/4ed" EXE), fm_str(arena, dir, "/4ed" EXE)); + fm_copy_file(fm_str(arena, build_dir, "/4ed_app" DLL), fm_str(arena, dir, "/4ed_app" DLL)); + fm_copy_file(fm_str(arena, build_dir, "/custom_4coder" DLL), fm_str(arena, dir, "/custom_4coder" DLL)); + + i32 dist_file_count = ArrayCount(dist_files); + if (i == Tier_Demo){ + dist_file_count -= 1; + } + + for (i32 j = 0; j < dist_file_count; j += 1){ + fm_copy_all(dist_files[j], dir); + } + + if (i == Tier_Super){ + char *custom_src_dir = fm_str(arena, cdir, SLASH, "custom"); + char *custom_dst_dir = fm_str(arena, dir, SLASH, "custom"); + fm_make_folder_if_missing(arena, custom_dst_dir); + fm_copy_all(custom_src_dir, custom_dst_dir); + } + + char *dist_name = get_4coder_dist_name(arena, This_OS, tier_name, arch); + char *zip_name = fm_str(arena, zip_dir, SLASH, dist_name, ".zip"); + fm_make_folder_if_missing(arena, zip_dir); + fm_zip(parent_dir, "4coder", zip_name); + } + + end_temp(temp); + } +} + +int main(int argc, char **argv){ + Arena arena = fm_init_system(); + + char cdir[256]; + BEGIN_TIME_SECTION(); + i32 n = fm_get_current_directory(cdir, sizeof(cdir)); + Assert(n < sizeof(cdir)); + END_TIME_SECTION("current directory"); + + u32 flags = SUPER; + u32 arch = Arch_X64; +#if defined(DEV_BUILD) || defined(DEV_BUILD_X86) + flags |= DEBUG_INFO | INTERNAL; +#endif +#if defined(OPT_BUILD) || defined(OPT_BUILD_X86) + flags |= OPTIMIZATION; +#endif +#if defined(DEV_BUILD_X86) || defined(OPT_BUILD_X86) + arch = Arch_X86; +#endif + +#if defined(DEV_BUILD) || defined(OPT_BUILD) || defined(DEV_BUILD_X86) + standard_build(&arena, cdir, flags, arch); + +#elif defined(PACKAGE) + package(&arena, cdir); + +#else +# error No build type specified. +#endif + + return(error_state); +} + +// BOTTOM + diff --git a/bin/build.sh b/bin/build.sh index 0d01ab2d..491067b0 100755 --- a/bin/build.sh +++ b/bin/build.sh @@ -4,7 +4,8 @@ set -e # Set up directories (mirrors build.bat) -ME="$(readlink -f "$0")" +# NOTE(yuval): Temporary fix that works only for macOS +ME="$(greadlink -f "$0")" LOCATION="$(dirname "$ME")" SRC_ROOT="$(dirname "$LOCATION")" PROJECT_ROOT="$(dirname "$SRC_ROOT")" @@ -29,7 +30,7 @@ os=$("$BIN_ROOT/detect_os.sh") if [[ "$os" == "linux" ]]; then WARNINGS="-Wno-write-strings -Wno-comment" elif [[ "$os" == "mac" ]]; then -WARNINGS="-Wno-write-strings -Wno-comment -Wno-logical-op-parentheses -Wno-null-dereference -Wno-switch" +WARNINGS="-Wno-write-strings -Wno-comment -Wno-null-dereference -Wno-switch" fi FLAGS="-D_GNU_SOURCE -fPIC -fpermissive $BUILD_MODE" diff --git a/custom/4coder_base_types.cpp b/custom/4coder_base_types.cpp index 9f7b3483..2209ff55 100644 --- a/custom/4coder_base_types.cpp +++ b/custom/4coder_base_types.cpp @@ -1727,7 +1727,7 @@ Ii32_size(i32 pos, i32 size){ function Range_i64 Ii64_size(i64 pos, i64 size){ return(Ii64(pos, pos + size)); -} +} function Range_u64 Iu64_size(u64 pos, u64 size){ return(Iu64(pos, pos + size)); @@ -2978,7 +2978,7 @@ make_base_allocator(Base_Allocator_Reserve_Signature *func_reserve, } function Data base_allocate__inner(Base_Allocator *allocator, u64 size, String_Const_u8 location){ - u64 full_size = 0; + u64 full_size = 0; void *memory = allocator->reserve(allocator->user_data, size, &full_size, location); allocator->commit(allocator->user_data, memory, full_size); return(make_data(memory, (u64)full_size)); @@ -5281,7 +5281,7 @@ push_string_copy(Arena *arena, u64 size, String_Const_Any src){ return(string); } - function String_Const_u8_Array +function String_Const_u8_Array push_string_array_copy(Arena *arena, String_Const_u8_Array src){ String_Const_u8_Array result = {}; result.vals = push_array(arena, String_Const_u8, src.count); @@ -6943,10 +6943,10 @@ global_const u8 integer_symbol_reverse[128] = { global_const u8 base64[64] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_', '$', }; diff --git a/custom/4coder_code_index.cpp b/custom/4coder_code_index.cpp index 2e7d0fcc..e3237f92 100644 --- a/custom/4coder_code_index.cpp +++ b/custom/4coder_code_index.cpp @@ -1,1173 +1,1173 @@ -/* -4coder_code_index.cpp - Generic code indexing system for layout, definition jumps, etc. -*/ - -// TOP - -global Code_Index global_code_index = {}; - -function void -code_index_init(void){ - global_code_index.mutex = system_mutex_make(); - global_code_index.node_arena = make_arena_system(KB(4)); - global_code_index.buffer_to_index_file = make_table_u64_u64(global_code_index.node_arena.base_allocator, 500); -} - -function Code_Index_File_Storage* -code_index__alloc_storage(void){ - Code_Index_File_Storage *result = global_code_index.free_storage; - if (result == 0){ - result = push_array_zero(&global_code_index.node_arena, Code_Index_File_Storage, 1); - } - else{ - sll_stack_pop(global_code_index.free_storage); - } - zdll_push_back(global_code_index.storage_first, global_code_index.storage_last, result); - global_code_index.storage_count += 1; - return(result); -} - -function void -code_index__free_storage(Code_Index_File_Storage *storage){ - zdll_remove(global_code_index.storage_first, global_code_index.storage_last, storage); - global_code_index.storage_count -= 1; - sll_stack_push(global_code_index.free_storage, storage); -} - -function void -code_index_push_nest(Code_Index_Nest_List *list, Code_Index_Nest *nest){ - sll_queue_push(list->first, list->last, nest); - list->count += 1; -} - -function Code_Index_Nest_Ptr_Array -code_index_nest_ptr_array_from_list(Arena *arena, Code_Index_Nest_List *list){ - Code_Index_Nest_Ptr_Array array = {}; - array.ptrs = push_array_zero(arena, Code_Index_Nest*, list->count); - array.count = list->count; - i32 counter = 0; - for (Code_Index_Nest *node = list->first; - node != 0; - node = node->next){ - array.ptrs[counter] = node; - counter += 1; - } - return(array); -} - -function Code_Index_Note_Ptr_Array -code_index_note_ptr_array_from_list(Arena *arena, Code_Index_Note_List *list){ - Code_Index_Note_Ptr_Array array = {}; - array.ptrs = push_array_zero(arena, Code_Index_Note*, list->count); - array.count = list->count; - i32 counter = 0; - for (Code_Index_Note *node = list->first; - node != 0; - node = node->next){ - array.ptrs[counter] = node; - counter += 1; - } - return(array); -} - -function void -code_index_lock(void){ - system_mutex_acquire(global_code_index.mutex); -} - -function void -code_index_unlock(void){ - system_mutex_release(global_code_index.mutex); -} - -function void -code_index_set_file(Buffer_ID buffer, Arena arena, Code_Index_File *index){ - Code_Index_File_Storage *storage = 0; - Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); - if (lookup.found_match){ - u64 val = 0; - table_read(&global_code_index.buffer_to_index_file, lookup, &val); - storage = (Code_Index_File_Storage*)IntAsPtr(val); - linalloc_clear(&storage->arena); - } - else{ - storage = code_index__alloc_storage(); - table_insert(&global_code_index.buffer_to_index_file, buffer, (u64)PtrAsInt(storage)); - } - storage->arena = arena; - storage->file = index; -} - -function void -code_index_erase_file(Buffer_ID buffer){ - Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); - if (lookup.found_match){ - u64 val = 0; - table_read(&global_code_index.buffer_to_index_file, lookup, &val); - Code_Index_File_Storage *storage = (Code_Index_File_Storage*)IntAsPtr(val); - linalloc_clear(&storage->arena); - table_erase(&global_code_index.buffer_to_index_file, lookup); - code_index__free_storage(storage); - } -} - -function Code_Index_File* -code_index_get_file(Buffer_ID buffer){ - Code_Index_File *result = 0; - Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); - if (lookup.found_match){ - u64 val = 0; - table_read(&global_code_index.buffer_to_index_file, lookup, &val); - Code_Index_File_Storage *storage = (Code_Index_File_Storage*)IntAsPtr(val); - result = storage->file; - } - return(result); -} - -function Code_Index_Nest* -code_index_get_nest(Code_Index_Nest_Ptr_Array *array, i64 pos){ - Code_Index_Nest *result = 0; - i32 count = array->count; - Code_Index_Nest **nest_ptrs = array->ptrs; - for (i32 i = 0; i < count; i += 1){ - Code_Index_Nest *nest = nest_ptrs[i]; - if (nest->open.max <= pos && pos <= nest->close.min){ - Code_Index_Nest *sub_nest = - code_index_get_nest(&nest->nest_array, pos); - if (sub_nest != 0){ - result = sub_nest; - } - else{ - result = nest; - } - break; - } - } - return(result); -} - -function Code_Index_Nest* -code_index_get_nest(Code_Index_Nest *nest, i64 pos){ - return(code_index_get_nest(&nest->nest_array, pos)); -} - -function Code_Index_Nest* -code_index_get_nest(Code_Index_File *file, i64 pos){ - return(code_index_get_nest(&file->nest_array, pos)); -} - -function void -index_shift(i64 *ptr, Range_i64 old_range, u64 new_size){ - i64 i = *ptr; - if (old_range.min <= i && i < old_range.max){ - *ptr = old_range.first; - } - else if (old_range.max <= i){ - *ptr = i + new_size - (old_range.max - old_range.min); - } -} - -function void -code_index_shift(Code_Index_Nest_Ptr_Array *array, - Range_i64 old_range, u64 new_size){ - i32 count = array->count; - Code_Index_Nest **nest_ptr = array->ptrs; - for (i32 i = 0; i < count; i += 1, nest_ptr += 1){ - Code_Index_Nest *nest = *nest_ptr; - index_shift(&nest->open.min, old_range, new_size); - index_shift(&nest->open.max, old_range, new_size); - if (nest->is_closed){ - index_shift(&nest->close.min, old_range, new_size); - index_shift(&nest->close.max, old_range, new_size); - } - code_index_shift(&nest->nest_array, old_range, new_size); - } -} - -function void -code_index_shift(Code_Index_File *file, Range_i64 old_range, u64 new_size){ - code_index_shift(&file->nest_array, old_range, new_size); -} - -//////////////////////////////// - -function void -generic_parse_inc(Generic_Parse_State *state){ - if (!token_it_inc_all(&state->it)){ - state->finished = true; - } -} - -function void -generic_parse_skip_soft_tokens(Code_Index_File *index, Generic_Parse_State *state){ - Token *token = token_it_read(&state->it); - for (;token != 0 && !state->finished;){ - if (state->in_preprocessor && !HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){ - break; - } - if (token->kind == TokenBaseKind_Comment){ - state->handle_comment(state->app, state->arena, index, token, state->contents); - } - else if (token->kind == TokenBaseKind_Whitespace){ - Range_i64 range = Ii64(token); - u8 *ptr = state->contents.str + range.one_past_last - 1; - for (i64 i = range.one_past_last - 1; - i >= range.first; - i -= 1, ptr -= 1){ - if (*ptr == '\n'){ - state->prev_line_start = ptr + 1; - break; - } - } - } - else{ - break; - } - generic_parse_inc(state); - token = token_it_read(&state->it); - } -} - -function void -generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 contents, Token_Array *tokens, Generic_Parse_Comment_Function *handle_comment, Generic_Parse_State *state){ - state->app = app; - state->arena = arena; - state->contents = contents; - state->it = token_iterator(0, tokens); - state->handle_comment = handle_comment; - state->prev_line_start = contents.str; -} - -//////////////////////////////// - -#if 0 -// NOTE(allen): grammar syntax -(X) = X -X Y = X and then Y -X? = zero or one X -$X = check for X but don't consume -[X] = zero or more Xs -X | Y = either X or Y -* = anything that does not match previous options in a X | Y | ... chain -* - X = anything that does not match X or previous options in a Y | Z | ... chain - = a token of type X -"X" = literally the string "X" -X{Y} = X with flag Y - -// NOTE(allen): grammar of code index parse -file: [preprocessor | scope | parens | function | type | * - ] -preprocessor: [scope | parens | stmnt]{pp-body} -scope: [preprocessor | scope | parens | * - ] -paren: [preprocessor | scope | parens | * - ] -stmnt-close-pattern: | | | | | -stmnt: [type | * - stmnt-close-pattern] stmnt-close-pattern -type: struct | union | enum | typedef -struct: "struct" $(";" | "{") -union: "union" $(";" | "{") -enum: "enum" $(";" | "{") -typedef: "typedef" [* - ( (";" | "("))] $(";" | "(") -function: >"(" [* - ("(" | ")" | "{" | "}" | ";")] ")" ("{" | ";") - -#endif - -//////////////////////////////// - -function Code_Index_Note* -index_new_note(Code_Index_File *index, Generic_Parse_State *state, Range_i64 range, Code_Index_Note_Kind kind, Code_Index_Nest *parent){ - Code_Index_Note *result = push_array(state->arena, Code_Index_Note, 1); - sll_queue_push(index->note_list.first, index->note_list.last, result); - index->note_list.count += 1; - result->note_kind = kind; - result->pos = range; - result->text = push_string_copy(state->arena, string_substring(state->contents, range)); - result->file = index; - result->parent = parent; - return(result); -} - -function void -cpp_parse_type_structure(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - if (state->finished){ - return; - } - Token *token = token_it_read(&state->it); - if (token != 0 && token->kind == TokenBaseKind_Identifier){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - Token *peek = token_it_read(&state->it); - if (peek != 0 && peek->kind == TokenBaseKind_StatementClose || - peek->kind == TokenBaseKind_ScopeOpen){ - index_new_note(index, state, Ii64(token), CodeIndexNote_Type, parent); - } - } -} - -function void -cpp_parse_type_def(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - for (;;){ - b32 did_advance = false; - Token *token = token_it_read(&state->it); - if (token == 0 || state->finished){ - break; - } - if (token->kind == TokenBaseKind_Identifier){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - did_advance = true; - Token *peek = token_it_read(&state->it); - if (peek != 0 && peek->kind == TokenBaseKind_StatementClose || - peek->kind == TokenBaseKind_ParentheticalOpen){ - index_new_note(index, state, Ii64(token), CodeIndexNote_Type, parent); - break; - } - } - else if (token->kind == TokenBaseKind_StatementClose || - token->kind == TokenBaseKind_ScopeOpen || - token->kind == TokenBaseKind_ScopeClose || - token->kind == TokenBaseKind_ScopeOpen || - token->kind == TokenBaseKind_ScopeClose){ - break; - } - else if (token->kind == TokenBaseKind_Keyword){ - String_Const_u8 lexeme = string_substring(state->contents, Ii64(token)); - if (string_match(lexeme, string_u8_litexpr("struct")) || - string_match(lexeme, string_u8_litexpr("union")) || - string_match(lexeme, string_u8_litexpr("enum"))){ - break; - } - } - if (!did_advance){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - } - } -} - -function void -cpp_parse_function(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ - Token *token = token_it_read(&state->it); - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - if (state->finished){ - return; - } - Token *peek = token_it_read(&state->it); - Token *reset_point = peek; - if (peek != 0 && peek->sub_kind == TokenCppKind_ParenOp){ - b32 at_paren_close = false; - for (; peek != 0;){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - peek = token_it_read(&state->it); - if (peek == 0 || state->finished){ - break; - } - - if (peek->kind == TokenBaseKind_ParentheticalOpen || - peek->kind == TokenBaseKind_ScopeOpen || - peek->kind == TokenBaseKind_ScopeClose || - peek->kind == TokenBaseKind_StatementClose){ - break; - } - if (peek->kind == TokenBaseKind_ParentheticalClose){ - at_paren_close = true; - break; - } - } - - if (at_paren_close){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - peek = token_it_read(&state->it); - if (peek != 0 && - peek->kind == TokenBaseKind_ScopeOpen || - peek->kind == TokenBaseKind_StatementClose){ - index_new_note(index, state, Ii64(token), CodeIndexNote_Function, parent); - } - } - } - state->it = token_iterator(state->it.user_id, state->it.tokens, state->it.count, reset_point); -} - -function Code_Index_Nest* -generic_parse_statement(Code_Index_File *index, Generic_Parse_State *state); - -function Code_Index_Nest* -generic_parse_preprocessor(Code_Index_File *index, Generic_Parse_State *state); - -function Code_Index_Nest* -generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state); - -function Code_Index_Nest* -generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state); - -function Code_Index_Nest* -generic_parse_statement(Code_Index_File *index, Generic_Parse_State *state){ - Token *token = token_it_read(&state->it); - Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); - result->kind = CodeIndexNest_Statement; - result->open = Ii64(token->pos); - result->close = Ii64(max_i64); - result->file = index; - - state->in_statement = true; - - for (;;){ - generic_parse_skip_soft_tokens(index, state); - token = token_it_read(&state->it); - if (token == 0 || state->finished){ - break; - } - - if (state->in_preprocessor){ - if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || - token->kind == TokenBaseKind_Preprocessor){ - result->is_closed = true; - result->close = Ii64(token->pos); - break; - } - } - else{ - if (token->kind == TokenBaseKind_Preprocessor){ - result->is_closed = true; - result->close = Ii64(token->pos); - break; - } - } - - if (token->kind == TokenBaseKind_ScopeOpen || - token->kind == TokenBaseKind_ScopeClose || - token->kind == TokenBaseKind_ParentheticalOpen){ - result->is_closed = true; - result->close = Ii64(token->pos); - break; - } - - if (token->kind == TokenBaseKind_StatementClose){ - result->is_closed = true; - result->close = Ii64(token); - generic_parse_inc(state); - break; - } - - generic_parse_inc(state); - } - - state->in_statement = false; - - return(result); -} - -function Code_Index_Nest* -generic_parse_preprocessor(Code_Index_File *index, Generic_Parse_State *state){ - Token *token = token_it_read(&state->it); - Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); - result->kind = CodeIndexNest_Preprocessor; - result->open = Ii64(token->pos); - result->close = Ii64(max_i64); - result->file = index; - - state->in_preprocessor = true; - - b32 potential_macro = false; - if (state->do_cpp_parse){ - if (token->sub_kind == TokenCppKind_PPDefine){ - potential_macro = true; - } - } - - generic_parse_inc(state); - for (;;){ - generic_parse_skip_soft_tokens(index, state); - token = token_it_read(&state->it); - if (token == 0 || state->finished){ - break; - } - - if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || - token->kind == TokenBaseKind_Preprocessor){ - result->is_closed = true; - result->close = Ii64(token->pos); - break; - } - - if (state->do_cpp_parse && potential_macro){ - if (token->sub_kind == TokenCppKind_Identifier){ - index_new_note(index, state, Ii64(token), CodeIndexNote_Macro, result); - } - potential_macro = false; - } - - if (token->kind == TokenBaseKind_ScopeOpen){ - Code_Index_Nest *nest = generic_parse_scope(index, state); - nest->parent = result; - code_index_push_nest(&result->nest_list, nest); - continue; - } - - if (token->kind == TokenBaseKind_ParentheticalOpen){ - Code_Index_Nest *nest = generic_parse_paren(index, state); - nest->parent = result; - code_index_push_nest(&result->nest_list, nest); - continue; - } - - generic_parse_inc(state); - } - - result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); - - state->in_preprocessor = false; - - return(result); -} - -function Code_Index_Nest* -generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state){ - Token *token = token_it_read(&state->it); - Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); - result->kind = CodeIndexNest_Scope; - result->open = Ii64(token); - result->close = Ii64(max_i64); - result->file = index; - - state->scope_counter += 1; - - generic_parse_inc(state); - for (;;){ - generic_parse_skip_soft_tokens(index, state); - token = token_it_read(&state->it); - if (token == 0 || state->finished){ - break; - } - - if (state->in_preprocessor){ - if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || - token->kind == TokenBaseKind_Preprocessor){ - break; - } - } - else{ - if (token->kind == TokenBaseKind_Preprocessor){ - Code_Index_Nest *nest = generic_parse_preprocessor(index, state); - code_index_push_nest(&index->nest_list, nest); - continue; - } - } - - if (token->kind == TokenBaseKind_ScopeClose){ - result->is_closed = true; - result->close = Ii64(token); - generic_parse_inc(state); - break; - } - - if (token->kind == TokenBaseKind_ScopeOpen){ - Code_Index_Nest *nest = generic_parse_scope(index, state); - nest->parent = result; - code_index_push_nest(&result->nest_list, nest); - continue; - } - - if (token->kind == TokenBaseKind_ParentheticalOpen){ - Code_Index_Nest *nest = generic_parse_paren(index, state); - nest->parent = result; - code_index_push_nest(&result->nest_list, nest); - continue; - } - - if (token->kind == TokenBaseKind_ParentheticalClose){ - generic_parse_inc(state); - continue; - } - - { - Code_Index_Nest *nest = generic_parse_statement(index, state); - nest->parent = result; - code_index_push_nest(&result->nest_list, nest); - } - } - - result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); - - state->scope_counter -= 1; - - return(result); -} - -function Code_Index_Nest* -generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state){ - Token *token = token_it_read(&state->it); - Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); - result->kind = CodeIndexNest_Paren; - result->open = Ii64(token); - result->close = Ii64(max_i64); - result->file = index; - - i64 manifested_characters_on_line = 0; - { - u8 *ptr = state->prev_line_start; - u8 *end_ptr = state->contents.str + token->pos; - // NOTE(allen): Initial whitespace - for (;ptr < end_ptr; ptr += 1){ - if (!character_is_whitespace(*ptr)){ - break; - } - } - // NOTE(allen): Manifested characters - manifested_characters_on_line = (i64)(end_ptr - ptr) + token->size; - } - - state->paren_counter += 1; - - generic_parse_inc(state); - for (;;){ - generic_parse_skip_soft_tokens(index, state); - token = token_it_read(&state->it); - if (token == 0 || state->finished){ - break; - } - - if (state->in_preprocessor){ - if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || - token->kind == TokenBaseKind_Preprocessor){ - break; - } - } - else{ - if (token->kind == TokenBaseKind_Preprocessor){ - Code_Index_Nest *nest = generic_parse_preprocessor(index, state); - code_index_push_nest(&index->nest_list, nest); - continue; - } - } - - if (token->kind == TokenBaseKind_ParentheticalClose){ - result->is_closed = true; - result->close = Ii64(token); - generic_parse_inc(state); - break; - } - - if (token->kind == TokenBaseKind_ScopeClose){ - break; - } - - if (token->kind == TokenBaseKind_ScopeOpen){ - Code_Index_Nest *nest = generic_parse_scope(index, state); - nest->parent = result; - code_index_push_nest(&result->nest_list, nest); - continue; - } - - if (token->kind == TokenBaseKind_ParentheticalOpen){ - Code_Index_Nest *nest = generic_parse_paren(index, state); - nest->parent = result; - code_index_push_nest(&result->nest_list, nest); - continue; - } - - generic_parse_inc(state); - } - - result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); - - state->paren_counter -= 1; - - return(result); -} - -function b32 -generic_parse_full_input_breaks(Code_Index_File *index, Generic_Parse_State *state, i32 limit){ - b32 result = false; - - i64 first_index = token_it_index(&state->it); - i64 one_past_last_index = first_index + limit; - for (;;){ - generic_parse_skip_soft_tokens(index, state); - Token *token = token_it_read(&state->it); - - if (token == 0 || state->finished){ - result = true; - break; - } - - if (token->kind == TokenBaseKind_Preprocessor){ - Code_Index_Nest *nest = generic_parse_preprocessor(index, state); - code_index_push_nest(&index->nest_list, nest); - } - else if (token->kind == TokenBaseKind_ScopeOpen){ - Code_Index_Nest *nest = generic_parse_scope(index, state); - code_index_push_nest(&index->nest_list, nest); - } - else if (token->kind == TokenBaseKind_ParentheticalOpen){ - Code_Index_Nest *nest = generic_parse_paren(index, state); - code_index_push_nest(&index->nest_list, nest); - } - else if (state->do_cpp_parse){ - if (token->sub_kind == TokenCppKind_Struct || - token->sub_kind == TokenCppKind_Union || - token->sub_kind == TokenCppKind_Enum){ - cpp_parse_type_structure(index, state, 0); - } - else if (token->sub_kind == TokenCppKind_Typedef){ - cpp_parse_type_def(index, state, 0); - } - else if (token->sub_kind == TokenCppKind_Identifier){ - cpp_parse_function(index, state, 0); - } - else{ - generic_parse_inc(state); - } - } - else{ - generic_parse_inc(state); - } - - i64 index = token_it_index(&state->it); - if (index >= one_past_last_index){ - token = token_it_read(&state->it); - if (token == 0){ - result = true; - } - break; - } - } - - if (result){ - index->nest_array = code_index_nest_ptr_array_from_list(state->arena, &index->nest_list); - index->note_array = code_index_note_ptr_array_from_list(state->arena, &index->note_list); - } - - return(result); -} - -//////////////////////////////// - -function void -default_comment_index(Application_Links *app, Arena *arena, Code_Index_File *index, Token *token, String_Const_u8 contents){ - -} - -function void -generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 contents, Token_Array *tokens, Generic_Parse_State *state){ - generic_parse_init(app, arena, contents, tokens, default_comment_index, state); -} - -//////////////////////////////// - -function Token_Pair -layout_token_pair(Token_Array *tokens, i64 pos){ - Token_Pair result = {}; - Token_Iterator_Array it = token_iterator_pos(0, tokens, pos); - Token *b = token_it_read(&it); - if (b != 0){ - if (b->kind == TokenBaseKind_Whitespace){ - token_it_inc_non_whitespace(&it); - b = token_it_read(&it); - } - } - token_it_dec_non_whitespace(&it); - Token *a = token_it_read(&it); - if (a != 0){ - result.a = *a; - } - if (b != 0){ - result.b = *b; - } - return(result); -} - -function f32 -layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_Nest *nest, i64 pos, f32 space_advance, b32 *unresolved_dependence){ - f32 result = 0.f; - if (nest != 0){ - switch (nest->kind){ - case CodeIndexNest_Scope: - case CodeIndexNest_Preprocessor: - { - result = layout_index_x_shift(app, reflex, nest->parent, pos, space_advance, unresolved_dependence); - if (nest->open.min < pos && nest->open.max <= pos && - (!nest->is_closed || pos < nest->close.min)){ - result += 4.f*space_advance; - } - }break; - - case CodeIndexNest_Statement: - { - result = layout_index_x_shift(app, reflex, nest->parent, pos, space_advance, unresolved_dependence); - if (nest->open.min < pos && nest->open.max <= pos && - (!nest->is_closed || pos < nest->close.min)){ - result += 4.f*space_advance; - } - }break; - - case CodeIndexNest_Paren: - { - Rect_f32 box = layout_reflex_get_rect(app, reflex, nest->open.max - 1, unresolved_dependence); - result = box.x1; - }break; - } - } - return(result); -} - -function f32 -layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_Nest *nest, i64 pos, f32 space_advance){ - b32 ignore; - return(layout_index_x_shift(app, reflex, nest, pos, space_advance, &ignore)); -} - -function f32 -layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_File *file, i64 pos, f32 space_advance, b32 *unresolved_dependence){ - f32 indent = 0; - Code_Index_Nest *nest = code_index_get_nest(file, pos); - if (nest != 0){ - indent = layout_index_x_shift(app, reflex, nest, pos, space_advance, unresolved_dependence); - } - return(indent); -} - -function f32 -layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_File *file, i64 pos, f32 space_advance){ - b32 ignore; - return(layout_index_x_shift(app, reflex, file, pos, space_advance, &ignore)); -} - -function void -layout_index__emit_chunk(LefRig_TopBot_Layout_Vars *pos_vars, Face_ID face, Arena *arena, u8 *text_str, i64 range_first, u8 *ptr, u8 *end, Layout_Item_List *list){ - for (;ptr < end;){ - Character_Consume_Result consume = utf8_consume(ptr, (u64)(end - ptr)); - if (consume.codepoint != '\r'){ - i64 index = layout_index_from_ptr(ptr, text_str, range_first); - if (consume.codepoint != max_u32){ - lr_tb_write(pos_vars, face, arena, list, index, consume.codepoint); - } - else{ - lr_tb_write_byte(pos_vars, face, arena, list, index, *ptr); - } - } - ptr += consume.inc; - } -} - -function i32 -layout_token_score_wrap_token(Token_Pair *pair, Token_Cpp_Kind kind){ - i32 result = 0; - if (pair->a.sub_kind != kind && pair->b.sub_kind == kind){ - result -= 1; - } - else if (pair->a.sub_kind == kind && pair->b.sub_kind != kind){ - result += 1; - } - return(result); -} - -function Layout_Item_List -layout_index__inner(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width, Code_Index_File *file, Layout_Wrap_Kind kind){ - Scratch_Block scratch(app); - - Managed_Scope scope = buffer_get_managed_scope(app, buffer); - Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, Token_Array); - - Layout_Item_List list = get_empty_item_list(range); - String_Const_u8 text = push_buffer_range(app, scratch, buffer, range); - - Face_Advance_Map advance_map = get_face_advance_map(app, face); - Face_Metrics metrics = get_face_metrics(app, face); - LefRig_TopBot_Layout_Vars pos_vars = get_lr_tb_layout_vars(&advance_map, &metrics, width); - - f32 wrap_align_x = width - metrics.normal_advance; - - Layout_Reflex reflex = get_layout_reflex(&list, buffer, width, face); - - if (text.size == 0){ - lr_tb_write_blank(&pos_vars, face, arena, &list, range.start); - } - else{ - b32 first_of_the_line = true; - Newline_Layout_Vars newline_vars = get_newline_layout_vars(); - - u8 *ptr = text.str; - u8 *end_ptr = ptr + text.size; - u8 *word_ptr = ptr; - - u8 *pending_wrap_ptr = ptr; - f32 pending_wrap_x = 0.f; - i32 pending_wrap_paren_nest_count = 0; - i32 pending_wrap_token_score = 0; - f32 pending_wrap_accumulated_w = 0.f; - - start: - if (ptr == end_ptr){ - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - f32 shift = layout_index_x_shift(app, &reflex, file, index, metrics.space_advance); - lr_tb_advance_x_without_item(&pos_vars, shift); - goto finish; - } - - if (!character_is_whitespace(*ptr)){ - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - f32 shift = layout_index_x_shift(app, &reflex, file, index, metrics.space_advance); - lr_tb_advance_x_without_item(&pos_vars, shift); - goto consuming_non_whitespace; - } - - { - for (;ptr < end_ptr; ptr += 1){ - if (!character_is_whitespace(*ptr)){ - pending_wrap_ptr = ptr; - word_ptr = ptr; - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - f32 shift = layout_index_x_shift(app, &reflex, file, index, metrics.space_advance); - lr_tb_advance_x_without_item(&pos_vars, shift); - goto consuming_non_whitespace; - } - if (*ptr == '\n'){ - pending_wrap_ptr = ptr; - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - f32 shift = layout_index_x_shift(app, &reflex, file, index, metrics.space_advance); - lr_tb_advance_x_without_item(&pos_vars, shift); - goto consuming_normal_whitespace; - } - } - - if (ptr == end_ptr){ - pending_wrap_ptr = ptr; - i64 index = layout_index_from_ptr(ptr - 1, text.str, range.first); - f32 shift = layout_index_x_shift(app, &reflex, file, index, metrics.space_advance); - lr_tb_advance_x_without_item(&pos_vars, shift); - goto finish; - } - } - - consuming_non_whitespace: - { - for (;ptr <= end_ptr; ptr += 1){ - if (ptr == end_ptr || character_is_whitespace(*ptr)){ - break; - } - } - - // NOTE(allen): measure this word - newline_layout_consume_default(&newline_vars); - String_Const_u8 word = SCu8(word_ptr, ptr); - u8 *word_end = ptr; - { - f32 word_advance = 0.f; - ptr = word.str; - for (;ptr < word_end;){ - Character_Consume_Result consume = utf8_consume(ptr, (u64)(word_end - ptr)); - if (consume.codepoint != max_u32){ - word_advance += lr_tb_advance(&pos_vars, face, consume.codepoint); - } - else{ - word_advance += lr_tb_advance_byte(&pos_vars); - } - ptr += consume.inc; - } - pending_wrap_accumulated_w += word_advance; - } - - if (!first_of_the_line && (kind == Layout_Wrapped) && lr_tb_crosses_width(&pos_vars, pending_wrap_accumulated_w)){ - i64 index = layout_index_from_ptr(pending_wrap_ptr, text.str, range.first); - lr_tb_align_rightward(&pos_vars, wrap_align_x); - lr_tb_write_ghost(&pos_vars, face, arena, &list, index, '\\'); - - lr_tb_next_line(&pos_vars); -#if 0 - f32 shift = layout_index_x_shift(app, &reflex, file, index, metrics.space_advance); - lr_tb_advance_x_without_item(&pos_vars, shift); -#endif - - ptr = pending_wrap_ptr; - pending_wrap_accumulated_w = 0.f; - first_of_the_line = true; - goto start; - } - } - - consuming_normal_whitespace: - for (; ptr < end_ptr; ptr += 1){ - if (!character_is_whitespace(*ptr)){ - u8 *new_wrap_ptr = ptr; - - i64 index = layout_index_from_ptr(new_wrap_ptr, text.str, range.first); - Code_Index_Nest *new_wrap_nest = code_index_get_nest(file, index); - b32 invalid_wrap_x = false; - f32 new_wrap_x = layout_index_x_shift(app, &reflex, new_wrap_nest, index, metrics.space_advance, &invalid_wrap_x); - if (invalid_wrap_x){ - new_wrap_x = max_f32; - } - - i32 new_wrap_paren_nest_count = 0; - for (Code_Index_Nest *nest = new_wrap_nest; - nest != 0; - nest = nest->parent){ - if (nest->kind == CodeIndexNest_Paren){ - new_wrap_paren_nest_count += 1; - } - } - - Token_Pair new_wrap_token_pair = layout_token_pair(tokens_ptr, index); - - // TODO(allen): pull out the token scoring part and make it replacable for other - // language's token based wrap scoring needs. - i32 token_score = 0; - if (new_wrap_token_pair.a.kind == TokenBaseKind_Keyword){ - if (new_wrap_token_pair.b.kind == TokenBaseKind_ParentheticalOpen || - new_wrap_token_pair.b.kind == TokenBaseKind_Keyword){ - token_score -= 2; - } - } - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Eq); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_PlusEq); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_MinusEq); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_StarEq); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_DivEq); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_ModEq); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_LeftLeftEq); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_RightRightEq); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Comma); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_AndAnd); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_OrOr); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Ternary); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Colon); - token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Semicolon); - - i32 new_wrap_token_score = token_score; - - b32 new_wrap_ptr_is_better = false; - if (first_of_the_line){ - new_wrap_ptr_is_better = true; - } - else{ - if (new_wrap_token_score > pending_wrap_token_score){ - new_wrap_ptr_is_better = true; - } - else if (new_wrap_token_score == pending_wrap_token_score){ - f32 new_score = new_wrap_paren_nest_count*10.f + new_wrap_x; - f32 old_score = pending_wrap_paren_nest_count*10.f + pending_wrap_x + metrics.normal_advance*4.f + pending_wrap_accumulated_w*0.5f; - - if (new_score < old_score){ - new_wrap_ptr_is_better = true; - } - } - } - - if (new_wrap_ptr_is_better){ - layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, new_wrap_ptr, &list); - first_of_the_line = false; - - pending_wrap_ptr = new_wrap_ptr; - pending_wrap_paren_nest_count = new_wrap_paren_nest_count; - pending_wrap_x = layout_index_x_shift(app, &reflex, new_wrap_nest, index, metrics.space_advance); - pending_wrap_paren_nest_count = new_wrap_paren_nest_count; - pending_wrap_token_score = new_wrap_token_score; - pending_wrap_accumulated_w = 0.f; - } - - word_ptr = ptr; - goto consuming_non_whitespace; - } - - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - switch (*ptr){ - default: - { - newline_layout_consume_default(&newline_vars); - pending_wrap_accumulated_w += lr_tb_advance(&pos_vars, face, *ptr); - }break; - - case '\r': - { - newline_layout_consume_CR(&newline_vars, index); - }break; - - case '\n': - { - layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, ptr, &list); - pending_wrap_ptr = ptr + 1; - pending_wrap_accumulated_w = 0.f; - - u64 newline_index = newline_layout_consume_LF(&newline_vars, index); - lr_tb_write_blank(&pos_vars, face, arena, &list, newline_index); - lr_tb_next_line(&pos_vars); - first_of_the_line = true; - ptr += 1; - goto start; - }break; - } - } - - finish: - if (newline_layout_consume_finish(&newline_vars)){ - layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, ptr, &list); - i64 index = layout_index_from_ptr(ptr, text.str, range.first); - lr_tb_write_blank(&pos_vars, face, arena, &list, index); - } - } - - layout_item_list_finish(&list, -pos_vars.line_to_text_shift); - - return(list); -} - -function Layout_Item_List -layout_virt_indent_index(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width, Layout_Wrap_Kind kind){ - Layout_Item_List result = {}; - - if (global_config.enable_virtual_whitespace){ - code_index_lock(); - Code_Index_File *file = code_index_get_file(buffer); - if (file != 0){ - result = layout_index__inner(app, arena, buffer, range, face, width, file, kind); - } - code_index_unlock(); - if (file == 0){ - result = layout_virt_indent_literal(app, arena, buffer, range, face, width, kind); - } - } - else{ - result = layout_basic(app, arena, buffer, range, face, width, kind); - } - - return(result); -} - -function Layout_Item_List -layout_virt_indent_index_unwrapped(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ - return(layout_virt_indent_index(app, arena, buffer, range, face, width, Layout_Unwrapped)); -} - -function Layout_Item_List -layout_virt_indent_index_wrapped(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ - return(layout_virt_indent_index(app, arena, buffer, range, face, width, Layout_Wrapped)); -} - -function Layout_Item_List -layout_virt_indent_index_generic(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ - Managed_Scope scope = buffer_get_managed_scope(app, buffer); - b32 *wrap_lines_ptr = scope_attachment(app, scope, buffer_wrap_lines, b32); - b32 wrap_lines = (wrap_lines_ptr != 0 && *wrap_lines_ptr); - return(layout_virt_indent_index(app, arena, buffer, range, face, width, wrap_lines?Layout_Wrapped:Layout_Unwrapped)); -} - -CUSTOM_COMMAND_SIG(toggle_virtual_whitespace) -CUSTOM_DOC("Toggles the current buffer's virtual whitespace status.") -{ - global_config.enable_virtual_whitespace = !global_config.enable_virtual_whitespace; - - for (Buffer_ID buffer = get_buffer_next(app, 0, Access_Always); - buffer != 0; - buffer = get_buffer_next(app, buffer, Access_Always)){ - buffer_clear_layout_cache(app, buffer); - } -} - -// BOTTOM - +/* +4coder_code_index.cpp - Generic code indexing system for layout, definition jumps, etc. +*/ + +// TOP + +global Code_Index global_code_index = {}; + +function void +code_index_init(void){ + global_code_index.mutex = system_mutex_make(); + global_code_index.node_arena = make_arena_system(KB(4)); + global_code_index.buffer_to_index_file = make_table_u64_u64(global_code_index.node_arena.base_allocator, 500); +} + +function Code_Index_File_Storage* +code_index__alloc_storage(void){ + Code_Index_File_Storage *result = global_code_index.free_storage; + if (result == 0){ + result = push_array_zero(&global_code_index.node_arena, Code_Index_File_Storage, 1); + } + else{ + sll_stack_pop(global_code_index.free_storage); + } + zdll_push_back(global_code_index.storage_first, global_code_index.storage_last, result); + global_code_index.storage_count += 1; + return(result); +} + +function void +code_index__free_storage(Code_Index_File_Storage *storage){ + zdll_remove(global_code_index.storage_first, global_code_index.storage_last, storage); + global_code_index.storage_count -= 1; + sll_stack_push(global_code_index.free_storage, storage); +} + +function void +code_index_push_nest(Code_Index_Nest_List *list, Code_Index_Nest *nest){ + sll_queue_push(list->first, list->last, nest); + list->count += 1; +} + +function Code_Index_Nest_Ptr_Array +code_index_nest_ptr_array_from_list(Arena *arena, Code_Index_Nest_List *list){ + Code_Index_Nest_Ptr_Array array = {}; + array.ptrs = push_array_zero(arena, Code_Index_Nest*, list->count); + array.count = list->count; + i32 counter = 0; + for (Code_Index_Nest *node = list->first; + node != 0; + node = node->next){ + array.ptrs[counter] = node; + counter += 1; + } + return(array); +} + +function Code_Index_Note_Ptr_Array +code_index_note_ptr_array_from_list(Arena *arena, Code_Index_Note_List *list){ + Code_Index_Note_Ptr_Array array = {}; + array.ptrs = push_array_zero(arena, Code_Index_Note*, list->count); + array.count = list->count; + i32 counter = 0; + for (Code_Index_Note *node = list->first; + node != 0; + node = node->next){ + array.ptrs[counter] = node; + counter += 1; + } + return(array); +} + +function void +code_index_lock(void){ + system_mutex_acquire(global_code_index.mutex); +} + +function void +code_index_unlock(void){ + system_mutex_release(global_code_index.mutex); +} + +function void +code_index_set_file(Buffer_ID buffer, Arena arena, Code_Index_File *index){ + Code_Index_File_Storage *storage = 0; + Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); + if (lookup.found_match){ + u64 val = 0; + table_read(&global_code_index.buffer_to_index_file, lookup, &val); + storage = (Code_Index_File_Storage*)IntAsPtr(val); + linalloc_clear(&storage->arena); + } + else{ + storage = code_index__alloc_storage(); + table_insert(&global_code_index.buffer_to_index_file, buffer, (u64)PtrAsInt(storage)); + } + storage->arena = arena; + storage->file = index; +} + +function void +code_index_erase_file(Buffer_ID buffer){ + Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); + if (lookup.found_match){ + u64 val = 0; + table_read(&global_code_index.buffer_to_index_file, lookup, &val); + Code_Index_File_Storage *storage = (Code_Index_File_Storage*)IntAsPtr(val); + linalloc_clear(&storage->arena); + table_erase(&global_code_index.buffer_to_index_file, lookup); + code_index__free_storage(storage); + } +} + +function Code_Index_File* +code_index_get_file(Buffer_ID buffer){ + Code_Index_File *result = 0; + Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); + if (lookup.found_match){ + u64 val = 0; + table_read(&global_code_index.buffer_to_index_file, lookup, &val); + Code_Index_File_Storage *storage = (Code_Index_File_Storage*)IntAsPtr(val); + result = storage->file; + } + return(result); +} + +function Code_Index_Nest* +code_index_get_nest(Code_Index_Nest_Ptr_Array *array, i64 pos){ + Code_Index_Nest *result = 0; + i32 count = array->count; + Code_Index_Nest **nest_ptrs = array->ptrs; + for (i32 i = 0; i < count; i += 1){ + Code_Index_Nest *nest = nest_ptrs[i]; + if (nest->open.max <= pos && pos <= nest->close.min){ + Code_Index_Nest *sub_nest = + code_index_get_nest(&nest->nest_array, pos); + if (sub_nest != 0){ + result = sub_nest; + } + else{ + result = nest; + } + break; + } + } + return(result); +} + +function Code_Index_Nest* +code_index_get_nest(Code_Index_Nest *nest, i64 pos){ + return(code_index_get_nest(&nest->nest_array, pos)); +} + +function Code_Index_Nest* +code_index_get_nest(Code_Index_File *file, i64 pos){ + return(code_index_get_nest(&file->nest_array, pos)); +} + +function void +index_shift(i64 *ptr, Range_i64 old_range, u64 new_size){ + i64 i = *ptr; + if (old_range.min <= i && i < old_range.max){ + *ptr = old_range.first; + } + else if (old_range.max <= i){ + *ptr = i + new_size - (old_range.max - old_range.min); + } +} + +function void +code_index_shift(Code_Index_Nest_Ptr_Array *array, + Range_i64 old_range, u64 new_size){ + i32 count = array->count; + Code_Index_Nest **nest_ptr = array->ptrs; + for (i32 i = 0; i < count; i += 1, nest_ptr += 1){ + Code_Index_Nest *nest = *nest_ptr; + index_shift(&nest->open.min, old_range, new_size); + index_shift(&nest->open.max, old_range, new_size); + if (nest->is_closed){ + index_shift(&nest->close.min, old_range, new_size); + index_shift(&nest->close.max, old_range, new_size); + } + code_index_shift(&nest->nest_array, old_range, new_size); + } +} + +function void +code_index_shift(Code_Index_File *file, Range_i64 old_range, u64 new_size){ + code_index_shift(&file->nest_array, old_range, new_size); +} + +//////////////////////////////// + +function void +generic_parse_inc(Generic_Parse_State *state){ + if (!token_it_inc_all(&state->it)){ + state->finished = true; + } +} + +function void +generic_parse_skip_soft_tokens(Code_Index_File *index, Generic_Parse_State *state){ + Token *token = token_it_read(&state->it); + for (;token != 0 && !state->finished;){ + if (state->in_preprocessor && !HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){ + break; + } + if (token->kind == TokenBaseKind_Comment){ + state->handle_comment(state->app, state->arena, index, token, state->contents); + } + else if (token->kind == TokenBaseKind_Whitespace){ + Range_i64 range = Ii64(token); + u8 *ptr = state->contents.str + range.one_past_last - 1; + for (i64 i = range.one_past_last - 1; + i >= range.first; + i -= 1, ptr -= 1){ + if (*ptr == '\n'){ + state->prev_line_start = ptr + 1; + break; + } + } + } + else{ + break; + } + generic_parse_inc(state); + token = token_it_read(&state->it); + } +} + +function void +generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 contents, Token_Array *tokens, Generic_Parse_Comment_Function *handle_comment, Generic_Parse_State *state){ + state->app = app; + state->arena = arena; + state->contents = contents; + state->it = token_iterator(0, tokens); + state->handle_comment = handle_comment; + state->prev_line_start = contents.str; +} + +//////////////////////////////// + +#if 0 +// NOTE(allen): grammar syntax +(X) = X +X Y = X and then Y +X? = zero or one X +$X = check for X but dont consume // NOTE(yuval): Removed apostrophe as it was causing a warning when compiling with gcc +[X] = zero or more Xs +X | Y = either X or Y +* = anything that does not match previous options in a X | Y | ... chain +* - X = anything that does not match X or previous options in a Y | Z | ... chain + = a token of type X +"X" = literally the string "X" +X{Y} = X with flag Y + +// NOTE(allen): grammar of code index parse +file: [preprocessor | scope | parens | function | type | * - ] +preprocessor: [scope | parens | stmnt]{pp-body} +scope: [preprocessor | scope | parens | * - ] +paren: [preprocessor | scope | parens | * - ] +stmnt-close-pattern: | | | | | +stmnt: [type | * - stmnt-close-pattern] stmnt-close-pattern +type: struct | union | enum | typedef +struct: "struct" $(";" | "{") +union: "union" $(";" | "{") +enum: "enum" $(";" | "{") +typedef: "typedef" [* - ( (";" | "("))] $(";" | "(") +function: >"(" [* - ("(" | ")" | "{" | "}" | ";")] ")" ("{" | ";") + +#endif + +//////////////////////////////// + +function Code_Index_Note* +index_new_note(Code_Index_File *index, Generic_Parse_State *state, Range_i64 range, Code_Index_Note_Kind kind, Code_Index_Nest *parent){ + Code_Index_Note *result = push_array(state->arena, Code_Index_Note, 1); + sll_queue_push(index->note_list.first, index->note_list.last, result); + index->note_list.count += 1; + result->note_kind = kind; + result->pos = range; + result->text = push_string_copy(state->arena, string_substring(state->contents, range)); + result->file = index; + result->parent = parent; + return(result); +} + +function void +cpp_parse_type_structure(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + if (state->finished){ + return; + } + Token *token = token_it_read(&state->it); + if (token != 0 && token->kind == TokenBaseKind_Identifier){ + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + Token *peek = token_it_read(&state->it); + if (peek != 0 && peek->kind == TokenBaseKind_StatementClose || + peek->kind == TokenBaseKind_ScopeOpen){ + index_new_note(index, state, Ii64(token), CodeIndexNote_Type, parent); + } + } +} + +function void +cpp_parse_type_def(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + for (;;){ + b32 did_advance = false; + Token *token = token_it_read(&state->it); + if (token == 0 || state->finished){ + break; + } + if (token->kind == TokenBaseKind_Identifier){ + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + did_advance = true; + Token *peek = token_it_read(&state->it); + if (peek != 0 && peek->kind == TokenBaseKind_StatementClose || + peek->kind == TokenBaseKind_ParentheticalOpen){ + index_new_note(index, state, Ii64(token), CodeIndexNote_Type, parent); + break; + } + } + else if (token->kind == TokenBaseKind_StatementClose || + token->kind == TokenBaseKind_ScopeOpen || + token->kind == TokenBaseKind_ScopeClose || + token->kind == TokenBaseKind_ScopeOpen || + token->kind == TokenBaseKind_ScopeClose){ + break; + } + else if (token->kind == TokenBaseKind_Keyword){ + String_Const_u8 lexeme = string_substring(state->contents, Ii64(token)); + if (string_match(lexeme, string_u8_litexpr("struct")) || + string_match(lexeme, string_u8_litexpr("union")) || + string_match(lexeme, string_u8_litexpr("enum"))){ + break; + } + } + if (!did_advance){ + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + } + } +} + +function void +cpp_parse_function(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ + Token *token = token_it_read(&state->it); + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + if (state->finished){ + return; + } + Token *peek = token_it_read(&state->it); + Token *reset_point = peek; + if (peek != 0 && peek->sub_kind == TokenCppKind_ParenOp){ + b32 at_paren_close = false; + for (; peek != 0;){ + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + peek = token_it_read(&state->it); + if (peek == 0 || state->finished){ + break; + } + + if (peek->kind == TokenBaseKind_ParentheticalOpen || + peek->kind == TokenBaseKind_ScopeOpen || + peek->kind == TokenBaseKind_ScopeClose || + peek->kind == TokenBaseKind_StatementClose){ + break; + } + if (peek->kind == TokenBaseKind_ParentheticalClose){ + at_paren_close = true; + break; + } + } + + if (at_paren_close){ + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + peek = token_it_read(&state->it); + if (peek != 0 && + peek->kind == TokenBaseKind_ScopeOpen || + peek->kind == TokenBaseKind_StatementClose){ + index_new_note(index, state, Ii64(token), CodeIndexNote_Function, parent); + } + } + } + state->it = token_iterator(state->it.user_id, state->it.tokens, state->it.count, reset_point); +} + +function Code_Index_Nest* +generic_parse_statement(Code_Index_File *index, Generic_Parse_State *state); + +function Code_Index_Nest* +generic_parse_preprocessor(Code_Index_File *index, Generic_Parse_State *state); + +function Code_Index_Nest* +generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state); + +function Code_Index_Nest* +generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state); + +function Code_Index_Nest* +generic_parse_statement(Code_Index_File *index, Generic_Parse_State *state){ + Token *token = token_it_read(&state->it); + Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); + result->kind = CodeIndexNest_Statement; + result->open = Ii64(token->pos); + result->close = Ii64(max_i64); + result->file = index; + + state->in_statement = true; + + for (;;){ + generic_parse_skip_soft_tokens(index, state); + token = token_it_read(&state->it); + if (token == 0 || state->finished){ + break; + } + + if (state->in_preprocessor){ + if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || + token->kind == TokenBaseKind_Preprocessor){ + result->is_closed = true; + result->close = Ii64(token->pos); + break; + } + } + else{ + if (token->kind == TokenBaseKind_Preprocessor){ + result->is_closed = true; + result->close = Ii64(token->pos); + break; + } + } + + if (token->kind == TokenBaseKind_ScopeOpen || + token->kind == TokenBaseKind_ScopeClose || + token->kind == TokenBaseKind_ParentheticalOpen){ + result->is_closed = true; + result->close = Ii64(token->pos); + break; + } + + if (token->kind == TokenBaseKind_StatementClose){ + result->is_closed = true; + result->close = Ii64(token); + generic_parse_inc(state); + break; + } + + generic_parse_inc(state); + } + + state->in_statement = false; + + return(result); +} + +function Code_Index_Nest* +generic_parse_preprocessor(Code_Index_File *index, Generic_Parse_State *state){ + Token *token = token_it_read(&state->it); + Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); + result->kind = CodeIndexNest_Preprocessor; + result->open = Ii64(token->pos); + result->close = Ii64(max_i64); + result->file = index; + + state->in_preprocessor = true; + + b32 potential_macro = false; + if (state->do_cpp_parse){ + if (token->sub_kind == TokenCppKind_PPDefine){ + potential_macro = true; + } + } + + generic_parse_inc(state); + for (;;){ + generic_parse_skip_soft_tokens(index, state); + token = token_it_read(&state->it); + if (token == 0 || state->finished){ + break; + } + + if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || + token->kind == TokenBaseKind_Preprocessor){ + result->is_closed = true; + result->close = Ii64(token->pos); + break; + } + + if (state->do_cpp_parse && potential_macro){ + if (token->sub_kind == TokenCppKind_Identifier){ + index_new_note(index, state, Ii64(token), CodeIndexNote_Macro, result); + } + potential_macro = false; + } + + if (token->kind == TokenBaseKind_ScopeOpen){ + Code_Index_Nest *nest = generic_parse_scope(index, state); + nest->parent = result; + code_index_push_nest(&result->nest_list, nest); + continue; + } + + if (token->kind == TokenBaseKind_ParentheticalOpen){ + Code_Index_Nest *nest = generic_parse_paren(index, state); + nest->parent = result; + code_index_push_nest(&result->nest_list, nest); + continue; + } + + generic_parse_inc(state); + } + + result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); + + state->in_preprocessor = false; + + return(result); +} + +function Code_Index_Nest* +generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state){ + Token *token = token_it_read(&state->it); + Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); + result->kind = CodeIndexNest_Scope; + result->open = Ii64(token); + result->close = Ii64(max_i64); + result->file = index; + + state->scope_counter += 1; + + generic_parse_inc(state); + for (;;){ + generic_parse_skip_soft_tokens(index, state); + token = token_it_read(&state->it); + if (token == 0 || state->finished){ + break; + } + + if (state->in_preprocessor){ + if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || + token->kind == TokenBaseKind_Preprocessor){ + break; + } + } + else{ + if (token->kind == TokenBaseKind_Preprocessor){ + Code_Index_Nest *nest = generic_parse_preprocessor(index, state); + code_index_push_nest(&index->nest_list, nest); + continue; + } + } + + if (token->kind == TokenBaseKind_ScopeClose){ + result->is_closed = true; + result->close = Ii64(token); + generic_parse_inc(state); + break; + } + + if (token->kind == TokenBaseKind_ScopeOpen){ + Code_Index_Nest *nest = generic_parse_scope(index, state); + nest->parent = result; + code_index_push_nest(&result->nest_list, nest); + continue; + } + + if (token->kind == TokenBaseKind_ParentheticalOpen){ + Code_Index_Nest *nest = generic_parse_paren(index, state); + nest->parent = result; + code_index_push_nest(&result->nest_list, nest); + continue; + } + + if (token->kind == TokenBaseKind_ParentheticalClose){ + generic_parse_inc(state); + continue; + } + + { + Code_Index_Nest *nest = generic_parse_statement(index, state); + nest->parent = result; + code_index_push_nest(&result->nest_list, nest); + } + } + + result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); + + state->scope_counter -= 1; + + return(result); +} + +function Code_Index_Nest* +generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state){ + Token *token = token_it_read(&state->it); + Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); + result->kind = CodeIndexNest_Paren; + result->open = Ii64(token); + result->close = Ii64(max_i64); + result->file = index; + + i64 manifested_characters_on_line = 0; + { + u8 *ptr = state->prev_line_start; + u8 *end_ptr = state->contents.str + token->pos; + // NOTE(allen): Initial whitespace + for (;ptr < end_ptr; ptr += 1){ + if (!character_is_whitespace(*ptr)){ + break; + } + } + // NOTE(allen): Manifested characters + manifested_characters_on_line = (i64)(end_ptr - ptr) + token->size; + } + + state->paren_counter += 1; + + generic_parse_inc(state); + for (;;){ + generic_parse_skip_soft_tokens(index, state); + token = token_it_read(&state->it); + if (token == 0 || state->finished){ + break; + } + + if (state->in_preprocessor){ + if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || + token->kind == TokenBaseKind_Preprocessor){ + break; + } + } + else{ + if (token->kind == TokenBaseKind_Preprocessor){ + Code_Index_Nest *nest = generic_parse_preprocessor(index, state); + code_index_push_nest(&index->nest_list, nest); + continue; + } + } + + if (token->kind == TokenBaseKind_ParentheticalClose){ + result->is_closed = true; + result->close = Ii64(token); + generic_parse_inc(state); + break; + } + + if (token->kind == TokenBaseKind_ScopeClose){ + break; + } + + if (token->kind == TokenBaseKind_ScopeOpen){ + Code_Index_Nest *nest = generic_parse_scope(index, state); + nest->parent = result; + code_index_push_nest(&result->nest_list, nest); + continue; + } + + if (token->kind == TokenBaseKind_ParentheticalOpen){ + Code_Index_Nest *nest = generic_parse_paren(index, state); + nest->parent = result; + code_index_push_nest(&result->nest_list, nest); + continue; + } + + generic_parse_inc(state); + } + + result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); + + state->paren_counter -= 1; + + return(result); +} + +function b32 +generic_parse_full_input_breaks(Code_Index_File *index, Generic_Parse_State *state, i32 limit){ + b32 result = false; + + i64 first_index = token_it_index(&state->it); + i64 one_past_last_index = first_index + limit; + for (;;){ + generic_parse_skip_soft_tokens(index, state); + Token *token = token_it_read(&state->it); + + if (token == 0 || state->finished){ + result = true; + break; + } + + if (token->kind == TokenBaseKind_Preprocessor){ + Code_Index_Nest *nest = generic_parse_preprocessor(index, state); + code_index_push_nest(&index->nest_list, nest); + } + else if (token->kind == TokenBaseKind_ScopeOpen){ + Code_Index_Nest *nest = generic_parse_scope(index, state); + code_index_push_nest(&index->nest_list, nest); + } + else if (token->kind == TokenBaseKind_ParentheticalOpen){ + Code_Index_Nest *nest = generic_parse_paren(index, state); + code_index_push_nest(&index->nest_list, nest); + } + else if (state->do_cpp_parse){ + if (token->sub_kind == TokenCppKind_Struct || + token->sub_kind == TokenCppKind_Union || + token->sub_kind == TokenCppKind_Enum){ + cpp_parse_type_structure(index, state, 0); + } + else if (token->sub_kind == TokenCppKind_Typedef){ + cpp_parse_type_def(index, state, 0); + } + else if (token->sub_kind == TokenCppKind_Identifier){ + cpp_parse_function(index, state, 0); + } + else{ + generic_parse_inc(state); + } + } + else{ + generic_parse_inc(state); + } + + i64 index = token_it_index(&state->it); + if (index >= one_past_last_index){ + token = token_it_read(&state->it); + if (token == 0){ + result = true; + } + break; + } + } + + if (result){ + index->nest_array = code_index_nest_ptr_array_from_list(state->arena, &index->nest_list); + index->note_array = code_index_note_ptr_array_from_list(state->arena, &index->note_list); + } + + return(result); +} + +//////////////////////////////// + +function void +default_comment_index(Application_Links *app, Arena *arena, Code_Index_File *index, Token *token, String_Const_u8 contents){ + +} + +function void +generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 contents, Token_Array *tokens, Generic_Parse_State *state){ + generic_parse_init(app, arena, contents, tokens, default_comment_index, state); +} + +//////////////////////////////// + +function Token_Pair +layout_token_pair(Token_Array *tokens, i64 pos){ + Token_Pair result = {}; + Token_Iterator_Array it = token_iterator_pos(0, tokens, pos); + Token *b = token_it_read(&it); + if (b != 0){ + if (b->kind == TokenBaseKind_Whitespace){ + token_it_inc_non_whitespace(&it); + b = token_it_read(&it); + } + } + token_it_dec_non_whitespace(&it); + Token *a = token_it_read(&it); + if (a != 0){ + result.a = *a; + } + if (b != 0){ + result.b = *b; + } + return(result); +} + +function f32 +layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_Nest *nest, i64 pos, f32 space_advance, b32 *unresolved_dependence){ + f32 result = 0.f; + if (nest != 0){ + switch (nest->kind){ + case CodeIndexNest_Scope: + case CodeIndexNest_Preprocessor: + { + result = layout_index_x_shift(app, reflex, nest->parent, pos, space_advance, unresolved_dependence); + if (nest->open.min < pos && nest->open.max <= pos && + (!nest->is_closed || pos < nest->close.min)){ + result += 4.f*space_advance; + } + }break; + + case CodeIndexNest_Statement: + { + result = layout_index_x_shift(app, reflex, nest->parent, pos, space_advance, unresolved_dependence); + if (nest->open.min < pos && nest->open.max <= pos && + (!nest->is_closed || pos < nest->close.min)){ + result += 4.f*space_advance; + } + }break; + + case CodeIndexNest_Paren: + { + Rect_f32 box = layout_reflex_get_rect(app, reflex, nest->open.max - 1, unresolved_dependence); + result = box.x1; + }break; + } + } + return(result); +} + +function f32 +layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_Nest *nest, i64 pos, f32 space_advance){ + b32 ignore; + return(layout_index_x_shift(app, reflex, nest, pos, space_advance, &ignore)); +} + +function f32 +layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_File *file, i64 pos, f32 space_advance, b32 *unresolved_dependence){ + f32 indent = 0; + Code_Index_Nest *nest = code_index_get_nest(file, pos); + if (nest != 0){ + indent = layout_index_x_shift(app, reflex, nest, pos, space_advance, unresolved_dependence); + } + return(indent); +} + +function f32 +layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_File *file, i64 pos, f32 space_advance){ + b32 ignore; + return(layout_index_x_shift(app, reflex, file, pos, space_advance, &ignore)); +} + +function void +layout_index__emit_chunk(LefRig_TopBot_Layout_Vars *pos_vars, Face_ID face, Arena *arena, u8 *text_str, i64 range_first, u8 *ptr, u8 *end, Layout_Item_List *list){ + for (;ptr < end;){ + Character_Consume_Result consume = utf8_consume(ptr, (u64)(end - ptr)); + if (consume.codepoint != '\r'){ + i64 index = layout_index_from_ptr(ptr, text_str, range_first); + if (consume.codepoint != max_u32){ + lr_tb_write(pos_vars, face, arena, list, index, consume.codepoint); + } + else{ + lr_tb_write_byte(pos_vars, face, arena, list, index, *ptr); + } + } + ptr += consume.inc; + } +} + +function i32 +layout_token_score_wrap_token(Token_Pair *pair, Token_Cpp_Kind kind){ + i32 result = 0; + if (pair->a.sub_kind != kind && pair->b.sub_kind == kind){ + result -= 1; + } + else if (pair->a.sub_kind == kind && pair->b.sub_kind != kind){ + result += 1; + } + return(result); +} + +function Layout_Item_List +layout_index__inner(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width, Code_Index_File *file, Layout_Wrap_Kind kind){ + Scratch_Block scratch(app); + + Managed_Scope scope = buffer_get_managed_scope(app, buffer); + Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, Token_Array); + + Layout_Item_List list = get_empty_item_list(range); + String_Const_u8 text = push_buffer_range(app, scratch, buffer, range); + + Face_Advance_Map advance_map = get_face_advance_map(app, face); + Face_Metrics metrics = get_face_metrics(app, face); + LefRig_TopBot_Layout_Vars pos_vars = get_lr_tb_layout_vars(&advance_map, &metrics, width); + + f32 wrap_align_x = width - metrics.normal_advance; + + Layout_Reflex reflex = get_layout_reflex(&list, buffer, width, face); + + if (text.size == 0){ + lr_tb_write_blank(&pos_vars, face, arena, &list, range.start); + } + else{ + b32 first_of_the_line = true; + Newline_Layout_Vars newline_vars = get_newline_layout_vars(); + + u8 *ptr = text.str; + u8 *end_ptr = ptr + text.size; + u8 *word_ptr = ptr; + + u8 *pending_wrap_ptr = ptr; + f32 pending_wrap_x = 0.f; + i32 pending_wrap_paren_nest_count = 0; + i32 pending_wrap_token_score = 0; + f32 pending_wrap_accumulated_w = 0.f; + + start: + if (ptr == end_ptr){ + i64 index = layout_index_from_ptr(ptr, text.str, range.first); + f32 shift = layout_index_x_shift(app, &reflex, file, index, metrics.space_advance); + lr_tb_advance_x_without_item(&pos_vars, shift); + goto finish; + } + + if (!character_is_whitespace(*ptr)){ + i64 index = layout_index_from_ptr(ptr, text.str, range.first); + f32 shift = layout_index_x_shift(app, &reflex, file, index, metrics.space_advance); + lr_tb_advance_x_without_item(&pos_vars, shift); + goto consuming_non_whitespace; + } + + { + for (;ptr < end_ptr; ptr += 1){ + if (!character_is_whitespace(*ptr)){ + pending_wrap_ptr = ptr; + word_ptr = ptr; + i64 index = layout_index_from_ptr(ptr, text.str, range.first); + f32 shift = layout_index_x_shift(app, &reflex, file, index, metrics.space_advance); + lr_tb_advance_x_without_item(&pos_vars, shift); + goto consuming_non_whitespace; + } + if (*ptr == '\n'){ + pending_wrap_ptr = ptr; + i64 index = layout_index_from_ptr(ptr, text.str, range.first); + f32 shift = layout_index_x_shift(app, &reflex, file, index, metrics.space_advance); + lr_tb_advance_x_without_item(&pos_vars, shift); + goto consuming_normal_whitespace; + } + } + + if (ptr == end_ptr){ + pending_wrap_ptr = ptr; + i64 index = layout_index_from_ptr(ptr - 1, text.str, range.first); + f32 shift = layout_index_x_shift(app, &reflex, file, index, metrics.space_advance); + lr_tb_advance_x_without_item(&pos_vars, shift); + goto finish; + } + } + + consuming_non_whitespace: + { + for (;ptr <= end_ptr; ptr += 1){ + if (ptr == end_ptr || character_is_whitespace(*ptr)){ + break; + } + } + + // NOTE(allen): measure this word + newline_layout_consume_default(&newline_vars); + String_Const_u8 word = SCu8(word_ptr, ptr); + u8 *word_end = ptr; + { + f32 word_advance = 0.f; + ptr = word.str; + for (;ptr < word_end;){ + Character_Consume_Result consume = utf8_consume(ptr, (u64)(word_end - ptr)); + if (consume.codepoint != max_u32){ + word_advance += lr_tb_advance(&pos_vars, face, consume.codepoint); + } + else{ + word_advance += lr_tb_advance_byte(&pos_vars); + } + ptr += consume.inc; + } + pending_wrap_accumulated_w += word_advance; + } + + if (!first_of_the_line && (kind == Layout_Wrapped) && lr_tb_crosses_width(&pos_vars, pending_wrap_accumulated_w)){ + i64 index = layout_index_from_ptr(pending_wrap_ptr, text.str, range.first); + lr_tb_align_rightward(&pos_vars, wrap_align_x); + lr_tb_write_ghost(&pos_vars, face, arena, &list, index, '\\'); + + lr_tb_next_line(&pos_vars); +#if 0 + f32 shift = layout_index_x_shift(app, &reflex, file, index, metrics.space_advance); + lr_tb_advance_x_without_item(&pos_vars, shift); +#endif + + ptr = pending_wrap_ptr; + pending_wrap_accumulated_w = 0.f; + first_of_the_line = true; + goto start; + } + } + + consuming_normal_whitespace: + for (; ptr < end_ptr; ptr += 1){ + if (!character_is_whitespace(*ptr)){ + u8 *new_wrap_ptr = ptr; + + i64 index = layout_index_from_ptr(new_wrap_ptr, text.str, range.first); + Code_Index_Nest *new_wrap_nest = code_index_get_nest(file, index); + b32 invalid_wrap_x = false; + f32 new_wrap_x = layout_index_x_shift(app, &reflex, new_wrap_nest, index, metrics.space_advance, &invalid_wrap_x); + if (invalid_wrap_x){ + new_wrap_x = max_f32; + } + + i32 new_wrap_paren_nest_count = 0; + for (Code_Index_Nest *nest = new_wrap_nest; + nest != 0; + nest = nest->parent){ + if (nest->kind == CodeIndexNest_Paren){ + new_wrap_paren_nest_count += 1; + } + } + + Token_Pair new_wrap_token_pair = layout_token_pair(tokens_ptr, index); + + // TODO(allen): pull out the token scoring part and make it replacable for other + // language's token based wrap scoring needs. + i32 token_score = 0; + if (new_wrap_token_pair.a.kind == TokenBaseKind_Keyword){ + if (new_wrap_token_pair.b.kind == TokenBaseKind_ParentheticalOpen || + new_wrap_token_pair.b.kind == TokenBaseKind_Keyword){ + token_score -= 2; + } + } + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Eq); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_PlusEq); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_MinusEq); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_StarEq); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_DivEq); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_ModEq); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_LeftLeftEq); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_RightRightEq); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Comma); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_AndAnd); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_OrOr); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Ternary); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Colon); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Semicolon); + + i32 new_wrap_token_score = token_score; + + b32 new_wrap_ptr_is_better = false; + if (first_of_the_line){ + new_wrap_ptr_is_better = true; + } + else{ + if (new_wrap_token_score > pending_wrap_token_score){ + new_wrap_ptr_is_better = true; + } + else if (new_wrap_token_score == pending_wrap_token_score){ + f32 new_score = new_wrap_paren_nest_count*10.f + new_wrap_x; + f32 old_score = pending_wrap_paren_nest_count*10.f + pending_wrap_x + metrics.normal_advance*4.f + pending_wrap_accumulated_w*0.5f; + + if (new_score < old_score){ + new_wrap_ptr_is_better = true; + } + } + } + + if (new_wrap_ptr_is_better){ + layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, new_wrap_ptr, &list); + first_of_the_line = false; + + pending_wrap_ptr = new_wrap_ptr; + pending_wrap_paren_nest_count = new_wrap_paren_nest_count; + pending_wrap_x = layout_index_x_shift(app, &reflex, new_wrap_nest, index, metrics.space_advance); + pending_wrap_paren_nest_count = new_wrap_paren_nest_count; + pending_wrap_token_score = new_wrap_token_score; + pending_wrap_accumulated_w = 0.f; + } + + word_ptr = ptr; + goto consuming_non_whitespace; + } + + i64 index = layout_index_from_ptr(ptr, text.str, range.first); + switch (*ptr){ + default: + { + newline_layout_consume_default(&newline_vars); + pending_wrap_accumulated_w += lr_tb_advance(&pos_vars, face, *ptr); + }break; + + case '\r': + { + newline_layout_consume_CR(&newline_vars, index); + }break; + + case '\n': + { + layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, ptr, &list); + pending_wrap_ptr = ptr + 1; + pending_wrap_accumulated_w = 0.f; + + u64 newline_index = newline_layout_consume_LF(&newline_vars, index); + lr_tb_write_blank(&pos_vars, face, arena, &list, newline_index); + lr_tb_next_line(&pos_vars); + first_of_the_line = true; + ptr += 1; + goto start; + }break; + } + } + + finish: + if (newline_layout_consume_finish(&newline_vars)){ + layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, ptr, &list); + i64 index = layout_index_from_ptr(ptr, text.str, range.first); + lr_tb_write_blank(&pos_vars, face, arena, &list, index); + } + } + + layout_item_list_finish(&list, -pos_vars.line_to_text_shift); + + return(list); +} + +function Layout_Item_List +layout_virt_indent_index(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width, Layout_Wrap_Kind kind){ + Layout_Item_List result = {}; + + if (global_config.enable_virtual_whitespace){ + code_index_lock(); + Code_Index_File *file = code_index_get_file(buffer); + if (file != 0){ + result = layout_index__inner(app, arena, buffer, range, face, width, file, kind); + } + code_index_unlock(); + if (file == 0){ + result = layout_virt_indent_literal(app, arena, buffer, range, face, width, kind); + } + } + else{ + result = layout_basic(app, arena, buffer, range, face, width, kind); + } + + return(result); +} + +function Layout_Item_List +layout_virt_indent_index_unwrapped(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ + return(layout_virt_indent_index(app, arena, buffer, range, face, width, Layout_Unwrapped)); +} + +function Layout_Item_List +layout_virt_indent_index_wrapped(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ + return(layout_virt_indent_index(app, arena, buffer, range, face, width, Layout_Wrapped)); +} + +function Layout_Item_List +layout_virt_indent_index_generic(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ + Managed_Scope scope = buffer_get_managed_scope(app, buffer); + b32 *wrap_lines_ptr = scope_attachment(app, scope, buffer_wrap_lines, b32); + b32 wrap_lines = (wrap_lines_ptr != 0 && *wrap_lines_ptr); + return(layout_virt_indent_index(app, arena, buffer, range, face, width, wrap_lines?Layout_Wrapped:Layout_Unwrapped)); +} + +CUSTOM_COMMAND_SIG(toggle_virtual_whitespace) +CUSTOM_DOC("Toggles the current buffer's virtual whitespace status.") +{ + global_config.enable_virtual_whitespace = !global_config.enable_virtual_whitespace; + + for (Buffer_ID buffer = get_buffer_next(app, 0, Access_Always); + buffer != 0; + buffer = get_buffer_next(app, buffer, Access_Always)){ + buffer_clear_layout_cache(app, buffer); + } +} + +// BOTTOM + diff --git a/custom/4coder_draw.cpp b/custom/4coder_draw.cpp index 7ee104c6..c08b4b73 100644 --- a/custom/4coder_draw.cpp +++ b/custom/4coder_draw.cpp @@ -1,843 +1,843 @@ -/* -4coder_draw.cpp - Layout and rendering implementation of standard UI pieces (including buffers) -*/ - -// TOP - -function void -draw_text_layout_default(Application_Links *app, Text_Layout_ID layout_id){ - ARGB_Color special_color = finalize_color(defcolor_special_character, 0); - ARGB_Color ghost_color = finalize_color(defcolor_ghost_character, 0); - draw_text_layout(app, layout_id, special_color, ghost_color); -} - -function FColor -get_margin_color(i32 level){ - FColor margin = fcolor_zero(); - switch (level){ - default: - case UIHighlight_None: - { - margin = fcolor_id(defcolor_list_item); - }break; - case UIHighlight_Hover: - { - margin = fcolor_id(defcolor_list_item_hover); - }break; - case UIHighlight_Active: - { - margin = fcolor_id(defcolor_list_item_active); - }break; - } - return(margin); -} - -function Vec2_f32 -draw_string(Application_Links *app, Face_ID font_id, String_Const_u8 string, Vec2_f32 p, ARGB_Color color){ - return(draw_string_oriented(app, font_id, color, string, p, 0, V2f32(1.f, 0.f))); -} - -function Vec2_f32 -draw_string(Application_Links *app, Face_ID font_id, String_Const_u8 string, Vec2_f32 p, FColor color){ - ARGB_Color argb = fcolor_resolve(color); - draw_string(app, font_id, string, p, argb); -} - -function void -draw_rectangle_fcolor(Application_Links *app, Rect_f32 rect, f32 roundness, FColor color){ - ARGB_Color argb = fcolor_resolve(color); - draw_rectangle(app, rect, roundness, argb); -} - -function void -draw_rectangle_outline_fcolor(Application_Links *app, Rect_f32 rect, f32 roundness, f32 thickness, FColor color){ - ARGB_Color argb = fcolor_resolve(color); - draw_rectangle_outline(app, rect, roundness, thickness, argb); -} - -function void -draw_margin(Application_Links *app, Rect_f32 outer, Rect_f32 inner, ARGB_Color color){ - draw_rectangle(app, Rf32(outer.x0, outer.y0, outer.x1, inner.y0), 0.f, color); - draw_rectangle(app, Rf32(outer.x0, inner.y1, outer.x1, outer.y1), 0.f, color); - draw_rectangle(app, Rf32(outer.x0, inner.y0, inner.x0, inner.y1), 0.f, color); - draw_rectangle(app, Rf32(inner.x1, inner.y0, outer.x1, inner.y1), 0.f, color); -} - -function void -draw_margin(Application_Links *app, Rect_f32 outer, Rect_f32 inner, FColor color){ - ARGB_Color argb = fcolor_resolve(color); - draw_margin(app, outer, inner, argb); -} - -function void -draw_character_block(Application_Links *app, Text_Layout_ID layout, i64 pos, f32 roundness, ARGB_Color color){ - Rect_f32 rect = text_layout_character_on_screen(app, layout, pos); - draw_rectangle(app, rect, roundness, color); -} - -function void -draw_character_block(Application_Links *app, Text_Layout_ID layout, i64 pos, f32 roundness, FColor color){ - ARGB_Color argb = fcolor_resolve(color); - draw_character_block(app, layout, pos, roundness, argb); -} - -function void -draw_character_block(Application_Links *app, Text_Layout_ID layout, Range_i64 range, f32 roundness, ARGB_Color color){ - if (range.first < range.one_past_last){ - i64 i = range.first; - Rect_f32 first_rect = text_layout_character_on_screen(app, layout, i); - i += 1; - Range_f32 y = rect_range_y(first_rect); - Range_f32 x = rect_range_x(first_rect); - for (;i < range.one_past_last; i += 1){ - Rect_f32 rect = text_layout_character_on_screen(app, layout, i); - if (rect.x0 < rect.x1 && rect.y0 < rect.y1){ - Range_f32 new_y = rect_range_y(rect); - Range_f32 new_x = rect_range_x(rect); - b32 joinable = false; - if (new_y == y && (range_overlap(x, new_x) || x.max == new_x.min || new_x.max == x.min)){ - joinable = true; - } - - if (!joinable){ - draw_rectangle(app, Rf32(x, y), roundness, color); - y = new_y; - x = new_x; - } - else{ - x = range_union(x, new_x); - } - } - } - draw_rectangle(app, Rf32(x, y), roundness, color); - } - for (i64 i = range.first; i < range.one_past_last; i += 1){ - draw_character_block(app, layout, i, roundness, color); - } -} - -function void -draw_character_block(Application_Links *app, Text_Layout_ID layout, Range_i64 range, f32 roundness, FColor color){ - ARGB_Color argb = fcolor_resolve(color); - draw_character_block(app, layout, range, roundness, argb); - } - -function void -draw_character_wire_frame(Application_Links *app, Text_Layout_ID layout, i64 pos, f32 roundness, f32 thickness, ARGB_Color color){ - Rect_f32 rect = text_layout_character_on_screen(app, layout, pos); - draw_rectangle_outline(app, rect, roundness, thickness, color); -} - -function void -draw_character_wire_frame(Application_Links *app, Text_Layout_ID layout, i64 pos, f32 roundness, f32 thickness, FColor color){ - ARGB_Color argb = fcolor_resolve(color); - draw_character_wire_frame(app, layout, pos, roundness, thickness, argb); -} - -function void -draw_character_wire_frame(Application_Links *app, Text_Layout_ID layout, Range_i64 range, f32 roundness, f32 thickness, FColor color){ - for (i64 i = range.first; i < range.one_past_last; i += 1){ - draw_character_wire_frame(app, layout, i, roundness, thickness, color); - } -} - -function void -draw_character_i_bar(Application_Links *app, Text_Layout_ID layout, i64 pos, ARGB_Color color){ - Rect_f32 rect = text_layout_character_on_screen(app, layout, pos); - rect.x1 = rect.x0 + 1.f; - draw_rectangle(app, rect, 0.f, color); -} - -function void -draw_character_i_bar(Application_Links *app, Text_Layout_ID layout, i64 pos, FColor color){ - ARGB_Color argb = fcolor_resolve(color); - draw_character_i_bar(app, layout, pos, argb); -} - -function void -draw_line_highlight(Application_Links *app, Text_Layout_ID layout, Range_i64 line_range, ARGB_Color color){ - Range_f32 y1 = text_layout_line_on_screen(app, layout, line_range.min); - Range_f32 y2 = text_layout_line_on_screen(app, layout, line_range.max); - Range_f32 y = range_union(y1, y2); - if (range_size(y) > 0.f){ - Rect_f32 region = text_layout_region(app, layout); - draw_rectangle(app, Rf32(rect_range_x(region), y), 0.f, color); - } -} - -function void -draw_line_highlight(Application_Links *app, Text_Layout_ID layout, Range_i64 line_range, FColor color){ - ARGB_Color argb = fcolor_resolve(color); - draw_line_highlight(app, layout, line_range, argb); -} - -function void -draw_line_highlight(Application_Links *app, Text_Layout_ID layout, i64 line, ARGB_Color color){ - draw_line_highlight(app, layout, Ii64(line), color); -} - -function void -draw_line_highlight(Application_Links *app, Text_Layout_ID layout, i64 line, FColor color){ - draw_line_highlight(app, layout, Ii64(line), color); -} - -function void -paint_text_color_fcolor(Application_Links *app, Text_Layout_ID layout, Range_i64 pos, FColor color){ - ARGB_Color argb = fcolor_resolve(color); - paint_text_color(app, layout, pos, argb); -} - -function void -paint_text_color_pos(Application_Links *app, Text_Layout_ID layout, i64 pos, ARGB_Color color){ - paint_text_color(app, layout, Ii64(pos, pos + 1), color); -} - -function void -paint_text_color_pos(Application_Links *app, Text_Layout_ID layout, i64 pos, FColor color){ - ARGB_Color argb = fcolor_resolve(color); - paint_text_color_pos(app, layout, pos, argb); -} - -//////////////////////////////// - -function Rect_f32_Pair -layout_file_bar_on_top(Rect_f32 rect, f32 line_height){ - return(rect_split_top_bottom(rect, line_height + 2.f)); -} - -function Rect_f32_Pair -layout_file_bar_on_bot(Rect_f32 rect, f32 line_height){ - return(rect_split_top_bottom_neg(rect, line_height + 2.f)); -} - -function Rect_f32_Pair -layout_query_bar_on_top(Rect_f32 rect, f32 line_height, i32 bar_count){ - return(rect_split_top_bottom(rect, (line_height + 2.f)*bar_count)); -} - -function Rect_f32_Pair -layout_query_bar_on_bot(Rect_f32 rect, f32 line_height, i32 bar_count){ - return(rect_split_top_bottom_neg(rect, (line_height + 2.f)*bar_count)); -} - -function Rect_f32_Pair -layout_line_number_margin(Rect_f32 rect, f32 digit_advance, i64 digit_count){ - f32 margin_width = (f32)digit_count*digit_advance + 2.f; - return(rect_split_left_right(rect, margin_width)); -} - -function Rect_f32_Pair -layout_line_number_margin(Application_Links *app, Buffer_ID buffer, Rect_f32 rect, f32 digit_advance){ - i64 line_count = buffer_get_line_count(app, buffer); - i64 line_count_digit_count = digit_count_from_integer(line_count, 10); - return(layout_line_number_margin(rect, digit_advance, line_count_digit_count)); -} - -global_const i32 fps_history_depth = 10; -function Rect_f32_Pair -layout_fps_hud_on_bottom(Rect_f32 rect, f32 line_height){ - return(rect_split_top_bottom_neg(rect, line_height*fps_history_depth)); -} - -function Rect_f32 -draw_background_and_margin(Application_Links *app, View_ID view, ARGB_Color margin, ARGB_Color back){ - Rect_f32 view_rect = view_get_screen_rect(app, view); - Rect_f32 inner = rect_inner(view_rect, 3.f); - draw_rectangle(app, inner, 0.f, back); - draw_margin(app, view_rect, inner, margin); - return(inner); -} - -function Rect_f32 -draw_background_and_margin(Application_Links *app, View_ID view, FColor margin, FColor back){ - ARGB_Color margin_argb = fcolor_resolve(margin); - ARGB_Color back_argb = fcolor_resolve(back); - return(draw_background_and_margin(app, view, margin_argb, back_argb)); -} - -function Rect_f32 -draw_background_and_margin(Application_Links *app, View_ID view, b32 is_active_view){ - FColor margin_color = get_margin_color(is_active_view?UIHighlight_Active:UIHighlight_None); - return(draw_background_and_margin(app, view, margin_color, fcolor_id(defcolor_back))); -} - -function Rect_f32 -draw_background_and_margin(Application_Links *app, View_ID view){ - View_ID active_view = get_active_view(app, Access_Always); - b32 is_active_view = (active_view == view); - return(draw_background_and_margin(app, view, is_active_view)); -} - -function void -draw_file_bar(Application_Links *app, View_ID view_id, Buffer_ID buffer, Face_ID face_id, Rect_f32 bar){ - Scratch_Block scratch(app); - - draw_rectangle_fcolor(app, bar, 0.f, fcolor_id(defcolor_bar)); - - FColor base_color = fcolor_id(defcolor_base); - FColor pop2_color = fcolor_id(defcolor_pop2); - - i64 cursor_position = view_get_cursor_pos(app, view_id); - Buffer_Cursor cursor = view_compute_cursor(app, view_id, seek_pos(cursor_position)); - - Fancy_Line list = {}; - String_Const_u8 unique_name = push_buffer_unique_name(app, scratch, buffer); - push_fancy_string(scratch, &list, base_color, unique_name); - push_fancy_stringf(scratch, &list, base_color, " - Row: %3.lld Col: %3.lld -", cursor.line, cursor.col); - - Managed_Scope scope = buffer_get_managed_scope(app, buffer); - Line_Ending_Kind *eol_setting = scope_attachment(app, scope, buffer_eol_setting, - Line_Ending_Kind); - switch (*eol_setting){ - case LineEndingKind_Binary: - { - push_fancy_string(scratch, &list, base_color, string_u8_litexpr(" bin")); - }break; - - case LineEndingKind_LF: - { - push_fancy_string(scratch, &list, base_color, string_u8_litexpr(" lf")); - }break; - - case LineEndingKind_CRLF: - { - push_fancy_string(scratch, &list, base_color, string_u8_litexpr(" crlf")); - }break; - } - - { - Dirty_State dirty = buffer_get_dirty_state(app, buffer); - u8 space[3]; - String_u8 str = Su8(space, 0, 3); - if (dirty != 0){ - string_append(&str, string_u8_litexpr(" ")); - } - if (HasFlag(dirty, DirtyState_UnsavedChanges)){ - string_append(&str, string_u8_litexpr("*")); - } - if (HasFlag(dirty, DirtyState_UnloadedChanges)){ - string_append(&str, string_u8_litexpr("!")); - } - push_fancy_string(scratch, &list, pop2_color, str.string); - } - - Vec2_f32 p = bar.p0 + V2f32(2.f, 2.f); - draw_fancy_line(app, face_id, fcolor_zero(), &list, p); -} - -function void -draw_query_bar(Application_Links *app, Query_Bar *query_bar, Face_ID face_id, Rect_f32 bar){ - Scratch_Block scratch(app); - Fancy_Line list = {}; - push_fancy_string(scratch, &list, fcolor_id(defcolor_pop1) , query_bar->prompt); - push_fancy_string(scratch, &list, fcolor_id(defcolor_text_default), query_bar->string); - Vec2_f32 p = bar.p0 + V2f32(2.f, 2.f); - draw_fancy_line(app, face_id, fcolor_zero(), &list, p); -} - -function void -draw_line_number_margin(Application_Links *app, View_ID view_id, Buffer_ID buffer, Face_ID face_id, Text_Layout_ID text_layout_id, Rect_f32 margin){ - Rect_f32 prev_clip = draw_set_clip(app, margin); - draw_rectangle_fcolor(app, margin, 0.f, fcolor_id(defcolor_line_numbers_back)); - - Range_i64 visible_range = text_layout_get_visible_range(app, text_layout_id); - - FColor line_color = fcolor_id(defcolor_line_numbers_text); - - i64 line_count = buffer_get_line_count(app, buffer); - i64 line_count_digit_count = digit_count_from_integer(line_count, 10); - - Scratch_Block scratch(app, Scratch_Share); - - Buffer_Cursor cursor = view_compute_cursor(app, view_id, seek_pos(visible_range.first)); - i64 line_number = cursor.line; - for (;cursor.pos <= visible_range.one_past_last;){ - if (line_number > line_count){ - break; - } - Range_f32 line_y = text_layout_line_on_screen(app, text_layout_id, line_number); - Vec2_f32 p = V2f32(margin.x0, line_y.min); - Temp_Memory_Block temp(scratch); - Fancy_String *string = push_fancy_stringf(scratch, 0, line_color, - "%*lld", - line_count_digit_count, - line_number); - draw_fancy_string(app, face_id, fcolor_zero(), string, p); - line_number += 1; - } - - draw_set_clip(app, prev_clip); -} - -function void -draw_fps_hud(Application_Links *app, Frame_Info frame_info, - Face_ID face_id, Rect_f32 rect){ - Face_Metrics face_metrics = get_face_metrics(app, face_id); - f32 line_height = face_metrics.line_height; - - local_persist f32 history_literal_dt[fps_history_depth] = {}; - local_persist f32 history_animation_dt[fps_history_depth] = {}; - local_persist i32 history_frame_index[fps_history_depth] = {}; - - i32 wrapped_index = frame_info.index%fps_history_depth; - history_literal_dt[wrapped_index] = frame_info.literal_dt; - history_animation_dt[wrapped_index] = frame_info.animation_dt; - history_frame_index[wrapped_index] = frame_info.index; - - draw_rectangle_fcolor(app, rect, 0.f, f_black); - draw_rectangle_outline_fcolor(app, rect, 0.f, 1.f, f_white); - - Vec2_f32 p = rect.p0; - - Scratch_Block scratch(app); - - Range_i32 ranges[2] = {}; - ranges[0].first = wrapped_index; - ranges[0].one_past_last = -1; - ranges[1].first = fps_history_depth - 1; - ranges[1].one_past_last = wrapped_index; - for (i32 i = 0; i < 2; i += 1){ - Range_i32 r = ranges[i]; - for (i32 j = r.first; j > r.one_past_last; j -= 1, p.y += line_height){ - f32 dts[2]; - dts[0] = history_literal_dt[j]; - dts[1] = history_animation_dt[j]; - i32 frame_index = history_frame_index[j]; - - Fancy_Line list = {}; - push_fancy_stringf(scratch, &list, f_pink , "FPS: "); - push_fancy_stringf(scratch, &list, f_green, "["); - push_fancy_stringf(scratch, &list, f_white, "%5d", frame_index); - push_fancy_stringf(scratch, &list, f_green, "]: "); - - for (i32 k = 0; k < 2; k += 1){ - f32 dt = dts[k]; - if (dt == 0.f){ - push_fancy_stringf(scratch, &list, f_white, "----------"); - } - else{ - push_fancy_stringf(scratch, &list, f_white, "%10.6f", dt); - } - push_fancy_stringf(scratch, &list, f_green, " | "); - } - - draw_fancy_line(app, face_id, fcolor_zero(), &list, p); - } - } -} - -function FColor -get_token_color_cpp(Token token){ - Managed_ID color = defcolor_text_default; - switch (token.kind){ - case TokenBaseKind_Preprocessor: - { - color = defcolor_preproc; - }break; - case TokenBaseKind_Keyword: - { - color = defcolor_keyword; - }break; - case TokenBaseKind_Comment: - { - color = defcolor_comment; - }break; - case TokenBaseKind_LiteralString: - { - color = defcolor_str_constant; - }break; - case TokenBaseKind_LiteralInteger: - { - color = defcolor_int_constant; - }break; - case TokenBaseKind_LiteralFloat: - { - color = defcolor_float_constant; - }break; - default: - { - switch (token.sub_kind){ - case TokenCppKind_LiteralTrue: - case TokenCppKind_LiteralFalse: - { - color = defcolor_bool_constant; - }break; - case TokenCppKind_LiteralCharacter: - case TokenCppKind_LiteralCharacterWide: - case TokenCppKind_LiteralCharacterUTF8: - case TokenCppKind_LiteralCharacterUTF16: - case TokenCppKind_LiteralCharacterUTF32: - { - color = defcolor_char_constant; - }break; - case TokenCppKind_PPIncludeFile: - { - color = defcolor_include; - }break; - } - }break; - } - return(fcolor_id(color)); -} - -function void -draw_cpp_token_colors(Application_Links *app, Text_Layout_ID text_layout_id, Token_Array *array){ - Range_i64 visible_range = text_layout_get_visible_range(app, text_layout_id); - i64 first_index = token_index_from_pos(array, visible_range.first); - Token_Iterator_Array it = token_iterator_index(0, array, first_index); - for (;;){ - Token *token = token_it_read(&it); - if (token->pos >= visible_range.one_past_last){ - break; - } - FColor color = get_token_color_cpp(*token); - ARGB_Color argb = fcolor_resolve(color); - paint_text_color(app, text_layout_id, Ii64_size(token->pos, token->size), argb); - if (!token_it_inc_all(&it)){ - break; - } - } -} - -function void -draw_comment_highlights(Application_Links *app, Buffer_ID buffer, Text_Layout_ID text_layout_id, - Token_Array *array, Comment_Highlight_Pair *pairs, i32 pair_count){ - Scratch_Block scratch(app); - Range_i64 visible_range = text_layout_get_visible_range(app, text_layout_id); - i64 first_index = token_index_from_pos(array, visible_range.first); - Token_Iterator_Array it = token_iterator_index(buffer, array, first_index); - for (;;){ - Temp_Memory_Block temp(scratch); - Token *token = token_it_read(&it); - if (token->pos >= visible_range.one_past_last){ - break; - } - String_Const_u8 tail = {}; - if (token_it_check_and_get_lexeme(app, scratch, &it, TokenBaseKind_Comment, &tail)){ - for (i64 index = token->pos; - tail.size > 0; - tail = string_skip(tail, 1), index += 1){ - Comment_Highlight_Pair *pair = pairs; - for (i32 i = 0; i < pair_count; i += 1, pair += 1){ - u64 needle_size = pair->needle.size; - if (needle_size == 0){ - continue; - } - String_Const_u8 prefix = string_prefix(tail, needle_size); - if (string_match(prefix, pair->needle)){ - Range_i64 range = Ii64_size(index, needle_size); - paint_text_color(app, text_layout_id, range, pair->color); - tail = string_skip(tail, needle_size - 1); - index += needle_size - 1; - break; - } - } - } - } - if (!token_it_inc_non_whitespace(&it)){ - break; - } - } -} - -function Range_i64_Array -get_enclosure_ranges(Application_Links *app, Arena *arena, Buffer_ID buffer, i64 pos, u32 flags){ - Range_i64_Array array = {}; - i32 max = 100; - array.ranges = push_array(arena, Range_i64, max); - for (;;){ - Range_i64 range = {}; - if (find_surrounding_nest(app, buffer, pos, flags, &range)){ - array.ranges[array.count] = range; - array.count += 1; - pos = range.first; - if (array.count >= max){ - break; - } - } - else{ - break; - } - } - return(array); -} - -function void -draw_enclosures(Application_Links *app, Text_Layout_ID text_layout_id, Buffer_ID buffer, - i64 pos, u32 flags, Range_Highlight_Kind kind, - ARGB_Color *back_colors, i32 back_count, - ARGB_Color *fore_colors, i32 fore_count){ - Scratch_Block scratch(app); - Range_i64_Array ranges = get_enclosure_ranges(app, scratch, buffer, pos, flags); - - i32 color_index = 0; - for (i32 i = ranges.count - 1; i >= 0; i -= 1){ - Range_i64 range = ranges.ranges[i]; - if (kind == RangeHighlightKind_LineHighlight){ - Range_i64 r[2] = {}; - if (i > 0){ - Range_i64 inner_range = ranges.ranges[i - 1]; - Range_i64 lines = get_line_range_from_pos_range(app, buffer, range); - Range_i64 inner_lines = get_line_range_from_pos_range(app, buffer, inner_range); - inner_lines.min = clamp_bot(lines.min, inner_lines.min); - inner_lines.max = clamp_top(inner_lines.max, lines.max); - inner_lines.min -= 1; - inner_lines.max += 1; - if (lines.min <= inner_lines.min){ - r[0] = Ii64(lines.min, inner_lines.min); - } - if (inner_lines.max <= lines.max){ - r[1] = Ii64(inner_lines.max, lines.max); - } - } - else{ - r[0] = get_line_range_from_pos_range(app, buffer, range); - } - for (i32 j = 0; j < 2; j += 1){ - if (r[j].min == 0){ - continue; - } - Range_i64 line_range = r[j]; - if (back_colors != 0){ - i32 back_index = color_index%back_count; - draw_line_highlight(app, text_layout_id, line_range, back_colors[back_index]); - } - if (fore_colors != 0){ - i32 fore_index = color_index%fore_count; - Range_i64 pos_range = get_pos_range_from_line_range(app, buffer, line_range); - paint_text_color(app, text_layout_id, pos_range, fore_colors[fore_index]); - } - } - } - else{ - if (back_colors != 0){ - i32 back_index = color_index%back_count; - draw_character_block(app, text_layout_id, range.min, 0.f, back_colors[back_index]); - draw_character_block(app, text_layout_id, range.max - 1, 0.f, back_colors[back_index]); - } - if (fore_colors != 0){ - i32 fore_index = color_index%fore_count; - paint_text_color_pos(app, text_layout_id, range.min, fore_colors[fore_index]); - paint_text_color_pos(app, text_layout_id, range.max - 1, fore_colors[fore_index]); - } - } - color_index += 1; - } -} - -function void -draw_scope_highlight(Application_Links *app, Buffer_ID buffer, Text_Layout_ID text_layout_id, - i64 pos, ARGB_Color *colors, i32 color_count){ - draw_enclosures(app, text_layout_id, buffer, - pos, FindNest_Scope, RangeHighlightKind_LineHighlight, - colors, color_count, 0, 0); -} - -function void -draw_paren_highlight(Application_Links *app, Buffer_ID buffer, Text_Layout_ID text_layout_id, - i64 pos, ARGB_Color *colors, i32 color_count){ - Token_Array token_array = get_token_array_from_buffer(app, buffer); - if (token_array.tokens != 0){ - Token_Iterator_Array it = token_iterator_pos(0, &token_array, pos); - Token *token = token_it_read(&it); - if (token != 0 && token->kind == TokenBaseKind_ParentheticalOpen){ - pos = token->pos + token->size; - } - else{ - if (token_it_dec_all(&it)){ - token = token_it_read(&it); - if (token->kind == TokenBaseKind_ParentheticalClose && - pos == token->pos + token->size){ - pos = token->pos; - } - } - } - } - draw_enclosures(app, text_layout_id, buffer, - pos, FindNest_Paren, RangeHighlightKind_CharacterHighlight, - 0, 0, colors, color_count); -} - -function void -draw_jump_highlights(Application_Links *app, Buffer_ID buffer, Text_Layout_ID text_layout_id, - Buffer_ID jump_buffer, FColor line_color){ - Scratch_Block scratch(app); - if (jump_buffer != 0){ - Managed_Scope scopes[2]; - scopes[0] = buffer_get_managed_scope(app, jump_buffer); - scopes[1] = buffer_get_managed_scope(app, buffer); - Managed_Scope comp_scope = get_managed_scope_with_multiple_dependencies(app, scopes, ArrayCount(scopes)); - Managed_Object *markers_object = scope_attachment(app, comp_scope, sticky_jump_marker_handle, Managed_Object); - - i32 count = managed_object_get_item_count(app, *markers_object); - Marker *markers = push_array(scratch, Marker, count); - managed_object_load_data(app, *markers_object, 0, count, markers); - for (i32 i = 0; i < count; i += 1){ - i64 line_number = get_line_number_from_pos(app, buffer, markers[i].pos); - draw_line_highlight(app, text_layout_id, line_number, line_color); - } - } -} - -function b32 -draw_highlight_range(Application_Links *app, View_ID view_id, - Buffer_ID buffer, Text_Layout_ID text_layout_id, - f32 roundness){ - b32 has_highlight_range = false; - Managed_Scope scope = view_get_managed_scope(app, view_id); - Buffer_ID *highlight_buffer = scope_attachment(app, scope, view_highlight_buffer, Buffer_ID); - if (*highlight_buffer != 0){ - if (*highlight_buffer != buffer){ - view_disable_highlight_range(app, view_id); - } - else{ - has_highlight_range = true; - Managed_Object *highlight = scope_attachment(app, scope, view_highlight_range, Managed_Object); - Marker marker_range[2]; - if (managed_object_load_data(app, *highlight, 0, 2, marker_range)){ - Range_i64 range = Ii64(marker_range[0].pos, marker_range[1].pos); - draw_character_block(app, text_layout_id, range, roundness, - fcolor_id(defcolor_highlight)); - paint_text_color_fcolor(app, text_layout_id, range, - fcolor_id(defcolor_at_highlight)); - } - } - } - return(has_highlight_range); -} - -function void -draw_original_4coder_style_cursor_mark_highlight(Application_Links *app, View_ID view_id, b32 is_active_view, - Buffer_ID buffer, Text_Layout_ID text_layout_id, - f32 roundness, f32 outline_thickness){ - b32 has_highlight_range = draw_highlight_range(app, view_id, buffer, text_layout_id, roundness); - if (!has_highlight_range){ - i64 cursor_pos = view_get_cursor_pos(app, view_id); - i64 mark_pos = view_get_mark_pos(app, view_id); - if (is_active_view){ - draw_character_block(app, text_layout_id, cursor_pos, roundness, - fcolor_id(defcolor_cursor)); - paint_text_color_pos(app, text_layout_id, cursor_pos, - fcolor_id(defcolor_at_cursor)); - draw_character_wire_frame(app, text_layout_id, mark_pos, - roundness, outline_thickness, - fcolor_id(defcolor_mark)); - } - else{ - draw_character_wire_frame(app, text_layout_id, mark_pos, - roundness, outline_thickness, - fcolor_id(defcolor_mark)); - draw_character_wire_frame(app, text_layout_id, cursor_pos, - roundness, outline_thickness, - fcolor_id(defcolor_cursor)); - } - } -} - -function void -draw_notepad_style_cursor_highlight(Application_Links *app, View_ID view_id, - Buffer_ID buffer, Text_Layout_ID text_layout_id, - f32 roundness){ - b32 has_highlight_range = draw_highlight_range(app, view_id, buffer, text_layout_id, roundness); - if (!has_highlight_range){ - i64 cursor_pos = view_get_cursor_pos(app, view_id); - i64 mark_pos = view_get_mark_pos(app, view_id); - if (cursor_pos != mark_pos){ - Range_i64 range = Ii64(cursor_pos, mark_pos); - draw_character_block(app, text_layout_id, range, roundness, - fcolor_id(defcolor_highlight)); - paint_text_color_fcolor(app, text_layout_id, range, - fcolor_id(defcolor_at_highlight)); - } - draw_character_i_bar(app, text_layout_id, cursor_pos, fcolor_id(defcolor_cursor)); - } -} - -//////////////////////////////// - -function Rect_f32 -get_contained_box_near_point(Rect_f32 container, Vec2_f32 p, Vec2_f32 box_dims){ - Vec2_f32 container_dims = rect_dim(container); - box_dims.x = clamp_top(box_dims.x, container_dims.x); - box_dims.y = clamp_top(box_dims.y, container_dims.y); - Vec2_f32 q = p + V2f32(-20.f, 22.f); - if (q.x + box_dims.x > container.x1){ - q.x = container.x1 - box_dims.x; - } - if (q.y + box_dims.y > container.y1){ - q.y = p.y - box_dims.y - 2.f; - if (q.y < container.y0){ - q.y = (container.y0 + container.y1 - box_dims.y)*0.5f; - } - } - return(Rf32_xy_wh(q, box_dims)); -} - -function Rect_f32 -draw_tool_tip(Application_Links *app, Face_ID face, Fancy_Block *block, - Vec2_f32 p, Rect_f32 region, f32 x_padding, f32 x_half_padding, - FColor back_color){ - Rect_f32 box = Rf32(p, p); - if (block->line_count > 0){ - Vec2_f32 dims = get_fancy_block_dim(app, face, block); - dims += V2f32(x_padding, 2.f); - box = get_contained_box_near_point(region, p, dims); - box.x0 = f32_round32(box.x0); - box.y0 = f32_round32(box.y0); - box.x1 = f32_round32(box.x1); - box.y1 = f32_round32(box.y1); - Rect_f32 prev_clip = draw_set_clip(app, box); - draw_rectangle_fcolor(app, box, 6.f, back_color); - draw_fancy_block(app, face, fcolor_zero(), block, - box.p0 + V2f32(x_half_padding, 1.f)); - draw_set_clip(app, prev_clip); - } - return(box); -} - -function Rect_f32 -draw_drop_down(Application_Links *app, Face_ID face, Fancy_Block *block, - Vec2_f32 p, Rect_f32 region, f32 x_padding, f32 x_half_padding, - FColor outline_color, FColor back_color){ - Rect_f32 box = Rf32(p, p); - if (block->line_count > 0){ - Vec2_f32 dims = get_fancy_block_dim(app, face, block); - dims += V2f32(x_padding, 4.f); - box = get_contained_box_near_point(region, p, dims); - box.x0 = f32_round32(box.x0); - box.y0 = f32_round32(box.y0); - box.x1 = f32_round32(box.x1); - box.y1 = f32_round32(box.y1); - Rect_f32 prev_clip = draw_set_clip(app, box); - draw_rectangle_fcolor(app, box, 0.f, back_color); - draw_margin(app, box, rect_inner(box, 1.f), outline_color); - draw_fancy_block(app, face, fcolor_zero(), block, - box.p0 + V2f32(x_half_padding, 2.f)); - draw_set_clip(app, prev_clip); - } - return(box); -} - -function b32 -draw_button(Application_Links *app, Rect_f32 rect, Vec2_f32 mouse_p, Face_ID face, String_Const_u8 text){ - b32 hovered = false; - if (rect_contains_point(rect, mouse_p)){ - hovered = true; - } - - FColor margin_color = get_margin_color(hovered?UIHighlight_Active:UIHighlight_None); - draw_rectangle_fcolor(app, rect, 3.f, margin_color); - rect = rect_inner(rect, 3.f); - draw_rectangle_fcolor(app, rect, 3.f, fcolor_id(defcolor_back)); - - Scratch_Block scratch(app); - Fancy_String *fancy = push_fancy_string(scratch, 0, face, fcolor_id(defcolor_text_default), text); - Vec2_f32 dim = get_fancy_string_dim(app, 0, fancy); - Vec2_f32 p = (rect.p0 + rect.p1 - dim)*0.5f; - draw_fancy_string(app, fancy, p); - - return(hovered); -} - -// BOTTOM - +/* +4coder_draw.cpp - Layout and rendering implementation of standard UI pieces (including buffers) +*/ + +// TOP + +function void +draw_text_layout_default(Application_Links *app, Text_Layout_ID layout_id){ + ARGB_Color special_color = finalize_color(defcolor_special_character, 0); + ARGB_Color ghost_color = finalize_color(defcolor_ghost_character, 0); + draw_text_layout(app, layout_id, special_color, ghost_color); +} + +function FColor +get_margin_color(i32 level){ + FColor margin = fcolor_zero(); + switch (level){ + default: + case UIHighlight_None: + { + margin = fcolor_id(defcolor_list_item); + }break; + case UIHighlight_Hover: + { + margin = fcolor_id(defcolor_list_item_hover); + }break; + case UIHighlight_Active: + { + margin = fcolor_id(defcolor_list_item_active); + }break; + } + return(margin); +} + +function Vec2_f32 +draw_string(Application_Links *app, Face_ID font_id, String_Const_u8 string, Vec2_f32 p, ARGB_Color color){ + return(draw_string_oriented(app, font_id, color, string, p, 0, V2f32(1.f, 0.f))); +} + +function Vec2_f32 +draw_string(Application_Links *app, Face_ID font_id, String_Const_u8 string, Vec2_f32 p, FColor color){ + ARGB_Color argb = fcolor_resolve(color); + return(draw_string(app, font_id, string, p, argb)); +} + +function void +draw_rectangle_fcolor(Application_Links *app, Rect_f32 rect, f32 roundness, FColor color){ + ARGB_Color argb = fcolor_resolve(color); + draw_rectangle(app, rect, roundness, argb); +} + +function void +draw_rectangle_outline_fcolor(Application_Links *app, Rect_f32 rect, f32 roundness, f32 thickness, FColor color){ + ARGB_Color argb = fcolor_resolve(color); + draw_rectangle_outline(app, rect, roundness, thickness, argb); +} + +function void +draw_margin(Application_Links *app, Rect_f32 outer, Rect_f32 inner, ARGB_Color color){ + draw_rectangle(app, Rf32(outer.x0, outer.y0, outer.x1, inner.y0), 0.f, color); + draw_rectangle(app, Rf32(outer.x0, inner.y1, outer.x1, outer.y1), 0.f, color); + draw_rectangle(app, Rf32(outer.x0, inner.y0, inner.x0, inner.y1), 0.f, color); + draw_rectangle(app, Rf32(inner.x1, inner.y0, outer.x1, inner.y1), 0.f, color); +} + +function void +draw_margin(Application_Links *app, Rect_f32 outer, Rect_f32 inner, FColor color){ + ARGB_Color argb = fcolor_resolve(color); + draw_margin(app, outer, inner, argb); +} + +function void +draw_character_block(Application_Links *app, Text_Layout_ID layout, i64 pos, f32 roundness, ARGB_Color color){ + Rect_f32 rect = text_layout_character_on_screen(app, layout, pos); + draw_rectangle(app, rect, roundness, color); +} + +function void +draw_character_block(Application_Links *app, Text_Layout_ID layout, i64 pos, f32 roundness, FColor color){ + ARGB_Color argb = fcolor_resolve(color); + draw_character_block(app, layout, pos, roundness, argb); +} + +function void +draw_character_block(Application_Links *app, Text_Layout_ID layout, Range_i64 range, f32 roundness, ARGB_Color color){ + if (range.first < range.one_past_last){ + i64 i = range.first; + Rect_f32 first_rect = text_layout_character_on_screen(app, layout, i); + i += 1; + Range_f32 y = rect_range_y(first_rect); + Range_f32 x = rect_range_x(first_rect); + for (;i < range.one_past_last; i += 1){ + Rect_f32 rect = text_layout_character_on_screen(app, layout, i); + if (rect.x0 < rect.x1 && rect.y0 < rect.y1){ + Range_f32 new_y = rect_range_y(rect); + Range_f32 new_x = rect_range_x(rect); + b32 joinable = false; + if (new_y == y && (range_overlap(x, new_x) || x.max == new_x.min || new_x.max == x.min)){ + joinable = true; + } + + if (!joinable){ + draw_rectangle(app, Rf32(x, y), roundness, color); + y = new_y; + x = new_x; + } + else{ + x = range_union(x, new_x); + } + } + } + draw_rectangle(app, Rf32(x, y), roundness, color); + } + for (i64 i = range.first; i < range.one_past_last; i += 1){ + draw_character_block(app, layout, i, roundness, color); + } +} + +function void +draw_character_block(Application_Links *app, Text_Layout_ID layout, Range_i64 range, f32 roundness, FColor color){ + ARGB_Color argb = fcolor_resolve(color); + draw_character_block(app, layout, range, roundness, argb); +} + +function void +draw_character_wire_frame(Application_Links *app, Text_Layout_ID layout, i64 pos, f32 roundness, f32 thickness, ARGB_Color color){ + Rect_f32 rect = text_layout_character_on_screen(app, layout, pos); + draw_rectangle_outline(app, rect, roundness, thickness, color); +} + +function void +draw_character_wire_frame(Application_Links *app, Text_Layout_ID layout, i64 pos, f32 roundness, f32 thickness, FColor color){ + ARGB_Color argb = fcolor_resolve(color); + draw_character_wire_frame(app, layout, pos, roundness, thickness, argb); +} + +function void +draw_character_wire_frame(Application_Links *app, Text_Layout_ID layout, Range_i64 range, f32 roundness, f32 thickness, FColor color){ + for (i64 i = range.first; i < range.one_past_last; i += 1){ + draw_character_wire_frame(app, layout, i, roundness, thickness, color); + } +} + +function void +draw_character_i_bar(Application_Links *app, Text_Layout_ID layout, i64 pos, ARGB_Color color){ + Rect_f32 rect = text_layout_character_on_screen(app, layout, pos); + rect.x1 = rect.x0 + 1.f; + draw_rectangle(app, rect, 0.f, color); +} + +function void +draw_character_i_bar(Application_Links *app, Text_Layout_ID layout, i64 pos, FColor color){ + ARGB_Color argb = fcolor_resolve(color); + draw_character_i_bar(app, layout, pos, argb); +} + +function void +draw_line_highlight(Application_Links *app, Text_Layout_ID layout, Range_i64 line_range, ARGB_Color color){ + Range_f32 y1 = text_layout_line_on_screen(app, layout, line_range.min); + Range_f32 y2 = text_layout_line_on_screen(app, layout, line_range.max); + Range_f32 y = range_union(y1, y2); + if (range_size(y) > 0.f){ + Rect_f32 region = text_layout_region(app, layout); + draw_rectangle(app, Rf32(rect_range_x(region), y), 0.f, color); + } +} + +function void +draw_line_highlight(Application_Links *app, Text_Layout_ID layout, Range_i64 line_range, FColor color){ + ARGB_Color argb = fcolor_resolve(color); + draw_line_highlight(app, layout, line_range, argb); +} + +function void +draw_line_highlight(Application_Links *app, Text_Layout_ID layout, i64 line, ARGB_Color color){ + draw_line_highlight(app, layout, Ii64(line), color); +} + +function void +draw_line_highlight(Application_Links *app, Text_Layout_ID layout, i64 line, FColor color){ + draw_line_highlight(app, layout, Ii64(line), color); +} + +function void +paint_text_color_fcolor(Application_Links *app, Text_Layout_ID layout, Range_i64 pos, FColor color){ + ARGB_Color argb = fcolor_resolve(color); + paint_text_color(app, layout, pos, argb); +} + +function void +paint_text_color_pos(Application_Links *app, Text_Layout_ID layout, i64 pos, ARGB_Color color){ + paint_text_color(app, layout, Ii64(pos, pos + 1), color); +} + +function void +paint_text_color_pos(Application_Links *app, Text_Layout_ID layout, i64 pos, FColor color){ + ARGB_Color argb = fcolor_resolve(color); + paint_text_color_pos(app, layout, pos, argb); +} + +//////////////////////////////// + +function Rect_f32_Pair +layout_file_bar_on_top(Rect_f32 rect, f32 line_height){ + return(rect_split_top_bottom(rect, line_height + 2.f)); +} + +function Rect_f32_Pair +layout_file_bar_on_bot(Rect_f32 rect, f32 line_height){ + return(rect_split_top_bottom_neg(rect, line_height + 2.f)); +} + +function Rect_f32_Pair +layout_query_bar_on_top(Rect_f32 rect, f32 line_height, i32 bar_count){ + return(rect_split_top_bottom(rect, (line_height + 2.f)*bar_count)); +} + +function Rect_f32_Pair +layout_query_bar_on_bot(Rect_f32 rect, f32 line_height, i32 bar_count){ + return(rect_split_top_bottom_neg(rect, (line_height + 2.f)*bar_count)); +} + +function Rect_f32_Pair +layout_line_number_margin(Rect_f32 rect, f32 digit_advance, i64 digit_count){ + f32 margin_width = (f32)digit_count*digit_advance + 2.f; + return(rect_split_left_right(rect, margin_width)); +} + +function Rect_f32_Pair +layout_line_number_margin(Application_Links *app, Buffer_ID buffer, Rect_f32 rect, f32 digit_advance){ + i64 line_count = buffer_get_line_count(app, buffer); + i64 line_count_digit_count = digit_count_from_integer(line_count, 10); + return(layout_line_number_margin(rect, digit_advance, line_count_digit_count)); +} + +global_const i32 fps_history_depth = 10; +function Rect_f32_Pair +layout_fps_hud_on_bottom(Rect_f32 rect, f32 line_height){ + return(rect_split_top_bottom_neg(rect, line_height*fps_history_depth)); +} + +function Rect_f32 +draw_background_and_margin(Application_Links *app, View_ID view, ARGB_Color margin, ARGB_Color back){ + Rect_f32 view_rect = view_get_screen_rect(app, view); + Rect_f32 inner = rect_inner(view_rect, 3.f); + draw_rectangle(app, inner, 0.f, back); + draw_margin(app, view_rect, inner, margin); + return(inner); +} + +function Rect_f32 +draw_background_and_margin(Application_Links *app, View_ID view, FColor margin, FColor back){ + ARGB_Color margin_argb = fcolor_resolve(margin); + ARGB_Color back_argb = fcolor_resolve(back); + return(draw_background_and_margin(app, view, margin_argb, back_argb)); +} + +function Rect_f32 +draw_background_and_margin(Application_Links *app, View_ID view, b32 is_active_view){ + FColor margin_color = get_margin_color(is_active_view?UIHighlight_Active:UIHighlight_None); + return(draw_background_and_margin(app, view, margin_color, fcolor_id(defcolor_back))); +} + +function Rect_f32 +draw_background_and_margin(Application_Links *app, View_ID view){ + View_ID active_view = get_active_view(app, Access_Always); + b32 is_active_view = (active_view == view); + return(draw_background_and_margin(app, view, is_active_view)); +} + +function void +draw_file_bar(Application_Links *app, View_ID view_id, Buffer_ID buffer, Face_ID face_id, Rect_f32 bar){ + Scratch_Block scratch(app); + + draw_rectangle_fcolor(app, bar, 0.f, fcolor_id(defcolor_bar)); + + FColor base_color = fcolor_id(defcolor_base); + FColor pop2_color = fcolor_id(defcolor_pop2); + + i64 cursor_position = view_get_cursor_pos(app, view_id); + Buffer_Cursor cursor = view_compute_cursor(app, view_id, seek_pos(cursor_position)); + + Fancy_Line list = {}; + String_Const_u8 unique_name = push_buffer_unique_name(app, scratch, buffer); + push_fancy_string(scratch, &list, base_color, unique_name); + push_fancy_stringf(scratch, &list, base_color, " - Row: %3.lld Col: %3.lld -", cursor.line, cursor.col); + + Managed_Scope scope = buffer_get_managed_scope(app, buffer); + Line_Ending_Kind *eol_setting = scope_attachment(app, scope, buffer_eol_setting, + Line_Ending_Kind); + switch (*eol_setting){ + case LineEndingKind_Binary: + { + push_fancy_string(scratch, &list, base_color, string_u8_litexpr(" bin")); + }break; + + case LineEndingKind_LF: + { + push_fancy_string(scratch, &list, base_color, string_u8_litexpr(" lf")); + }break; + + case LineEndingKind_CRLF: + { + push_fancy_string(scratch, &list, base_color, string_u8_litexpr(" crlf")); + }break; + } + + { + Dirty_State dirty = buffer_get_dirty_state(app, buffer); + u8 space[3]; + String_u8 str = Su8(space, 0, 3); + if (dirty != 0){ + string_append(&str, string_u8_litexpr(" ")); + } + if (HasFlag(dirty, DirtyState_UnsavedChanges)){ + string_append(&str, string_u8_litexpr("*")); + } + if (HasFlag(dirty, DirtyState_UnloadedChanges)){ + string_append(&str, string_u8_litexpr("!")); + } + push_fancy_string(scratch, &list, pop2_color, str.string); + } + + Vec2_f32 p = bar.p0 + V2f32(2.f, 2.f); + draw_fancy_line(app, face_id, fcolor_zero(), &list, p); +} + +function void +draw_query_bar(Application_Links *app, Query_Bar *query_bar, Face_ID face_id, Rect_f32 bar){ + Scratch_Block scratch(app); + Fancy_Line list = {}; + push_fancy_string(scratch, &list, fcolor_id(defcolor_pop1) , query_bar->prompt); + push_fancy_string(scratch, &list, fcolor_id(defcolor_text_default), query_bar->string); + Vec2_f32 p = bar.p0 + V2f32(2.f, 2.f); + draw_fancy_line(app, face_id, fcolor_zero(), &list, p); +} + +function void +draw_line_number_margin(Application_Links *app, View_ID view_id, Buffer_ID buffer, Face_ID face_id, Text_Layout_ID text_layout_id, Rect_f32 margin){ + Rect_f32 prev_clip = draw_set_clip(app, margin); + draw_rectangle_fcolor(app, margin, 0.f, fcolor_id(defcolor_line_numbers_back)); + + Range_i64 visible_range = text_layout_get_visible_range(app, text_layout_id); + + FColor line_color = fcolor_id(defcolor_line_numbers_text); + + i64 line_count = buffer_get_line_count(app, buffer); + i64 line_count_digit_count = digit_count_from_integer(line_count, 10); + + Scratch_Block scratch(app, Scratch_Share); + + Buffer_Cursor cursor = view_compute_cursor(app, view_id, seek_pos(visible_range.first)); + i64 line_number = cursor.line; + for (;cursor.pos <= visible_range.one_past_last;){ + if (line_number > line_count){ + break; + } + Range_f32 line_y = text_layout_line_on_screen(app, text_layout_id, line_number); + Vec2_f32 p = V2f32(margin.x0, line_y.min); + Temp_Memory_Block temp(scratch); + Fancy_String *string = push_fancy_stringf(scratch, 0, line_color, + "%*lld", + line_count_digit_count, + line_number); + draw_fancy_string(app, face_id, fcolor_zero(), string, p); + line_number += 1; + } + + draw_set_clip(app, prev_clip); +} + +function void +draw_fps_hud(Application_Links *app, Frame_Info frame_info, + Face_ID face_id, Rect_f32 rect){ + Face_Metrics face_metrics = get_face_metrics(app, face_id); + f32 line_height = face_metrics.line_height; + + local_persist f32 history_literal_dt[fps_history_depth] = {}; + local_persist f32 history_animation_dt[fps_history_depth] = {}; + local_persist i32 history_frame_index[fps_history_depth] = {}; + + i32 wrapped_index = frame_info.index%fps_history_depth; + history_literal_dt[wrapped_index] = frame_info.literal_dt; + history_animation_dt[wrapped_index] = frame_info.animation_dt; + history_frame_index[wrapped_index] = frame_info.index; + + draw_rectangle_fcolor(app, rect, 0.f, f_black); + draw_rectangle_outline_fcolor(app, rect, 0.f, 1.f, f_white); + + Vec2_f32 p = rect.p0; + + Scratch_Block scratch(app); + + Range_i32 ranges[2] = {}; + ranges[0].first = wrapped_index; + ranges[0].one_past_last = -1; + ranges[1].first = fps_history_depth - 1; + ranges[1].one_past_last = wrapped_index; + for (i32 i = 0; i < 2; i += 1){ + Range_i32 r = ranges[i]; + for (i32 j = r.first; j > r.one_past_last; j -= 1, p.y += line_height){ + f32 dts[2]; + dts[0] = history_literal_dt[j]; + dts[1] = history_animation_dt[j]; + i32 frame_index = history_frame_index[j]; + + Fancy_Line list = {}; + push_fancy_stringf(scratch, &list, f_pink , "FPS: "); + push_fancy_stringf(scratch, &list, f_green, "["); + push_fancy_stringf(scratch, &list, f_white, "%5d", frame_index); + push_fancy_stringf(scratch, &list, f_green, "]: "); + + for (i32 k = 0; k < 2; k += 1){ + f32 dt = dts[k]; + if (dt == 0.f){ + push_fancy_stringf(scratch, &list, f_white, "----------"); + } + else{ + push_fancy_stringf(scratch, &list, f_white, "%10.6f", dt); + } + push_fancy_stringf(scratch, &list, f_green, " | "); + } + + draw_fancy_line(app, face_id, fcolor_zero(), &list, p); + } + } +} + +function FColor +get_token_color_cpp(Token token){ + Managed_ID color = defcolor_text_default; + switch (token.kind){ + case TokenBaseKind_Preprocessor: + { + color = defcolor_preproc; + }break; + case TokenBaseKind_Keyword: + { + color = defcolor_keyword; + }break; + case TokenBaseKind_Comment: + { + color = defcolor_comment; + }break; + case TokenBaseKind_LiteralString: + { + color = defcolor_str_constant; + }break; + case TokenBaseKind_LiteralInteger: + { + color = defcolor_int_constant; + }break; + case TokenBaseKind_LiteralFloat: + { + color = defcolor_float_constant; + }break; + default: + { + switch (token.sub_kind){ + case TokenCppKind_LiteralTrue: + case TokenCppKind_LiteralFalse: + { + color = defcolor_bool_constant; + }break; + case TokenCppKind_LiteralCharacter: + case TokenCppKind_LiteralCharacterWide: + case TokenCppKind_LiteralCharacterUTF8: + case TokenCppKind_LiteralCharacterUTF16: + case TokenCppKind_LiteralCharacterUTF32: + { + color = defcolor_char_constant; + }break; + case TokenCppKind_PPIncludeFile: + { + color = defcolor_include; + }break; + } + }break; + } + return(fcolor_id(color)); +} + +function void +draw_cpp_token_colors(Application_Links *app, Text_Layout_ID text_layout_id, Token_Array *array){ + Range_i64 visible_range = text_layout_get_visible_range(app, text_layout_id); + i64 first_index = token_index_from_pos(array, visible_range.first); + Token_Iterator_Array it = token_iterator_index(0, array, first_index); + for (;;){ + Token *token = token_it_read(&it); + if (token->pos >= visible_range.one_past_last){ + break; + } + FColor color = get_token_color_cpp(*token); + ARGB_Color argb = fcolor_resolve(color); + paint_text_color(app, text_layout_id, Ii64_size(token->pos, token->size), argb); + if (!token_it_inc_all(&it)){ + break; + } + } +} + +function void +draw_comment_highlights(Application_Links *app, Buffer_ID buffer, Text_Layout_ID text_layout_id, + Token_Array *array, Comment_Highlight_Pair *pairs, i32 pair_count){ + Scratch_Block scratch(app); + Range_i64 visible_range = text_layout_get_visible_range(app, text_layout_id); + i64 first_index = token_index_from_pos(array, visible_range.first); + Token_Iterator_Array it = token_iterator_index(buffer, array, first_index); + for (;;){ + Temp_Memory_Block temp(scratch); + Token *token = token_it_read(&it); + if (token->pos >= visible_range.one_past_last){ + break; + } + String_Const_u8 tail = {}; + if (token_it_check_and_get_lexeme(app, scratch, &it, TokenBaseKind_Comment, &tail)){ + for (i64 index = token->pos; + tail.size > 0; + tail = string_skip(tail, 1), index += 1){ + Comment_Highlight_Pair *pair = pairs; + for (i32 i = 0; i < pair_count; i += 1, pair += 1){ + u64 needle_size = pair->needle.size; + if (needle_size == 0){ + continue; + } + String_Const_u8 prefix = string_prefix(tail, needle_size); + if (string_match(prefix, pair->needle)){ + Range_i64 range = Ii64_size(index, needle_size); + paint_text_color(app, text_layout_id, range, pair->color); + tail = string_skip(tail, needle_size - 1); + index += needle_size - 1; + break; + } + } + } + } + if (!token_it_inc_non_whitespace(&it)){ + break; + } + } +} + +function Range_i64_Array +get_enclosure_ranges(Application_Links *app, Arena *arena, Buffer_ID buffer, i64 pos, u32 flags){ + Range_i64_Array array = {}; + i32 max = 100; + array.ranges = push_array(arena, Range_i64, max); + for (;;){ + Range_i64 range = {}; + if (find_surrounding_nest(app, buffer, pos, flags, &range)){ + array.ranges[array.count] = range; + array.count += 1; + pos = range.first; + if (array.count >= max){ + break; + } + } + else{ + break; + } + } + return(array); +} + +function void +draw_enclosures(Application_Links *app, Text_Layout_ID text_layout_id, Buffer_ID buffer, + i64 pos, u32 flags, Range_Highlight_Kind kind, + ARGB_Color *back_colors, i32 back_count, + ARGB_Color *fore_colors, i32 fore_count){ + Scratch_Block scratch(app); + Range_i64_Array ranges = get_enclosure_ranges(app, scratch, buffer, pos, flags); + + i32 color_index = 0; + for (i32 i = ranges.count - 1; i >= 0; i -= 1){ + Range_i64 range = ranges.ranges[i]; + if (kind == RangeHighlightKind_LineHighlight){ + Range_i64 r[2] = {}; + if (i > 0){ + Range_i64 inner_range = ranges.ranges[i - 1]; + Range_i64 lines = get_line_range_from_pos_range(app, buffer, range); + Range_i64 inner_lines = get_line_range_from_pos_range(app, buffer, inner_range); + inner_lines.min = clamp_bot(lines.min, inner_lines.min); + inner_lines.max = clamp_top(inner_lines.max, lines.max); + inner_lines.min -= 1; + inner_lines.max += 1; + if (lines.min <= inner_lines.min){ + r[0] = Ii64(lines.min, inner_lines.min); + } + if (inner_lines.max <= lines.max){ + r[1] = Ii64(inner_lines.max, lines.max); + } + } + else{ + r[0] = get_line_range_from_pos_range(app, buffer, range); + } + for (i32 j = 0; j < 2; j += 1){ + if (r[j].min == 0){ + continue; + } + Range_i64 line_range = r[j]; + if (back_colors != 0){ + i32 back_index = color_index%back_count; + draw_line_highlight(app, text_layout_id, line_range, back_colors[back_index]); + } + if (fore_colors != 0){ + i32 fore_index = color_index%fore_count; + Range_i64 pos_range = get_pos_range_from_line_range(app, buffer, line_range); + paint_text_color(app, text_layout_id, pos_range, fore_colors[fore_index]); + } + } + } + else{ + if (back_colors != 0){ + i32 back_index = color_index%back_count; + draw_character_block(app, text_layout_id, range.min, 0.f, back_colors[back_index]); + draw_character_block(app, text_layout_id, range.max - 1, 0.f, back_colors[back_index]); + } + if (fore_colors != 0){ + i32 fore_index = color_index%fore_count; + paint_text_color_pos(app, text_layout_id, range.min, fore_colors[fore_index]); + paint_text_color_pos(app, text_layout_id, range.max - 1, fore_colors[fore_index]); + } + } + color_index += 1; + } +} + +function void +draw_scope_highlight(Application_Links *app, Buffer_ID buffer, Text_Layout_ID text_layout_id, + i64 pos, ARGB_Color *colors, i32 color_count){ + draw_enclosures(app, text_layout_id, buffer, + pos, FindNest_Scope, RangeHighlightKind_LineHighlight, + colors, color_count, 0, 0); +} + +function void +draw_paren_highlight(Application_Links *app, Buffer_ID buffer, Text_Layout_ID text_layout_id, + i64 pos, ARGB_Color *colors, i32 color_count){ + Token_Array token_array = get_token_array_from_buffer(app, buffer); + if (token_array.tokens != 0){ + Token_Iterator_Array it = token_iterator_pos(0, &token_array, pos); + Token *token = token_it_read(&it); + if (token != 0 && token->kind == TokenBaseKind_ParentheticalOpen){ + pos = token->pos + token->size; + } + else{ + if (token_it_dec_all(&it)){ + token = token_it_read(&it); + if (token->kind == TokenBaseKind_ParentheticalClose && + pos == token->pos + token->size){ + pos = token->pos; + } + } + } + } + draw_enclosures(app, text_layout_id, buffer, + pos, FindNest_Paren, RangeHighlightKind_CharacterHighlight, + 0, 0, colors, color_count); +} + +function void +draw_jump_highlights(Application_Links *app, Buffer_ID buffer, Text_Layout_ID text_layout_id, + Buffer_ID jump_buffer, FColor line_color){ + Scratch_Block scratch(app); + if (jump_buffer != 0){ + Managed_Scope scopes[2]; + scopes[0] = buffer_get_managed_scope(app, jump_buffer); + scopes[1] = buffer_get_managed_scope(app, buffer); + Managed_Scope comp_scope = get_managed_scope_with_multiple_dependencies(app, scopes, ArrayCount(scopes)); + Managed_Object *markers_object = scope_attachment(app, comp_scope, sticky_jump_marker_handle, Managed_Object); + + i32 count = managed_object_get_item_count(app, *markers_object); + Marker *markers = push_array(scratch, Marker, count); + managed_object_load_data(app, *markers_object, 0, count, markers); + for (i32 i = 0; i < count; i += 1){ + i64 line_number = get_line_number_from_pos(app, buffer, markers[i].pos); + draw_line_highlight(app, text_layout_id, line_number, line_color); + } + } +} + +function b32 +draw_highlight_range(Application_Links *app, View_ID view_id, + Buffer_ID buffer, Text_Layout_ID text_layout_id, + f32 roundness){ + b32 has_highlight_range = false; + Managed_Scope scope = view_get_managed_scope(app, view_id); + Buffer_ID *highlight_buffer = scope_attachment(app, scope, view_highlight_buffer, Buffer_ID); + if (*highlight_buffer != 0){ + if (*highlight_buffer != buffer){ + view_disable_highlight_range(app, view_id); + } + else{ + has_highlight_range = true; + Managed_Object *highlight = scope_attachment(app, scope, view_highlight_range, Managed_Object); + Marker marker_range[2]; + if (managed_object_load_data(app, *highlight, 0, 2, marker_range)){ + Range_i64 range = Ii64(marker_range[0].pos, marker_range[1].pos); + draw_character_block(app, text_layout_id, range, roundness, + fcolor_id(defcolor_highlight)); + paint_text_color_fcolor(app, text_layout_id, range, + fcolor_id(defcolor_at_highlight)); + } + } + } + return(has_highlight_range); +} + +function void +draw_original_4coder_style_cursor_mark_highlight(Application_Links *app, View_ID view_id, b32 is_active_view, + Buffer_ID buffer, Text_Layout_ID text_layout_id, + f32 roundness, f32 outline_thickness){ + b32 has_highlight_range = draw_highlight_range(app, view_id, buffer, text_layout_id, roundness); + if (!has_highlight_range){ + i64 cursor_pos = view_get_cursor_pos(app, view_id); + i64 mark_pos = view_get_mark_pos(app, view_id); + if (is_active_view){ + draw_character_block(app, text_layout_id, cursor_pos, roundness, + fcolor_id(defcolor_cursor)); + paint_text_color_pos(app, text_layout_id, cursor_pos, + fcolor_id(defcolor_at_cursor)); + draw_character_wire_frame(app, text_layout_id, mark_pos, + roundness, outline_thickness, + fcolor_id(defcolor_mark)); + } + else{ + draw_character_wire_frame(app, text_layout_id, mark_pos, + roundness, outline_thickness, + fcolor_id(defcolor_mark)); + draw_character_wire_frame(app, text_layout_id, cursor_pos, + roundness, outline_thickness, + fcolor_id(defcolor_cursor)); + } + } +} + +function void +draw_notepad_style_cursor_highlight(Application_Links *app, View_ID view_id, + Buffer_ID buffer, Text_Layout_ID text_layout_id, + f32 roundness){ + b32 has_highlight_range = draw_highlight_range(app, view_id, buffer, text_layout_id, roundness); + if (!has_highlight_range){ + i64 cursor_pos = view_get_cursor_pos(app, view_id); + i64 mark_pos = view_get_mark_pos(app, view_id); + if (cursor_pos != mark_pos){ + Range_i64 range = Ii64(cursor_pos, mark_pos); + draw_character_block(app, text_layout_id, range, roundness, + fcolor_id(defcolor_highlight)); + paint_text_color_fcolor(app, text_layout_id, range, + fcolor_id(defcolor_at_highlight)); + } + draw_character_i_bar(app, text_layout_id, cursor_pos, fcolor_id(defcolor_cursor)); + } +} + +//////////////////////////////// + +function Rect_f32 +get_contained_box_near_point(Rect_f32 container, Vec2_f32 p, Vec2_f32 box_dims){ + Vec2_f32 container_dims = rect_dim(container); + box_dims.x = clamp_top(box_dims.x, container_dims.x); + box_dims.y = clamp_top(box_dims.y, container_dims.y); + Vec2_f32 q = p + V2f32(-20.f, 22.f); + if (q.x + box_dims.x > container.x1){ + q.x = container.x1 - box_dims.x; + } + if (q.y + box_dims.y > container.y1){ + q.y = p.y - box_dims.y - 2.f; + if (q.y < container.y0){ + q.y = (container.y0 + container.y1 - box_dims.y)*0.5f; + } + } + return(Rf32_xy_wh(q, box_dims)); +} + +function Rect_f32 +draw_tool_tip(Application_Links *app, Face_ID face, Fancy_Block *block, + Vec2_f32 p, Rect_f32 region, f32 x_padding, f32 x_half_padding, + FColor back_color){ + Rect_f32 box = Rf32(p, p); + if (block->line_count > 0){ + Vec2_f32 dims = get_fancy_block_dim(app, face, block); + dims += V2f32(x_padding, 2.f); + box = get_contained_box_near_point(region, p, dims); + box.x0 = f32_round32(box.x0); + box.y0 = f32_round32(box.y0); + box.x1 = f32_round32(box.x1); + box.y1 = f32_round32(box.y1); + Rect_f32 prev_clip = draw_set_clip(app, box); + draw_rectangle_fcolor(app, box, 6.f, back_color); + draw_fancy_block(app, face, fcolor_zero(), block, + box.p0 + V2f32(x_half_padding, 1.f)); + draw_set_clip(app, prev_clip); + } + return(box); +} + +function Rect_f32 +draw_drop_down(Application_Links *app, Face_ID face, Fancy_Block *block, + Vec2_f32 p, Rect_f32 region, f32 x_padding, f32 x_half_padding, + FColor outline_color, FColor back_color){ + Rect_f32 box = Rf32(p, p); + if (block->line_count > 0){ + Vec2_f32 dims = get_fancy_block_dim(app, face, block); + dims += V2f32(x_padding, 4.f); + box = get_contained_box_near_point(region, p, dims); + box.x0 = f32_round32(box.x0); + box.y0 = f32_round32(box.y0); + box.x1 = f32_round32(box.x1); + box.y1 = f32_round32(box.y1); + Rect_f32 prev_clip = draw_set_clip(app, box); + draw_rectangle_fcolor(app, box, 0.f, back_color); + draw_margin(app, box, rect_inner(box, 1.f), outline_color); + draw_fancy_block(app, face, fcolor_zero(), block, + box.p0 + V2f32(x_half_padding, 2.f)); + draw_set_clip(app, prev_clip); + } + return(box); +} + +function b32 +draw_button(Application_Links *app, Rect_f32 rect, Vec2_f32 mouse_p, Face_ID face, String_Const_u8 text){ + b32 hovered = false; + if (rect_contains_point(rect, mouse_p)){ + hovered = true; + } + + FColor margin_color = get_margin_color(hovered?UIHighlight_Active:UIHighlight_None); + draw_rectangle_fcolor(app, rect, 3.f, margin_color); + rect = rect_inner(rect, 3.f); + draw_rectangle_fcolor(app, rect, 3.f, fcolor_id(defcolor_back)); + + Scratch_Block scratch(app); + Fancy_String *fancy = push_fancy_string(scratch, 0, face, fcolor_id(defcolor_text_default), text); + Vec2_f32 dim = get_fancy_string_dim(app, 0, fancy); + Vec2_f32 p = (rect.p0 + rect.p1 - dim)*0.5f; + draw_fancy_string(app, fancy, p); + + return(hovered); +} + +// BOTTOM + diff --git a/custom/4coder_malloc_allocator.cpp b/custom/4coder_malloc_allocator.cpp index a16b7419..8a142f86 100644 --- a/custom/4coder_malloc_allocator.cpp +++ b/custom/4coder_malloc_allocator.cpp @@ -5,7 +5,10 @@ // TOP #include -#include + +#if !OS_MAC +# include +#endif internal void* base_reserve__malloc(void *user_data, u64 size, u64 *size_out, String_Const_u8 location){ diff --git a/custom/4coder_types.h b/custom/4coder_types.h index f432316f..12d365ff 100644 --- a/custom/4coder_types.h +++ b/custom/4coder_types.h @@ -54,7 +54,7 @@ struct Color_Array{ api(custom) struct Color_Table{ - Color_Array *arrays; + Color_Array *arrays; u32 count; }; @@ -741,7 +741,7 @@ struct View_Context{ u64 delta_rule_memory_size; b32 hides_buffer; struct Mapping *mapping; - i64 map_id; + i64 map_id; }; api(custom) @@ -777,4 +777,3 @@ struct Process_State{ }; #endif - diff --git a/custom/bin/buildsuper_x64.sh b/custom/bin/buildsuper_x64.sh index 6b49d4ab..2c83d6b1 100755 --- a/custom/bin/buildsuper_x64.sh +++ b/custom/bin/buildsuper_x64.sh @@ -14,7 +14,8 @@ if [ -z "$SOURCE" ]; then SOURCE="$(readlink -f "$CODE_HOME/4coder_default_bindings.cpp")" fi -opts="-Wno-write-strings -Wno-null-dereference -Wno-comment -Wno-switch -Wno-writable-strings -g" +# NOTE(yuval): Removed -Wno-writable-strings as it is the same as -Wno-write-strings +opts="-Wno-write-strings -Wno-null-dereference -Wno-comment -Wno-switch -g" arch=-m64 preproc_file=4coder_command_metadata.i diff --git a/custom/bin/buildsuper_x86.sh b/custom/bin/buildsuper_x86.sh index 46d0ab6e..e3dde9b0 100755 --- a/custom/bin/buildsuper_x86.sh +++ b/custom/bin/buildsuper_x86.sh @@ -35,7 +35,8 @@ done PHYS_DIR=`pwd -P` SOURCE=$PHYS_DIR/$TARGET_FILE -opts="-Wno-write-strings -Wno-null-dereference -Wno-comment -Wno-switch -Wno-writable-strings -g" +# NOTE(yuval): Removed -Wno-writable-strings as it is the same as -Wno-write-strings +opts="-Wno-write-strings -Wno-null-dereference -Wno-comment -Wno-switch -g" arch=-m32 cd "$REAL_PWD" diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index db1e23b1..a6e993c2 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -251,235 +251,235 @@ i32 source_name_len; i32 line_number; }; static Command_Metadata fcoder_metacmd_table[229] = { -{ PROC_LINKS(allow_mouse, 0), false, "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 409 }, -{ PROC_LINKS(auto_indent_line_at_cursor, 0), false, "auto_indent_line_at_cursor", 26, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 375 }, -{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 385 }, -{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 366 }, -{ PROC_LINKS(backspace_alpha_numeric_boundary, 0), false, "backspace_alpha_numeric_boundary", 32, "Delete characters between the cursor position and the first alphanumeric boundary to the left.", 94, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 154 }, -{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 96 }, -{ PROC_LINKS(basic_change_active_panel, 0), false, "basic_change_active_panel", 25, "Change the currently active panel, moving to the panel with the next highest view_id. Will not skipe the build panel if it is open.", 132, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 613 }, -{ PROC_LINKS(build_in_build_panel, 0), false, "build_in_build_panel", 20, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. Puts the *compilation* buffer in a panel at the footer of the current view.", 230, "w:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 165 }, -{ PROC_LINKS(build_search, 0), false, "build_search", 12, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*.", 153, "w:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 128 }, -{ PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 197 }, -{ PROC_LINKS(change_active_panel, 0), false, "change_active_panel", 19, "Change the currently active panel, moving to the panel with the next highest view_id.", 85, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 284 }, -{ PROC_LINKS(change_active_panel_backwards, 0), false, "change_active_panel_backwards", 29, "Change the currently active panel, moving to the panel with the next lowest view_id.", 84, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 290 }, -{ PROC_LINKS(change_to_build_panel, 0), false, "change_to_build_panel", 21, "If the special build panel is open, makes the build panel the active panel.", 75, "w:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 186 }, -{ PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 578 }, -{ PROC_LINKS(clear_all_themes, 0), false, "clear_all_themes", 16, "Clear the theme list", 20, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 480 }, -{ PROC_LINKS(click_set_cursor, 0), false, "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 233 }, -{ PROC_LINKS(click_set_cursor_and_mark, 0), false, "click_set_cursor_and_mark", 25, "Sets the cursor position and mark to the mouse position.", 56, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 223 }, -{ PROC_LINKS(click_set_cursor_if_lbutton, 0), false, "click_set_cursor_if_lbutton", 27, "If the mouse left button is pressed, sets the cursor position to the mouse position.", 84, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 243 }, -{ PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 255 }, -{ PROC_LINKS(close_all_code, 0), false, "close_all_code", 14, "Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.", 107, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 842 }, -{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "w:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 180 }, -{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 621 }, -{ PROC_LINKS(command_documentation, 0), true, "command_documentation", 21, "Prompts the user to select a command then loads a doc buffer for that item", 74, "w:\\4ed\\code\\custom\\4coder_docs.cpp", 34, 190 }, -{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 668 }, -{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 125 }, -{ PROC_LINKS(comment_line_toggle, 0), false, "comment_line_toggle", 19, "Turns uncommented lines into commented lines and vice versa for comments starting with '//'.", 92, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 149 }, -{ PROC_LINKS(copy, 0), false, "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 19 }, -{ PROC_LINKS(cursor_mark_swap, 0), false, "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 124 }, -{ PROC_LINKS(custom_api_documentation, 0), true, "custom_api_documentation", 24, "Prompts the user to select a Custom API item then loads a doc buffer for that item", 82, "w:\\4ed\\code\\custom\\4coder_docs.cpp", 34, 175 }, -{ PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 28 }, -{ PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 684 }, -{ PROC_LINKS(default_file_externally_modified, 0), false, "default_file_externally_modified", 32, "Notes the external modification of attached files by printing a message.", 72, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1798 }, -{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 7 }, -{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 23 }, -{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 57 }, -{ PROC_LINKS(delete_alpha_numeric_boundary, 0), false, "delete_alpha_numeric_boundary", 29, "Delete characters between the cursor position and the first alphanumeric boundary to the right.", 95, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 162 }, -{ PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 79 }, -{ PROC_LINKS(delete_current_scope, 0), false, "delete_current_scope", 20, "Deletes the braces surrounding the currently selected scope. Leaves the contents within the scope.", 99, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 112 }, -{ PROC_LINKS(delete_file_query, 0), false, "delete_file_query", 17, "Deletes the file of the current buffer if 4coder has the appropriate access rights. Will ask the user for confirmation first.", 125, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1221 }, -{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1396 }, -{ PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 134 }, -{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1382 }, -{ PROC_LINKS(execute_any_cli, 0), false, "execute_any_cli", 15, "Queries for an output buffer name and system command, runs the system command as a CLI and prints the output to the specified buffer.", 133, "w:\\4ed\\code\\custom\\4coder_cli_command.cpp", 41, 22 }, -{ PROC_LINKS(execute_previous_cli, 0), false, "execute_previous_cli", 20, "If the command execute_any_cli has already been used, this will execute a CLI reusing the most recent buffer name and command.", 126, "w:\\4ed\\code\\custom\\4coder_cli_command.cpp", 41, 7 }, -{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 740 }, -{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2184 }, -{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2192 }, -{ PROC_LINKS(goto_first_jump, 0), false, "goto_first_jump", 15, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 523 }, -{ PROC_LINKS(goto_first_jump_same_panel_sticky, 0), false, "goto_first_jump_same_panel_sticky", 33, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer and views the buffer in the panel where the jump list was.", 153, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 540 }, -{ PROC_LINKS(goto_jump_at_cursor, 0), false, "goto_jump_at_cursor", 19, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 346 }, -{ PROC_LINKS(goto_jump_at_cursor_same_panel, 0), false, "goto_jump_at_cursor_same_panel", 30, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.", 167, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 373 }, -{ PROC_LINKS(goto_line, 0), false, "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 748 }, -{ PROC_LINKS(goto_next_jump, 0), false, "goto_next_jump", 14, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 462 }, -{ PROC_LINKS(goto_next_jump_no_skips, 0), false, "goto_next_jump_no_skips", 23, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 492 }, -{ PROC_LINKS(goto_prev_jump, 0), false, "goto_prev_jump", 14, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 479 }, -{ PROC_LINKS(goto_prev_jump_no_skips, 0), false, "goto_prev_jump_no_skips", 23, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 509 }, -{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 651 }, -{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 637 }, -{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 869 }, -{ PROC_LINKS(if0_off, 0), false, "if0_off", 7, "Surround the range between the cursor and mark with an '#if 0' and an '#endif'", 78, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 70 }, -{ PROC_LINKS(if_read_only_goto_position, 0), false, "if_read_only_goto_position", 26, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 562 }, -{ PROC_LINKS(if_read_only_goto_position_same_panel, 0), false, "if_read_only_goto_position_same_panel", 37, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 579 }, -{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 673 }, -{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 515 }, -{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 597 }, -{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 634 }, -{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 563 }, -{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 505 }, -{ PROC_LINKS(jump_to_definition, 0), true, "jump_to_definition", 18, "List all definitions in the code index and jump to one chosen by the user.", 74, "w:\\4ed\\code\\custom\\4coder_code_index_listers.cpp", 48, 12 }, -{ PROC_LINKS(keyboard_macro_finish_recording, 0), false, "keyboard_macro_finish_recording", 31, "Stop macro recording, do nothing if macro recording is not already started", 74, "w:\\4ed\\code\\custom\\4coder_keyboard_macro.cpp", 44, 57 }, -{ PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "w:\\4ed\\code\\custom\\4coder_keyboard_macro.cpp", 44, 80 }, -{ PROC_LINKS(keyboard_macro_start_recording, 0), false, "keyboard_macro_start_recording", 30, "Start macro recording, do nothing if macro recording is already started", 71, "w:\\4ed\\code\\custom\\4coder_keyboard_macro.cpp", 44, 44 }, -{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1542 }, -{ PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 9 }, -{ PROC_LINKS(left_adjust_view, 0), false, "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 211 }, -{ PROC_LINKS(list_all_functions_all_buffers, 0), false, "list_all_functions_all_buffers", 30, "Creates a jump list of lines from all buffers that appear to define or declare functions.", 89, "w:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 295 }, -{ PROC_LINKS(list_all_functions_all_buffers_lister, 0), false, "list_all_functions_all_buffers_lister", 37, "Creates a lister of locations that look like function definitions and declarations all buffers.", 95, "w:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 301 }, -{ PROC_LINKS(list_all_functions_current_buffer, 0), false, "list_all_functions_current_buffer", 33, "Creates a jump list of lines of the current buffer that appear to define or declare functions.", 94, "w:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 267 }, -{ PROC_LINKS(list_all_functions_current_buffer_lister, 0), false, "list_all_functions_current_buffer_lister", 40, "Creates a lister of locations that look like function definitions and declarations in the buffer.", 97, "w:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 277 }, -{ PROC_LINKS(list_all_locations, 0), false, "list_all_locations", 18, "Queries the user for a string and lists all exact case-sensitive matches found in all open buffers.", 99, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 162 }, -{ PROC_LINKS(list_all_locations_case_insensitive, 0), false, "list_all_locations_case_insensitive", 35, "Queries the user for a string and lists all exact case-insensitive matches found in all open buffers.", 101, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 174 }, -{ PROC_LINKS(list_all_locations_of_identifier, 0), false, "list_all_locations_of_identifier", 32, "Reads a token or word under the cursor and lists all exact case-sensitive mathces in all open buffers.", 102, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 186 }, -{ PROC_LINKS(list_all_locations_of_identifier_case_insensitive, 0), false, "list_all_locations_of_identifier_case_insensitive", 49, "Reads a token or word under the cursor and lists all exact case-insensitive mathces in all open buffers.", 104, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 192 }, -{ PROC_LINKS(list_all_locations_of_selection, 0), false, "list_all_locations_of_selection", 31, "Reads the string in the selected range and lists all exact case-sensitive mathces in all open buffers.", 102, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 198 }, -{ PROC_LINKS(list_all_locations_of_selection_case_insensitive, 0), false, "list_all_locations_of_selection_case_insensitive", 48, "Reads the string in the selected range and lists all exact case-insensitive mathces in all open buffers.", 104, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 204 }, -{ PROC_LINKS(list_all_locations_of_type_definition, 0), false, "list_all_locations_of_type_definition", 37, "Queries user for string, lists all locations of strings that appear to define a type whose name matches the input string.", 121, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 210 }, -{ PROC_LINKS(list_all_locations_of_type_definition_of_identifier, 0), false, "list_all_locations_of_type_definition_of_identifier", 51, "Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it.", 125, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 218 }, -{ PROC_LINKS(list_all_substring_locations, 0), false, "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 168 }, -{ PROC_LINKS(list_all_substring_locations_case_insensitive, 0), false, "list_all_substring_locations_case_insensitive", 45, "Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.", 105, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 180 }, -{ PROC_LINKS(load_project, 0), false, "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 862 }, -{ PROC_LINKS(load_themes_default_folder, 0), false, "load_themes_default_folder", 26, "Loads all the theme files in the default theme folder.", 54, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 457 }, -{ PROC_LINKS(load_themes_hot_directory, 0), false, "load_themes_hot_directory", 25, "Loads all the theme files in the current hot directory.", 55, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 469 }, -{ PROC_LINKS(make_directory_query, 0), false, "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1336 }, -{ PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 44 }, -{ PROC_LINKS(miblo_decrement_time_stamp, 0), false, "miblo_decrement_time_stamp", 26, "Decrement a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 237 }, -{ PROC_LINKS(miblo_decrement_time_stamp_minute, 0), false, "miblo_decrement_time_stamp_minute", 33, "Decrement a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 249 }, -{ PROC_LINKS(miblo_increment_basic, 0), false, "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 29 }, -{ PROC_LINKS(miblo_increment_time_stamp, 0), false, "miblo_increment_time_stamp", 26, "Increment a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 231 }, -{ PROC_LINKS(miblo_increment_time_stamp_minute, 0), false, "miblo_increment_time_stamp_minute", 33, "Increment a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 243 }, -{ PROC_LINKS(mouse_wheel_change_face_size, 0), false, "mouse_wheel_change_face_size", 28, "Reads the state of the mouse wheel and uses it to either increase or decrease the face size.", 92, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 695 }, -{ PROC_LINKS(mouse_wheel_scroll, 0), false, "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 265 }, -{ PROC_LINKS(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 338 }, -{ PROC_LINKS(move_down_10, 0), false, "move_down_10", 12, "Moves the cursor down ten lines.", 32, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 350 }, -{ PROC_LINKS(move_down_textual, 0), false, "move_down_textual", 17, "Moves down to the next line of actual text, regardless of line wrapping.", 72, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 356 }, -{ PROC_LINKS(move_down_to_blank_line, 0), false, "move_down_to_blank_line", 23, "Seeks the cursor down to the next blank line.", 45, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 409 }, -{ PROC_LINKS(move_down_to_blank_line_end, 0), false, "move_down_to_blank_line_end", 27, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 433 }, -{ PROC_LINKS(move_down_to_blank_line_skip_whitespace, 0), false, "move_down_to_blank_line_skip_whitespace", 39, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 421 }, -{ PROC_LINKS(move_left, 0), false, "move_left", 9, "Moves the cursor one character to the left.", 43, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 439 }, -{ PROC_LINKS(move_left_alpha_numeric_boundary, 0), false, "move_left_alpha_numeric_boundary", 32, "Seek left for boundary between alphanumeric characters and non-alphanumeric characters.", 87, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 516 }, -{ PROC_LINKS(move_left_alpha_numeric_or_camel_boundary, 0), false, "move_left_alpha_numeric_or_camel_boundary", 41, "Seek left for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 106, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 530 }, -{ PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 488 }, -{ PROC_LINKS(move_left_whitespace_boundary, 0), false, "move_left_whitespace_boundary", 29, "Seek left for the next boundary between whitespace and non-whitespace.", 70, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 473 }, -{ PROC_LINKS(move_left_whitespace_or_token_boundary, 0), false, "move_left_whitespace_or_token_boundary", 38, "Seek left for the next end of a token or boundary between whitespace and non-whitespace.", 88, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 502 }, -{ PROC_LINKS(move_line_down, 0), false, "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1376 }, -{ PROC_LINKS(move_line_up, 0), false, "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1370 }, -{ PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 447 }, -{ PROC_LINKS(move_right_alpha_numeric_boundary, 0), false, "move_right_alpha_numeric_boundary", 33, "Seek right for boundary between alphanumeric characters and non-alphanumeric characters.", 88, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 509 }, -{ PROC_LINKS(move_right_alpha_numeric_or_camel_boundary, 0), false, "move_right_alpha_numeric_or_camel_boundary", 42, "Seek right for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 107, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 523 }, -{ PROC_LINKS(move_right_token_boundary, 0), false, "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 481 }, -{ PROC_LINKS(move_right_whitespace_boundary, 0), false, "move_right_whitespace_boundary", 30, "Seek right for the next boundary between whitespace and non-whitespace.", 71, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 465 }, -{ PROC_LINKS(move_right_whitespace_or_token_boundary, 0), false, "move_right_whitespace_or_token_boundary", 39, "Seek right for the next end of a token or boundary between whitespace and non-whitespace.", 89, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 495 }, -{ PROC_LINKS(move_up, 0), false, "move_up", 7, "Moves the cursor up one line.", 29, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 332 }, -{ PROC_LINKS(move_up_10, 0), false, "move_up_10", 10, "Moves the cursor up ten lines.", 30, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 344 }, -{ PROC_LINKS(move_up_to_blank_line, 0), false, "move_up_to_blank_line", 21, "Seeks the cursor up to the next blank line.", 43, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 403 }, -{ PROC_LINKS(move_up_to_blank_line_end, 0), false, "move_up_to_blank_line_end", 25, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 427 }, -{ PROC_LINKS(move_up_to_blank_line_skip_whitespace, 0), false, "move_up_to_blank_line_skip_whitespace", 37, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 415 }, -{ PROC_LINKS(open_all_code, 0), false, "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 848 }, -{ PROC_LINKS(open_all_code_recursive, 0), false, "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 854 }, -{ PROC_LINKS(open_file_in_quotes, 0), false, "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1461 }, -{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1792 }, -{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 46 }, -{ PROC_LINKS(open_long_braces_break, 0), false, "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 62 }, -{ PROC_LINKS(open_long_braces_semicolon, 0), false, "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 54 }, -{ PROC_LINKS(open_matching_file_cpp, 0), false, "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1493 }, -{ PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 310 }, -{ PROC_LINKS(open_panel_vsplit, 0), false, "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 300 }, -{ PROC_LINKS(page_down, 0), false, "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 374 }, -{ PROC_LINKS(page_up, 0), false, "page_up", 7, "Scrolls the view up one view height and moves the cursor up one view height.", 76, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 366 }, -{ PROC_LINKS(paste, 0), false, "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 39 }, -{ PROC_LINKS(paste_and_indent, 0), false, "paste_and_indent", 16, "Paste from the top of clipboard and run auto-indent on the newly pasted text.", 77, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 110 }, -{ PROC_LINKS(paste_next, 0), false, "paste_next", 10, "If the previous command was paste or paste_next, replaces the paste range with the next text down on the clipboard, otherwise operates as the paste command.", 156, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 71 }, -{ PROC_LINKS(paste_next_and_indent, 0), false, "paste_next_and_indent", 21, "Paste the next item on the clipboard and run auto-indent on the newly pasted text.", 82, "w:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 117 }, -{ PROC_LINKS(place_in_scope, 0), false, "place_in_scope", 14, "Wraps the code contained in the range between cursor and mark with a new curly brace scope.", 91, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 106 }, -{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 226 }, -{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 219 }, -{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "w:\\4ed\\code\\custom\\4coder_profile.cpp", 37, 212 }, -{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "w:\\4ed\\code\\custom\\4coder_profile_inspect.cpp", 45, 886 }, -{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1289 }, -{ PROC_LINKS(project_fkey_command, 0), false, "project_fkey_command", 20, "Run an 'fkey command' configured in a project.4coder file. Determines the index of the 'fkey command' by which function key or numeric key was pressed to trigger the command.", 175, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 870 }, -{ PROC_LINKS(project_go_to_root_directory, 0), false, "project_go_to_root_directory", 28, "Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns.", 125, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 896 }, -{ PROC_LINKS(query_replace, 0), false, "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1149 }, -{ PROC_LINKS(query_replace_identifier, 0), false, "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1170 }, -{ PROC_LINKS(query_replace_selection, 0), false, "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1186 }, -{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1631 }, -{ PROC_LINKS(redo_all_buffers, 0), false, "redo_all_buffers", 16, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1716 }, -{ PROC_LINKS(rename_file_query, 0), false, "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1298 }, -{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1560 }, -{ PROC_LINKS(replace_in_all_buffers, 0), false, "replace_in_all_buffers", 22, "Queries the user for a needle and string. Replaces all occurences of needle with string in all editable buffers.", 112, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1059 }, -{ PROC_LINKS(replace_in_buffer, 0), false, "replace_in_buffer", 17, "Queries the user for a needle and string. Replaces all occurences of needle with string in the active buffer.", 109, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1050 }, -{ PROC_LINKS(replace_in_range, 0), false, "replace_in_range", 16, "Queries the user for a needle and string. Replaces all occurences of needle with string in the range between cursor and the mark in the active buffer.", 150, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1041 }, -{ PROC_LINKS(reverse_search, 0), false, "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 982 }, -{ PROC_LINKS(reverse_search_identifier, 0), false, "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 994 }, -{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1550 }, -{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 382 }, -{ PROC_LINKS(save_to_query, 0), false, "save_to_query", 13, "Queries the user for a file name and saves the contents of the current buffer, altering the buffer's name too.", 110, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1265 }, -{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 976 }, -{ PROC_LINKS(search_identifier, 0), false, "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 988 }, -{ PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2172 }, -{ PROC_LINKS(seek_beginning_of_textual_line, 0), false, "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2160 }, -{ PROC_LINKS(seek_end_of_line, 0), false, "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2178 }, -{ PROC_LINKS(seek_end_of_textual_line, 0), false, "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2166 }, -{ PROC_LINKS(select_all, 0), false, "select_all", 10, "Puts the cursor at the top of the file, and the mark at the bottom of the file.", 79, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 539 }, -{ PROC_LINKS(select_next_scope_absolute, 0), false, "select_next_scope_absolute", 26, "Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.", 102, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 57 }, -{ PROC_LINKS(select_next_scope_after_current, 0), false, "select_next_scope_after_current", 31, "If a scope is selected, find first scope that starts after the selected scope. Otherwise find the first scope that starts after the cursor.", 139, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 66 }, -{ PROC_LINKS(select_prev_scope_absolute, 0), false, "select_prev_scope_absolute", 26, "Finds the first scope started by '{' before the cursor and puts the cursor and mark on the '{' and '}'.", 103, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 82 }, -{ PROC_LINKS(select_prev_top_most_scope, 0), false, "select_prev_top_most_scope", 26, "Finds the first scope that starts before the cursor, then finds the top most scope that contains that scope.", 108, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 99 }, -{ PROC_LINKS(select_surrounding_scope, 0), false, "select_surrounding_scope", 24, "Finds the scope enclosed by '{' '}' surrounding the cursor and puts the cursor and mark on the '{' and '}'.", 107, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 27 }, -{ PROC_LINKS(select_surrounding_scope_maximal, 0), false, "select_surrounding_scope_maximal", 32, "Selects the top-most scope that surrounds the cursor.", 53, "w:\\4ed\\code\\custom\\4coder_scope_commands.cpp", 44, 39 }, -{ PROC_LINKS(set_eol_mode_from_contents, 0), false, "set_eol_mode_from_contents", 26, "Sets the buffer's line ending mode to match the contents of the buffer.", 71, "w:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 125 }, -{ PROC_LINKS(set_eol_mode_to_binary, 0), false, "set_eol_mode_to_binary", 22, "Puts the buffer in bin line ending mode.", 40, "w:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 112 }, -{ PROC_LINKS(set_eol_mode_to_crlf, 0), false, "set_eol_mode_to_crlf", 20, "Puts the buffer in crlf line ending mode.", 41, "w:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 86 }, -{ PROC_LINKS(set_eol_mode_to_lf, 0), false, "set_eol_mode_to_lf", 18, "Puts the buffer in lf line ending mode.", 39, "w:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 99 }, -{ PROC_LINKS(set_mark, 0), false, "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 115 }, -{ PROC_LINKS(set_mode_to_notepad_like, 0), false, "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 427 }, -{ PROC_LINKS(set_mode_to_original, 0), false, "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 421 }, -{ PROC_LINKS(setup_build_bat, 0), false, "setup_build_bat", 15, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1237 }, -{ PROC_LINKS(setup_build_bat_and_sh, 0), false, "setup_build_bat_and_sh", 22, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1249 }, -{ PROC_LINKS(setup_build_sh, 0), false, "setup_build_sh", 14, "Queries the user for several configuration options and initializes a new build shell script.", 92, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1243 }, -{ PROC_LINKS(setup_new_project, 0), false, "setup_new_project", 17, "Queries the user for several configuration options and initializes a new 4coder project with build scripts for every OS.", 120, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1230 }, -{ PROC_LINKS(show_filebar, 0), false, "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 644 }, -{ PROC_LINKS(show_scrollbar, 0), false, "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 630 }, -{ PROC_LINKS(show_the_log_graph, 0), true, "show_the_log_graph", 18, "Parses *log* and displays the 'log graph' UI", 44, "w:\\4ed\\code\\custom\\4coder_log_parser.cpp", 40, 994 }, -{ PROC_LINKS(snipe_backward_whitespace_or_token_boundary, 0), false, "snipe_backward_whitespace_or_token_boundary", 43, "Delete a single, whole token on or to the left of the cursor and post it to the clipboard.", 90, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 179 }, -{ PROC_LINKS(snipe_forward_whitespace_or_token_boundary, 0), false, "snipe_forward_whitespace_or_token_boundary", 42, "Delete a single, whole token on or to the right of the cursor and post it to the clipboard.", 91, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 187 }, -{ PROC_LINKS(snippet_lister, 0), true, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 237 }, -{ PROC_LINKS(suppress_mouse, 0), false, "suppress_mouse", 14, "Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.", 83, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 403 }, -{ PROC_LINKS(swap_panels, 0), false, "swap_panels", 11, "Swaps the active panel with it's sibling.", 41, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1518 }, -{ PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 692 }, -{ PROC_LINKS(to_lowercase, 0), false, "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 565 }, -{ PROC_LINKS(to_uppercase, 0), false, "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 552 }, -{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 658 }, -{ PROC_LINKS(toggle_fps_meter, 0), false, "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 667 }, -{ PROC_LINKS(toggle_fullscreen, 0), false, "toggle_fullscreen", 17, "Toggle fullscreen mode on or off. The change(s) do not take effect until the next frame.", 89, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 451 }, -{ PROC_LINKS(toggle_highlight_enclosing_scopes, 0), false, "toggle_highlight_enclosing_scopes", 33, "In code files scopes surrounding the cursor are highlighted with distinguishing colors.", 87, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 439 }, -{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), false, "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 433 }, -{ PROC_LINKS(toggle_line_numbers, 0), false, "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 721 }, -{ PROC_LINKS(toggle_line_wrap, 0), false, "toggle_line_wrap", 16, "Toggles the line wrap setting on this buffer.", 45, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 727 }, -{ PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 415 }, -{ PROC_LINKS(toggle_paren_matching_helper, 0), false, "toggle_paren_matching_helper", 28, "In code files matching parentheses pairs are colored with distinguishing colors.", 80, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 445 }, -{ PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 712 }, -{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "w:\\4ed\\code\\custom\\4coder_code_index.cpp", 40, 1160 }, -{ PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 20 }, -{ PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 34 }, -{ PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 137 }, -{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1618 }, -{ PROC_LINKS(undo_all_buffers, 0), false, "undo_all_buffers", 16, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1645 }, -{ PROC_LINKS(view_buffer_other_panel, 0), false, "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1506 }, -{ PROC_LINKS(view_jump_list_with_lister, 0), false, "view_jump_list_with_lister", 26, "When executed on a buffer with jumps, creates a persistent lister for all the jumps", 83, "w:\\4ed\\code\\custom\\4coder_jump_lister.cpp", 41, 59 }, -{ PROC_LINKS(word_complete, 0), false, "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 392 }, -{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 639 }, -{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 94 }, -{ PROC_LINKS(write_hack, 0), false, "write_hack", 10, "At the cursor, insert a '// HACK' comment, includes user name if it was specified in config.4coder.", 99, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 82 }, -{ PROC_LINKS(write_note, 0), false, "write_note", 10, "At the cursor, insert a '// NOTE' comment, includes user name if it was specified in config.4coder.", 99, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 88 }, -{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts an underscore.", 22, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 67 }, -{ PROC_LINKS(write_text_and_auto_indent, 0), false, "write_text_and_auto_indent", 26, "Inserts text and auto-indents the line on which the cursor sits if any of the text contains 'layout punctuation' such as ;:{}()[]# and new lines.", 145, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 395 }, -{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 59 }, -{ PROC_LINKS(write_todo, 0), false, "write_todo", 10, "At the cursor, insert a '// TODO' comment, includes user name if it was specified in config.4coder.", 99, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 76 }, -{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 73 }, -{ PROC_LINKS(write_zero_struct, 0), false, "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 100 }, +{ PROC_LINKS(allow_mouse, 0), false, "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "../code/custom/4coder_default_framework.cpp", 43, 409 }, +{ PROC_LINKS(auto_indent_line_at_cursor, 0), false, "auto_indent_line_at_cursor", 26, "Auto-indents the line on which the cursor sits.", 47, "../code/custom/4coder_auto_indent.cpp", 37, 375 }, +{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "../code/custom/4coder_auto_indent.cpp", 37, 385 }, +{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "../code/custom/4coder_auto_indent.cpp", 37, 366 }, +{ PROC_LINKS(backspace_alpha_numeric_boundary, 0), false, "backspace_alpha_numeric_boundary", 32, "Delete characters between the cursor position and the first alphanumeric boundary to the left.", 94, "../code/custom/4coder_base_commands.cpp", 39, 154 }, +{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "../code/custom/4coder_base_commands.cpp", 39, 96 }, +{ PROC_LINKS(basic_change_active_panel, 0), false, "basic_change_active_panel", 25, "Change the currently active panel, moving to the panel with the next highest view_id. Will not skipe the build panel if it is open.", 132, "../code/custom/4coder_base_commands.cpp", 39, 613 }, +{ PROC_LINKS(build_in_build_panel, 0), false, "build_in_build_panel", 20, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. Puts the *compilation* buffer in a panel at the footer of the current view.", 230, "../code/custom/4coder_build_commands.cpp", 40, 165 }, +{ PROC_LINKS(build_search, 0), false, "build_search", 12, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*.", 153, "../code/custom/4coder_build_commands.cpp", 40, 128 }, +{ PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "../code/custom/4coder_base_commands.cpp", 39, 197 }, +{ PROC_LINKS(change_active_panel, 0), false, "change_active_panel", 19, "Change the currently active panel, moving to the panel with the next highest view_id.", 85, "../code/custom/4coder_default_framework.cpp", 43, 284 }, +{ PROC_LINKS(change_active_panel_backwards, 0), false, "change_active_panel_backwards", 29, "Change the currently active panel, moving to the panel with the next lowest view_id.", 84, "../code/custom/4coder_default_framework.cpp", 43, 290 }, +{ PROC_LINKS(change_to_build_panel, 0), false, "change_to_build_panel", 21, "If the special build panel is open, makes the build panel the active panel.", 75, "../code/custom/4coder_build_commands.cpp", 40, 186 }, +{ PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "../code/custom/4coder_base_commands.cpp", 39, 578 }, +{ PROC_LINKS(clear_all_themes, 0), false, "clear_all_themes", 16, "Clear the theme list", 20, "../code/custom/4coder_default_framework.cpp", 43, 480 }, +{ PROC_LINKS(click_set_cursor, 0), false, "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "../code/custom/4coder_base_commands.cpp", 39, 233 }, +{ PROC_LINKS(click_set_cursor_and_mark, 0), false, "click_set_cursor_and_mark", 25, "Sets the cursor position and mark to the mouse position.", 56, "../code/custom/4coder_base_commands.cpp", 39, 223 }, +{ PROC_LINKS(click_set_cursor_if_lbutton, 0), false, "click_set_cursor_if_lbutton", 27, "If the mouse left button is pressed, sets the cursor position to the mouse position.", 84, "../code/custom/4coder_base_commands.cpp", 39, 243 }, +{ PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "../code/custom/4coder_base_commands.cpp", 39, 255 }, +{ PROC_LINKS(close_all_code, 0), false, "close_all_code", 14, "Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.", 107, "../code/custom/4coder_project_commands.cpp", 42, 842 }, +{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "../code/custom/4coder_build_commands.cpp", 40, 180 }, +{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "../code/custom/4coder_base_commands.cpp", 39, 621 }, +{ PROC_LINKS(command_documentation, 0), true, "command_documentation", 21, "Prompts the user to select a command then loads a doc buffer for that item", 74, "../code/custom/4coder_docs.cpp", 30, 190 }, +{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "../code/custom/4coder_lists.cpp", 31, 668 }, +{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "../code/custom/4coder_combined_write_commands.cpp", 49, 125 }, +{ PROC_LINKS(comment_line_toggle, 0), false, "comment_line_toggle", 19, "Turns uncommented lines into commented lines and vice versa for comments starting with '//'.", 92, "../code/custom/4coder_combined_write_commands.cpp", 49, 149 }, +{ PROC_LINKS(copy, 0), false, "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "../code/custom/4coder_clipboard.cpp", 35, 19 }, +{ PROC_LINKS(cursor_mark_swap, 0), false, "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "../code/custom/4coder_base_commands.cpp", 39, 124 }, +{ PROC_LINKS(custom_api_documentation, 0), true, "custom_api_documentation", 24, "Prompts the user to select a Custom API item then loads a doc buffer for that item", 82, "../code/custom/4coder_docs.cpp", 30, 175 }, +{ PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "../code/custom/4coder_clipboard.cpp", 35, 28 }, +{ PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "../code/custom/4coder_base_commands.cpp", 39, 684 }, +{ PROC_LINKS(default_file_externally_modified, 0), false, "default_file_externally_modified", 32, "Notes the external modification of attached files by printing a message.", 72, "../code/custom/4coder_base_commands.cpp", 39, 1798 }, +{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "../code/custom/4coder_default_hooks.cpp", 39, 7 }, +{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "../code/custom/4coder_default_hooks.cpp", 39, 23 }, +{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "../code/custom/4coder_default_hooks.cpp", 39, 57 }, +{ PROC_LINKS(delete_alpha_numeric_boundary, 0), false, "delete_alpha_numeric_boundary", 29, "Delete characters between the cursor position and the first alphanumeric boundary to the right.", 95, "../code/custom/4coder_base_commands.cpp", 39, 162 }, +{ PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "../code/custom/4coder_base_commands.cpp", 39, 79 }, +{ PROC_LINKS(delete_current_scope, 0), false, "delete_current_scope", 20, "Deletes the braces surrounding the currently selected scope. Leaves the contents within the scope.", 99, "../code/custom/4coder_scope_commands.cpp", 40, 112 }, +{ PROC_LINKS(delete_file_query, 0), false, "delete_file_query", 17, "Deletes the file of the current buffer if 4coder has the appropriate access rights. Will ask the user for confirmation first.", 125, "../code/custom/4coder_base_commands.cpp", 39, 1221 }, +{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "../code/custom/4coder_base_commands.cpp", 39, 1396 }, +{ PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "../code/custom/4coder_base_commands.cpp", 39, 134 }, +{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "../code/custom/4coder_base_commands.cpp", 39, 1382 }, +{ PROC_LINKS(execute_any_cli, 0), false, "execute_any_cli", 15, "Queries for an output buffer name and system command, runs the system command as a CLI and prints the output to the specified buffer.", 133, "../code/custom/4coder_cli_command.cpp", 37, 22 }, +{ PROC_LINKS(execute_previous_cli, 0), false, "execute_previous_cli", 20, "If the command execute_any_cli has already been used, this will execute a CLI reusing the most recent buffer name and command.", 126, "../code/custom/4coder_cli_command.cpp", 37, 7 }, +{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "../code/custom/4coder_base_commands.cpp", 39, 740 }, +{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "../code/custom/4coder_helper.cpp", 32, 2184 }, +{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "../code/custom/4coder_helper.cpp", 32, 2192 }, +{ PROC_LINKS(goto_first_jump, 0), false, "goto_first_jump", 15, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "../code/custom/4coder_jump_sticky.cpp", 37, 523 }, +{ PROC_LINKS(goto_first_jump_same_panel_sticky, 0), false, "goto_first_jump_same_panel_sticky", 33, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer and views the buffer in the panel where the jump list was.", 153, "../code/custom/4coder_jump_sticky.cpp", 37, 540 }, +{ PROC_LINKS(goto_jump_at_cursor, 0), false, "goto_jump_at_cursor", 19, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "../code/custom/4coder_jump_sticky.cpp", 37, 346 }, +{ PROC_LINKS(goto_jump_at_cursor_same_panel, 0), false, "goto_jump_at_cursor_same_panel", 30, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.", 167, "../code/custom/4coder_jump_sticky.cpp", 37, 373 }, +{ PROC_LINKS(goto_line, 0), false, "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "../code/custom/4coder_base_commands.cpp", 39, 748 }, +{ PROC_LINKS(goto_next_jump, 0), false, "goto_next_jump", 14, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "../code/custom/4coder_jump_sticky.cpp", 37, 462 }, +{ PROC_LINKS(goto_next_jump_no_skips, 0), false, "goto_next_jump_no_skips", 23, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "../code/custom/4coder_jump_sticky.cpp", 37, 492 }, +{ PROC_LINKS(goto_prev_jump, 0), false, "goto_prev_jump", 14, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "../code/custom/4coder_jump_sticky.cpp", 37, 479 }, +{ PROC_LINKS(goto_prev_jump_no_skips, 0), false, "goto_prev_jump_no_skips", 23, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "../code/custom/4coder_jump_sticky.cpp", 37, 509 }, +{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "../code/custom/4coder_base_commands.cpp", 39, 651 }, +{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "../code/custom/4coder_base_commands.cpp", 39, 637 }, +{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "../code/custom/4coder_tutorial.cpp", 34, 869 }, +{ PROC_LINKS(if0_off, 0), false, "if0_off", 7, "Surround the range between the cursor and mark with an '#if 0' and an '#endif'", 78, "../code/custom/4coder_combined_write_commands.cpp", 49, 70 }, +{ PROC_LINKS(if_read_only_goto_position, 0), false, "if_read_only_goto_position", 26, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "../code/custom/4coder_jump_sticky.cpp", 37, 562 }, +{ PROC_LINKS(if_read_only_goto_position_same_panel, 0), false, "if_read_only_goto_position_same_panel", 37, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "../code/custom/4coder_jump_sticky.cpp", 37, 579 }, +{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "../code/custom/4coder_base_commands.cpp", 39, 673 }, +{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "../code/custom/4coder_lists.cpp", 31, 515 }, +{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "../code/custom/4coder_lists.cpp", 31, 597 }, +{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "../code/custom/4coder_lists.cpp", 31, 634 }, +{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "../code/custom/4coder_lists.cpp", 31, 563 }, +{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "../code/custom/4coder_lists.cpp", 31, 505 }, +{ PROC_LINKS(jump_to_definition, 0), true, "jump_to_definition", 18, "List all definitions in the code index and jump to one chosen by the user.", 74, "../code/custom/4coder_code_index_listers.cpp", 44, 12 }, +{ PROC_LINKS(keyboard_macro_finish_recording, 0), false, "keyboard_macro_finish_recording", 31, "Stop macro recording, do nothing if macro recording is not already started", 74, "../code/custom/4coder_keyboard_macro.cpp", 40, 57 }, +{ PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "../code/custom/4coder_keyboard_macro.cpp", 40, 80 }, +{ PROC_LINKS(keyboard_macro_start_recording, 0), false, "keyboard_macro_start_recording", 30, "Start macro recording, do nothing if macro recording is already started", 71, "../code/custom/4coder_keyboard_macro.cpp", 40, 44 }, +{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "../code/custom/4coder_base_commands.cpp", 39, 1542 }, +{ PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "../code/custom/4coder_tutorial.cpp", 34, 9 }, +{ PROC_LINKS(left_adjust_view, 0), false, "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "../code/custom/4coder_base_commands.cpp", 39, 211 }, +{ PROC_LINKS(list_all_functions_all_buffers, 0), false, "list_all_functions_all_buffers", 30, "Creates a jump list of lines from all buffers that appear to define or declare functions.", 89, "../code/custom/4coder_function_list.cpp", 39, 295 }, +{ PROC_LINKS(list_all_functions_all_buffers_lister, 0), false, "list_all_functions_all_buffers_lister", 37, "Creates a lister of locations that look like function definitions and declarations all buffers.", 95, "../code/custom/4coder_function_list.cpp", 39, 301 }, +{ PROC_LINKS(list_all_functions_current_buffer, 0), false, "list_all_functions_current_buffer", 33, "Creates a jump list of lines of the current buffer that appear to define or declare functions.", 94, "../code/custom/4coder_function_list.cpp", 39, 267 }, +{ PROC_LINKS(list_all_functions_current_buffer_lister, 0), false, "list_all_functions_current_buffer_lister", 40, "Creates a lister of locations that look like function definitions and declarations in the buffer.", 97, "../code/custom/4coder_function_list.cpp", 39, 277 }, +{ PROC_LINKS(list_all_locations, 0), false, "list_all_locations", 18, "Queries the user for a string and lists all exact case-sensitive matches found in all open buffers.", 99, "../code/custom/4coder_search.cpp", 32, 162 }, +{ PROC_LINKS(list_all_locations_case_insensitive, 0), false, "list_all_locations_case_insensitive", 35, "Queries the user for a string and lists all exact case-insensitive matches found in all open buffers.", 101, "../code/custom/4coder_search.cpp", 32, 174 }, +{ PROC_LINKS(list_all_locations_of_identifier, 0), false, "list_all_locations_of_identifier", 32, "Reads a token or word under the cursor and lists all exact case-sensitive mathces in all open buffers.", 102, "../code/custom/4coder_search.cpp", 32, 186 }, +{ PROC_LINKS(list_all_locations_of_identifier_case_insensitive, 0), false, "list_all_locations_of_identifier_case_insensitive", 49, "Reads a token or word under the cursor and lists all exact case-insensitive mathces in all open buffers.", 104, "../code/custom/4coder_search.cpp", 32, 192 }, +{ PROC_LINKS(list_all_locations_of_selection, 0), false, "list_all_locations_of_selection", 31, "Reads the string in the selected range and lists all exact case-sensitive mathces in all open buffers.", 102, "../code/custom/4coder_search.cpp", 32, 198 }, +{ PROC_LINKS(list_all_locations_of_selection_case_insensitive, 0), false, "list_all_locations_of_selection_case_insensitive", 48, "Reads the string in the selected range and lists all exact case-insensitive mathces in all open buffers.", 104, "../code/custom/4coder_search.cpp", 32, 204 }, +{ PROC_LINKS(list_all_locations_of_type_definition, 0), false, "list_all_locations_of_type_definition", 37, "Queries user for string, lists all locations of strings that appear to define a type whose name matches the input string.", 121, "../code/custom/4coder_search.cpp", 32, 210 }, +{ PROC_LINKS(list_all_locations_of_type_definition_of_identifier, 0), false, "list_all_locations_of_type_definition_of_identifier", 51, "Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it.", 125, "../code/custom/4coder_search.cpp", 32, 218 }, +{ PROC_LINKS(list_all_substring_locations, 0), false, "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "../code/custom/4coder_search.cpp", 32, 168 }, +{ PROC_LINKS(list_all_substring_locations_case_insensitive, 0), false, "list_all_substring_locations_case_insensitive", 45, "Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.", 105, "../code/custom/4coder_search.cpp", 32, 180 }, +{ PROC_LINKS(load_project, 0), false, "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "../code/custom/4coder_project_commands.cpp", 42, 862 }, +{ PROC_LINKS(load_themes_default_folder, 0), false, "load_themes_default_folder", 26, "Loads all the theme files in the default theme folder.", 54, "../code/custom/4coder_default_framework.cpp", 43, 457 }, +{ PROC_LINKS(load_themes_hot_directory, 0), false, "load_themes_hot_directory", 25, "Loads all the theme files in the current hot directory.", 55, "../code/custom/4coder_default_framework.cpp", 43, 469 }, +{ PROC_LINKS(make_directory_query, 0), false, "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "../code/custom/4coder_base_commands.cpp", 39, 1336 }, +{ PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "../code/custom/4coder_miblo_numbers.cpp", 39, 44 }, +{ PROC_LINKS(miblo_decrement_time_stamp, 0), false, "miblo_decrement_time_stamp", 26, "Decrement a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "../code/custom/4coder_miblo_numbers.cpp", 39, 237 }, +{ PROC_LINKS(miblo_decrement_time_stamp_minute, 0), false, "miblo_decrement_time_stamp_minute", 33, "Decrement a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "../code/custom/4coder_miblo_numbers.cpp", 39, 249 }, +{ PROC_LINKS(miblo_increment_basic, 0), false, "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "../code/custom/4coder_miblo_numbers.cpp", 39, 29 }, +{ PROC_LINKS(miblo_increment_time_stamp, 0), false, "miblo_increment_time_stamp", 26, "Increment a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "../code/custom/4coder_miblo_numbers.cpp", 39, 231 }, +{ PROC_LINKS(miblo_increment_time_stamp_minute, 0), false, "miblo_increment_time_stamp_minute", 33, "Increment a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "../code/custom/4coder_miblo_numbers.cpp", 39, 243 }, +{ PROC_LINKS(mouse_wheel_change_face_size, 0), false, "mouse_wheel_change_face_size", 28, "Reads the state of the mouse wheel and uses it to either increase or decrease the face size.", 92, "../code/custom/4coder_base_commands.cpp", 39, 695 }, +{ PROC_LINKS(mouse_wheel_scroll, 0), false, "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "../code/custom/4coder_base_commands.cpp", 39, 265 }, +{ PROC_LINKS(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "../code/custom/4coder_base_commands.cpp", 39, 338 }, +{ PROC_LINKS(move_down_10, 0), false, "move_down_10", 12, "Moves the cursor down ten lines.", 32, "../code/custom/4coder_base_commands.cpp", 39, 350 }, +{ PROC_LINKS(move_down_textual, 0), false, "move_down_textual", 17, "Moves down to the next line of actual text, regardless of line wrapping.", 72, "../code/custom/4coder_base_commands.cpp", 39, 356 }, +{ PROC_LINKS(move_down_to_blank_line, 0), false, "move_down_to_blank_line", 23, "Seeks the cursor down to the next blank line.", 45, "../code/custom/4coder_base_commands.cpp", 39, 409 }, +{ PROC_LINKS(move_down_to_blank_line_end, 0), false, "move_down_to_blank_line_end", 27, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "../code/custom/4coder_base_commands.cpp", 39, 433 }, +{ PROC_LINKS(move_down_to_blank_line_skip_whitespace, 0), false, "move_down_to_blank_line_skip_whitespace", 39, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "../code/custom/4coder_base_commands.cpp", 39, 421 }, +{ PROC_LINKS(move_left, 0), false, "move_left", 9, "Moves the cursor one character to the left.", 43, "../code/custom/4coder_base_commands.cpp", 39, 439 }, +{ PROC_LINKS(move_left_alpha_numeric_boundary, 0), false, "move_left_alpha_numeric_boundary", 32, "Seek left for boundary between alphanumeric characters and non-alphanumeric characters.", 87, "../code/custom/4coder_base_commands.cpp", 39, 516 }, +{ PROC_LINKS(move_left_alpha_numeric_or_camel_boundary, 0), false, "move_left_alpha_numeric_or_camel_boundary", 41, "Seek left for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 106, "../code/custom/4coder_base_commands.cpp", 39, 530 }, +{ PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "../code/custom/4coder_base_commands.cpp", 39, 488 }, +{ PROC_LINKS(move_left_whitespace_boundary, 0), false, "move_left_whitespace_boundary", 29, "Seek left for the next boundary between whitespace and non-whitespace.", 70, "../code/custom/4coder_base_commands.cpp", 39, 473 }, +{ PROC_LINKS(move_left_whitespace_or_token_boundary, 0), false, "move_left_whitespace_or_token_boundary", 38, "Seek left for the next end of a token or boundary between whitespace and non-whitespace.", 88, "../code/custom/4coder_base_commands.cpp", 39, 502 }, +{ PROC_LINKS(move_line_down, 0), false, "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "../code/custom/4coder_base_commands.cpp", 39, 1376 }, +{ PROC_LINKS(move_line_up, 0), false, "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "../code/custom/4coder_base_commands.cpp", 39, 1370 }, +{ PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "../code/custom/4coder_base_commands.cpp", 39, 447 }, +{ PROC_LINKS(move_right_alpha_numeric_boundary, 0), false, "move_right_alpha_numeric_boundary", 33, "Seek right for boundary between alphanumeric characters and non-alphanumeric characters.", 88, "../code/custom/4coder_base_commands.cpp", 39, 509 }, +{ PROC_LINKS(move_right_alpha_numeric_or_camel_boundary, 0), false, "move_right_alpha_numeric_or_camel_boundary", 42, "Seek right for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 107, "../code/custom/4coder_base_commands.cpp", 39, 523 }, +{ PROC_LINKS(move_right_token_boundary, 0), false, "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "../code/custom/4coder_base_commands.cpp", 39, 481 }, +{ PROC_LINKS(move_right_whitespace_boundary, 0), false, "move_right_whitespace_boundary", 30, "Seek right for the next boundary between whitespace and non-whitespace.", 71, "../code/custom/4coder_base_commands.cpp", 39, 465 }, +{ PROC_LINKS(move_right_whitespace_or_token_boundary, 0), false, "move_right_whitespace_or_token_boundary", 39, "Seek right for the next end of a token or boundary between whitespace and non-whitespace.", 89, "../code/custom/4coder_base_commands.cpp", 39, 495 }, +{ PROC_LINKS(move_up, 0), false, "move_up", 7, "Moves the cursor up one line.", 29, "../code/custom/4coder_base_commands.cpp", 39, 332 }, +{ PROC_LINKS(move_up_10, 0), false, "move_up_10", 10, "Moves the cursor up ten lines.", 30, "../code/custom/4coder_base_commands.cpp", 39, 344 }, +{ PROC_LINKS(move_up_to_blank_line, 0), false, "move_up_to_blank_line", 21, "Seeks the cursor up to the next blank line.", 43, "../code/custom/4coder_base_commands.cpp", 39, 403 }, +{ PROC_LINKS(move_up_to_blank_line_end, 0), false, "move_up_to_blank_line_end", 25, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "../code/custom/4coder_base_commands.cpp", 39, 427 }, +{ PROC_LINKS(move_up_to_blank_line_skip_whitespace, 0), false, "move_up_to_blank_line_skip_whitespace", 37, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "../code/custom/4coder_base_commands.cpp", 39, 415 }, +{ PROC_LINKS(open_all_code, 0), false, "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "../code/custom/4coder_project_commands.cpp", 42, 848 }, +{ PROC_LINKS(open_all_code_recursive, 0), false, "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "../code/custom/4coder_project_commands.cpp", 42, 854 }, +{ PROC_LINKS(open_file_in_quotes, 0), false, "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "../code/custom/4coder_base_commands.cpp", 39, 1461 }, +{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "../code/custom/4coder_base_commands.cpp", 39, 1792 }, +{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "../code/custom/4coder_combined_write_commands.cpp", 49, 46 }, +{ PROC_LINKS(open_long_braces_break, 0), false, "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "../code/custom/4coder_combined_write_commands.cpp", 49, 62 }, +{ PROC_LINKS(open_long_braces_semicolon, 0), false, "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "../code/custom/4coder_combined_write_commands.cpp", 49, 54 }, +{ PROC_LINKS(open_matching_file_cpp, 0), false, "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "../code/custom/4coder_base_commands.cpp", 39, 1493 }, +{ PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "../code/custom/4coder_default_framework.cpp", 43, 310 }, +{ PROC_LINKS(open_panel_vsplit, 0), false, "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "../code/custom/4coder_default_framework.cpp", 43, 300 }, +{ PROC_LINKS(page_down, 0), false, "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "../code/custom/4coder_base_commands.cpp", 39, 374 }, +{ PROC_LINKS(page_up, 0), false, "page_up", 7, "Scrolls the view up one view height and moves the cursor up one view height.", 76, "../code/custom/4coder_base_commands.cpp", 39, 366 }, +{ PROC_LINKS(paste, 0), false, "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "../code/custom/4coder_clipboard.cpp", 35, 39 }, +{ PROC_LINKS(paste_and_indent, 0), false, "paste_and_indent", 16, "Paste from the top of clipboard and run auto-indent on the newly pasted text.", 77, "../code/custom/4coder_clipboard.cpp", 35, 110 }, +{ PROC_LINKS(paste_next, 0), false, "paste_next", 10, "If the previous command was paste or paste_next, replaces the paste range with the next text down on the clipboard, otherwise operates as the paste command.", 156, "../code/custom/4coder_clipboard.cpp", 35, 71 }, +{ PROC_LINKS(paste_next_and_indent, 0), false, "paste_next_and_indent", 21, "Paste the next item on the clipboard and run auto-indent on the newly pasted text.", 82, "../code/custom/4coder_clipboard.cpp", 35, 117 }, +{ PROC_LINKS(place_in_scope, 0), false, "place_in_scope", 14, "Wraps the code contained in the range between cursor and mark with a new curly brace scope.", 91, "../code/custom/4coder_scope_commands.cpp", 40, 106 }, +{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "../code/custom/4coder_profile.cpp", 33, 226 }, +{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "../code/custom/4coder_profile.cpp", 33, 219 }, +{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "../code/custom/4coder_profile.cpp", 33, 212 }, +{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "../code/custom/4coder_profile_inspect.cpp", 41, 886 }, +{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "../code/custom/4coder_project_commands.cpp", 42, 1289 }, +{ PROC_LINKS(project_fkey_command, 0), false, "project_fkey_command", 20, "Run an 'fkey command' configured in a project.4coder file. Determines the index of the 'fkey command' by which function key or numeric key was pressed to trigger the command.", 175, "../code/custom/4coder_project_commands.cpp", 42, 870 }, +{ PROC_LINKS(project_go_to_root_directory, 0), false, "project_go_to_root_directory", 28, "Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns.", 125, "../code/custom/4coder_project_commands.cpp", 42, 896 }, +{ PROC_LINKS(query_replace, 0), false, "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "../code/custom/4coder_base_commands.cpp", 39, 1149 }, +{ PROC_LINKS(query_replace_identifier, 0), false, "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "../code/custom/4coder_base_commands.cpp", 39, 1170 }, +{ PROC_LINKS(query_replace_selection, 0), false, "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "../code/custom/4coder_base_commands.cpp", 39, 1186 }, +{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "../code/custom/4coder_base_commands.cpp", 39, 1631 }, +{ PROC_LINKS(redo_all_buffers, 0), false, "redo_all_buffers", 16, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "../code/custom/4coder_base_commands.cpp", 39, 1716 }, +{ PROC_LINKS(rename_file_query, 0), false, "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "../code/custom/4coder_base_commands.cpp", 39, 1298 }, +{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "../code/custom/4coder_base_commands.cpp", 39, 1560 }, +{ PROC_LINKS(replace_in_all_buffers, 0), false, "replace_in_all_buffers", 22, "Queries the user for a needle and string. Replaces all occurences of needle with string in all editable buffers.", 112, "../code/custom/4coder_base_commands.cpp", 39, 1059 }, +{ PROC_LINKS(replace_in_buffer, 0), false, "replace_in_buffer", 17, "Queries the user for a needle and string. Replaces all occurences of needle with string in the active buffer.", 109, "../code/custom/4coder_base_commands.cpp", 39, 1050 }, +{ PROC_LINKS(replace_in_range, 0), false, "replace_in_range", 16, "Queries the user for a needle and string. Replaces all occurences of needle with string in the range between cursor and the mark in the active buffer.", 150, "../code/custom/4coder_base_commands.cpp", 39, 1041 }, +{ PROC_LINKS(reverse_search, 0), false, "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "../code/custom/4coder_base_commands.cpp", 39, 982 }, +{ PROC_LINKS(reverse_search_identifier, 0), false, "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "../code/custom/4coder_base_commands.cpp", 39, 994 }, +{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "../code/custom/4coder_base_commands.cpp", 39, 1550 }, +{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "../code/custom/4coder_default_framework.cpp", 43, 382 }, +{ PROC_LINKS(save_to_query, 0), false, "save_to_query", 13, "Queries the user for a file name and saves the contents of the current buffer, altering the buffer's name too.", 110, "../code/custom/4coder_base_commands.cpp", 39, 1265 }, +{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "../code/custom/4coder_base_commands.cpp", 39, 976 }, +{ PROC_LINKS(search_identifier, 0), false, "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "../code/custom/4coder_base_commands.cpp", 39, 988 }, +{ PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "../code/custom/4coder_helper.cpp", 32, 2172 }, +{ PROC_LINKS(seek_beginning_of_textual_line, 0), false, "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "../code/custom/4coder_helper.cpp", 32, 2160 }, +{ PROC_LINKS(seek_end_of_line, 0), false, "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "../code/custom/4coder_helper.cpp", 32, 2178 }, +{ PROC_LINKS(seek_end_of_textual_line, 0), false, "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "../code/custom/4coder_helper.cpp", 32, 2166 }, +{ PROC_LINKS(select_all, 0), false, "select_all", 10, "Puts the cursor at the top of the file, and the mark at the bottom of the file.", 79, "../code/custom/4coder_base_commands.cpp", 39, 539 }, +{ PROC_LINKS(select_next_scope_absolute, 0), false, "select_next_scope_absolute", 26, "Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.", 102, "../code/custom/4coder_scope_commands.cpp", 40, 57 }, +{ PROC_LINKS(select_next_scope_after_current, 0), false, "select_next_scope_after_current", 31, "If a scope is selected, find first scope that starts after the selected scope. Otherwise find the first scope that starts after the cursor.", 139, "../code/custom/4coder_scope_commands.cpp", 40, 66 }, +{ PROC_LINKS(select_prev_scope_absolute, 0), false, "select_prev_scope_absolute", 26, "Finds the first scope started by '{' before the cursor and puts the cursor and mark on the '{' and '}'.", 103, "../code/custom/4coder_scope_commands.cpp", 40, 82 }, +{ PROC_LINKS(select_prev_top_most_scope, 0), false, "select_prev_top_most_scope", 26, "Finds the first scope that starts before the cursor, then finds the top most scope that contains that scope.", 108, "../code/custom/4coder_scope_commands.cpp", 40, 99 }, +{ PROC_LINKS(select_surrounding_scope, 0), false, "select_surrounding_scope", 24, "Finds the scope enclosed by '{' '}' surrounding the cursor and puts the cursor and mark on the '{' and '}'.", 107, "../code/custom/4coder_scope_commands.cpp", 40, 27 }, +{ PROC_LINKS(select_surrounding_scope_maximal, 0), false, "select_surrounding_scope_maximal", 32, "Selects the top-most scope that surrounds the cursor.", 53, "../code/custom/4coder_scope_commands.cpp", 40, 39 }, +{ PROC_LINKS(set_eol_mode_from_contents, 0), false, "set_eol_mode_from_contents", 26, "Sets the buffer's line ending mode to match the contents of the buffer.", 71, "../code/custom/4coder_eol.cpp", 29, 125 }, +{ PROC_LINKS(set_eol_mode_to_binary, 0), false, "set_eol_mode_to_binary", 22, "Puts the buffer in bin line ending mode.", 40, "../code/custom/4coder_eol.cpp", 29, 112 }, +{ PROC_LINKS(set_eol_mode_to_crlf, 0), false, "set_eol_mode_to_crlf", 20, "Puts the buffer in crlf line ending mode.", 41, "../code/custom/4coder_eol.cpp", 29, 86 }, +{ PROC_LINKS(set_eol_mode_to_lf, 0), false, "set_eol_mode_to_lf", 18, "Puts the buffer in lf line ending mode.", 39, "../code/custom/4coder_eol.cpp", 29, 99 }, +{ PROC_LINKS(set_mark, 0), false, "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "../code/custom/4coder_base_commands.cpp", 39, 115 }, +{ PROC_LINKS(set_mode_to_notepad_like, 0), false, "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "../code/custom/4coder_default_framework.cpp", 43, 427 }, +{ PROC_LINKS(set_mode_to_original, 0), false, "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "../code/custom/4coder_default_framework.cpp", 43, 421 }, +{ PROC_LINKS(setup_build_bat, 0), false, "setup_build_bat", 15, "Queries the user for several configuration options and initializes a new build batch script.", 92, "../code/custom/4coder_project_commands.cpp", 42, 1237 }, +{ PROC_LINKS(setup_build_bat_and_sh, 0), false, "setup_build_bat_and_sh", 22, "Queries the user for several configuration options and initializes a new build batch script.", 92, "../code/custom/4coder_project_commands.cpp", 42, 1249 }, +{ PROC_LINKS(setup_build_sh, 0), false, "setup_build_sh", 14, "Queries the user for several configuration options and initializes a new build shell script.", 92, "../code/custom/4coder_project_commands.cpp", 42, 1243 }, +{ PROC_LINKS(setup_new_project, 0), false, "setup_new_project", 17, "Queries the user for several configuration options and initializes a new 4coder project with build scripts for every OS.", 120, "../code/custom/4coder_project_commands.cpp", 42, 1230 }, +{ PROC_LINKS(show_filebar, 0), false, "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "../code/custom/4coder_base_commands.cpp", 39, 644 }, +{ PROC_LINKS(show_scrollbar, 0), false, "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "../code/custom/4coder_base_commands.cpp", 39, 630 }, +{ PROC_LINKS(show_the_log_graph, 0), true, "show_the_log_graph", 18, "Parses *log* and displays the 'log graph' UI", 44, "../code/custom/4coder_log_parser.cpp", 36, 994 }, +{ PROC_LINKS(snipe_backward_whitespace_or_token_boundary, 0), false, "snipe_backward_whitespace_or_token_boundary", 43, "Delete a single, whole token on or to the left of the cursor and post it to the clipboard.", 90, "../code/custom/4coder_base_commands.cpp", 39, 179 }, +{ PROC_LINKS(snipe_forward_whitespace_or_token_boundary, 0), false, "snipe_forward_whitespace_or_token_boundary", 42, "Delete a single, whole token on or to the right of the cursor and post it to the clipboard.", 91, "../code/custom/4coder_base_commands.cpp", 39, 187 }, +{ PROC_LINKS(snippet_lister, 0), true, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "../code/custom/4coder_combined_write_commands.cpp", 49, 237 }, +{ PROC_LINKS(suppress_mouse, 0), false, "suppress_mouse", 14, "Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.", 83, "../code/custom/4coder_default_framework.cpp", 43, 403 }, +{ PROC_LINKS(swap_panels, 0), false, "swap_panels", 11, "Swaps the active panel with it's sibling.", 41, "../code/custom/4coder_base_commands.cpp", 39, 1518 }, +{ PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "../code/custom/4coder_lists.cpp", 31, 692 }, +{ PROC_LINKS(to_lowercase, 0), false, "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "../code/custom/4coder_base_commands.cpp", 39, 565 }, +{ PROC_LINKS(to_uppercase, 0), false, "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "../code/custom/4coder_base_commands.cpp", 39, 552 }, +{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "../code/custom/4coder_base_commands.cpp", 39, 658 }, +{ PROC_LINKS(toggle_fps_meter, 0), false, "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "../code/custom/4coder_base_commands.cpp", 39, 667 }, +{ PROC_LINKS(toggle_fullscreen, 0), false, "toggle_fullscreen", 17, "Toggle fullscreen mode on or off. The change(s) do not take effect until the next frame.", 89, "../code/custom/4coder_default_framework.cpp", 43, 451 }, +{ PROC_LINKS(toggle_highlight_enclosing_scopes, 0), false, "toggle_highlight_enclosing_scopes", 33, "In code files scopes surrounding the cursor are highlighted with distinguishing colors.", 87, "../code/custom/4coder_default_framework.cpp", 43, 439 }, +{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), false, "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "../code/custom/4coder_default_framework.cpp", 43, 433 }, +{ PROC_LINKS(toggle_line_numbers, 0), false, "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "../code/custom/4coder_base_commands.cpp", 39, 721 }, +{ PROC_LINKS(toggle_line_wrap, 0), false, "toggle_line_wrap", 16, "Toggles the line wrap setting on this buffer.", 45, "../code/custom/4coder_base_commands.cpp", 39, 727 }, +{ PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "../code/custom/4coder_default_framework.cpp", 43, 415 }, +{ PROC_LINKS(toggle_paren_matching_helper, 0), false, "toggle_paren_matching_helper", 28, "In code files matching parentheses pairs are colored with distinguishing colors.", 80, "../code/custom/4coder_default_framework.cpp", 43, 445 }, +{ PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "../code/custom/4coder_base_commands.cpp", 39, 712 }, +{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "../code/custom/4coder_code_index.cpp", 36, 1160 }, +{ PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "../code/custom/4coder_tutorial.cpp", 34, 20 }, +{ PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "../code/custom/4coder_tutorial.cpp", 34, 34 }, +{ PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "../code/custom/4coder_combined_write_commands.cpp", 49, 137 }, +{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "../code/custom/4coder_base_commands.cpp", 39, 1618 }, +{ PROC_LINKS(undo_all_buffers, 0), false, "undo_all_buffers", 16, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "../code/custom/4coder_base_commands.cpp", 39, 1645 }, +{ PROC_LINKS(view_buffer_other_panel, 0), false, "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "../code/custom/4coder_base_commands.cpp", 39, 1506 }, +{ PROC_LINKS(view_jump_list_with_lister, 0), false, "view_jump_list_with_lister", 26, "When executed on a buffer with jumps, creates a persistent lister for all the jumps", 83, "../code/custom/4coder_jump_lister.cpp", 37, 59 }, +{ PROC_LINKS(word_complete, 0), false, "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "../code/custom/4coder_search.cpp", 32, 392 }, +{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "../code/custom/4coder_search.cpp", 32, 639 }, +{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "../code/custom/4coder_combined_write_commands.cpp", 49, 94 }, +{ PROC_LINKS(write_hack, 0), false, "write_hack", 10, "At the cursor, insert a '// HACK' comment, includes user name if it was specified in config.4coder.", 99, "../code/custom/4coder_combined_write_commands.cpp", 49, 82 }, +{ PROC_LINKS(write_note, 0), false, "write_note", 10, "At the cursor, insert a '// NOTE' comment, includes user name if it was specified in config.4coder.", 99, "../code/custom/4coder_combined_write_commands.cpp", 49, 88 }, +{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts an underscore.", 22, "../code/custom/4coder_base_commands.cpp", 39, 67 }, +{ PROC_LINKS(write_text_and_auto_indent, 0), false, "write_text_and_auto_indent", 26, "Inserts text and auto-indents the line on which the cursor sits if any of the text contains 'layout punctuation' such as ;:{}()[]# and new lines.", 145, "../code/custom/4coder_auto_indent.cpp", 37, 395 }, +{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "../code/custom/4coder_base_commands.cpp", 39, 59 }, +{ PROC_LINKS(write_todo, 0), false, "write_todo", 10, "At the cursor, insert a '// TODO' comment, includes user name if it was specified in config.4coder.", 99, "../code/custom/4coder_combined_write_commands.cpp", 49, 76 }, +{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "../code/custom/4coder_base_commands.cpp", 39, 73 }, +{ PROC_LINKS(write_zero_struct, 0), false, "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "../code/custom/4coder_combined_write_commands.cpp", 49, 100 }, }; static i32 fcoder_metacmd_ID_allow_mouse = 0; static i32 fcoder_metacmd_ID_auto_indent_line_at_cursor = 1; diff --git a/custom/metadata_generator.dSYM/Contents/Info.plist b/custom/metadata_generator.dSYM/Contents/Info.plist new file mode 100644 index 00000000..a05ad97b --- /dev/null +++ b/custom/metadata_generator.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.metadata_generator + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/custom/metadata_generator.dSYM/Contents/Resources/DWARF/metadata_generator b/custom/metadata_generator.dSYM/Contents/Resources/DWARF/metadata_generator new file mode 100644 index 00000000..28c1007f Binary files /dev/null and b/custom/metadata_generator.dSYM/Contents/Resources/DWARF/metadata_generator differ