From 9f518de27b9be0e374bc5234f9951306a0786447 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sun, 22 Dec 2019 23:43:36 +0200 Subject: [PATCH] Build system is now working for macOS. --- bin/4ed_build.cpp | 1226 ++++----- bin/build.sh | 5 +- custom/4coder_base_types.cpp | 14 +- custom/4coder_code_index.cpp | 2346 ++++++++--------- custom/4coder_draw.cpp | 1686 ++++++------ custom/4coder_malloc_allocator.cpp | 5 +- custom/4coder_types.h | 5 +- custom/bin/buildsuper_x64.sh | 3 +- custom/bin/buildsuper_x86.sh | 3 +- custom/generated/command_metadata.h | 458 ++-- .../Contents/Info.plist | 20 + .../Resources/DWARF/metadata_generator | Bin 0 -> 486440 bytes 12 files changed, 2898 insertions(+), 2873 deletions(-) create mode 100644 custom/metadata_generator.dSYM/Contents/Info.plist create mode 100644 custom/metadata_generator.dSYM/Contents/Resources/DWARF/metadata_generator 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 0000000000000000000000000000000000000000..28c1007f45ecd0a4f588766b5e518e8d7fe6dc50 GIT binary patch literal 486440 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 Yd#&*^$M^S#2(V=a_-h7h($ literal 0 HcmV?d00001